mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'implement_eslint' into 'master'
Implement ESLint See merge request Chill-Projet/chill-bundles!752
This commit is contained in:
commit
e8962782ed
1986
.eslint-baseline.json
Normal file
1986
.eslint-baseline.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@ cache:
|
|||||||
paths:
|
paths:
|
||||||
- /vendor/
|
- /vendor/
|
||||||
- .cache
|
- .cache
|
||||||
|
- node_modules/
|
||||||
|
|
||||||
# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
|
# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
|
||||||
# See http://docs.gitlab.com/ee/ci/services/README.html for examples.
|
# See http://docs.gitlab.com/ee/ci/services/README.html for examples.
|
||||||
@ -103,6 +104,32 @@ rector_tests:
|
|||||||
paths:
|
paths:
|
||||||
- vendor/
|
- vendor/
|
||||||
|
|
||||||
|
lint:
|
||||||
|
stage: Tests
|
||||||
|
image: node:20-alpine
|
||||||
|
before_script:
|
||||||
|
- apk add --no-cache python3 make g++ py3-setuptools
|
||||||
|
- export PYTHON="$(which python3)"
|
||||||
|
- export PATH="./node_modules/.bin:$PATH"
|
||||||
|
script:
|
||||||
|
- yarn install --ignore-optional
|
||||||
|
- npx eslint-baseline "**/*.{js,vue}"
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- node_modules/
|
||||||
|
|
||||||
|
# psalm_tests:
|
||||||
|
# stage: Tests
|
||||||
|
# image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82
|
||||||
|
# script:
|
||||||
|
# - bin/psalm
|
||||||
|
# allow_failure: true
|
||||||
|
# artifacts:
|
||||||
|
# expire_in: 30 min
|
||||||
|
# paths:
|
||||||
|
# - bin
|
||||||
|
# - tests/app/vendor/
|
||||||
|
|
||||||
unit_tests:
|
unit_tests:
|
||||||
stage: Tests
|
stage: Tests
|
||||||
image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82
|
image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82
|
||||||
|
53
docs/source/development/es-lint.rst
Normal file
53
docs/source/development/es-lint.rst
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
ESLint
|
||||||
|
======
|
||||||
|
|
||||||
|
To improve the quality of our JS and VueJS code, ESLint and eslint-plugin-vue are implemented within the chill-bundles project.
|
||||||
|
|
||||||
|
Commands
|
||||||
|
--------
|
||||||
|
|
||||||
|
To run ESLint, you can simply use the ``eslint`` command within the chill-bundles directory.
|
||||||
|
|
||||||
|
Interesting options are:
|
||||||
|
|
||||||
|
- ``--quiet`` to only get errors and silence the warnings
|
||||||
|
- ``--fix`` to have ESLint fix what it can, automatically. This will not fix everything.
|
||||||
|
|
||||||
|
Rules
|
||||||
|
-----
|
||||||
|
|
||||||
|
We use Vue 3, so the rules can be configured as follows within the ``eslint.config.mjs`` file:
|
||||||
|
|
||||||
|
- ``.configs["flat/base"]`` ... Settings and rules to enable correct ESLint parsing.
|
||||||
|
|
||||||
|
Configurations for using Vue.js 3.x:
|
||||||
|
|
||||||
|
- ``.configs["flat/essential"]`` : Base rules plus rules to prevent errors or unintended behavior.
|
||||||
|
- ``.configs["flat/strongly-recommended"]`` ... Above, plus rules to considerably improve code readability and/or dev experience.
|
||||||
|
- ``.configs["flat/recommended"]`` ... Above, plus rules to enforce subjective community defaults to ensure consistency.
|
||||||
|
|
||||||
|
Detailed information about which rules each set includes can be found here:
|
||||||
|
`https://eslint.vuejs.org/rules/ <https://eslint.vuejs.org/rules/>`_
|
||||||
|
|
||||||
|
Manual Rule Configuration
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
We can also manually configure certain rules or override rules that are part of the ruleset specified above.
|
||||||
|
|
||||||
|
For example, if we want to turn off a certain rule, we can do so as follows:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
'vue/multi-word-component': 'off'
|
||||||
|
}
|
||||||
|
|
||||||
|
We could also change the severity of a certain rule from 'error' to 'warning', for example.
|
||||||
|
|
||||||
|
Within specific ``.js`` or ``.vue`` files, we can also override a certain rule only for that specific file by adding a comment:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
/* eslint multi-word-component: "off", no-child-content: "error"
|
||||||
|
--------
|
||||||
|
Here's a description about why this configuration is necessary. */
|
@ -31,6 +31,7 @@ As Chill relies on the `symfony <http://symfony.com>`_ framework, reading the fr
|
|||||||
Exports <exports.rst>
|
Exports <exports.rst>
|
||||||
Embeddable comments <embeddable-comments.rst>
|
Embeddable comments <embeddable-comments.rst>
|
||||||
Run tests <run-tests.rst>
|
Run tests <run-tests.rst>
|
||||||
|
ESLint <es-lint.rst>
|
||||||
Useful snippets <useful-snippets.rst>
|
Useful snippets <useful-snippets.rst>
|
||||||
manual/index.rst
|
manual/index.rst
|
||||||
Assets <assets.rst>
|
Assets <assets.rst>
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
import { ShowHide } from 'ShowHide/show_hide.js';
|
import { ShowHide } from "ShowHide/show_hide.js";
|
||||||
|
|
||||||
var
|
var div_accompagnement = document.getElementById("form_accompagnement"),
|
||||||
div_accompagnement = document.getElementById("form_accompagnement"),
|
div_accompagnement_comment = document.getElementById(
|
||||||
div_accompagnement_comment = document.getElementById("form_accompagnement_comment"),
|
"form_accompagnement_comment",
|
||||||
|
),
|
||||||
div_caf_id = document.getElementById("cafId"),
|
div_caf_id = document.getElementById("cafId"),
|
||||||
div_caf_inscription_date = document.getElementById("cafInscriptionDate"),
|
div_caf_inscription_date = document.getElementById("cafInscriptionDate");
|
||||||
;
|
|
||||||
|
|
||||||
// let show/hide the div_accompagnement_comment if the input with value `'autre'` is checked
|
// let show/hide the div_accompagnement_comment if the input with value `'autre'` is checked
|
||||||
new ShowHide({
|
new ShowHide({
|
||||||
"froms": [div_accompagnement],
|
froms: [div_accompagnement],
|
||||||
"test": function(froms, event) {
|
test: function (froms, event) {
|
||||||
for (let el of froms.values()) {
|
for (let el of froms.values()) {
|
||||||
for (let input of el.querySelectorAll('input').values()) {
|
for (let input of el.querySelectorAll("input").values()) {
|
||||||
if (input.value === 'autre') {
|
if (input.value === "autre") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21,7 +20,7 @@ new ShowHide({
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
"container": [div_accompagnement_comment]
|
container: [div_accompagnement_comment],
|
||||||
});
|
});
|
||||||
|
|
||||||
// let show the date input only if the the id is filled
|
// let show the date input only if the the id is filled
|
||||||
@ -34,6 +33,5 @@ new ShowHide({
|
|||||||
},
|
},
|
||||||
container: [div_caf_inscription_date],
|
container: [div_caf_inscription_date],
|
||||||
// using this option, we use the event `input` instead of `change`
|
// using this option, we use the event `input` instead of `change`
|
||||||
event_name: 'input'
|
event_name: "input",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
35
eslint.config.mjs
Normal file
35
eslint.config.mjs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import eslintPluginVue from "eslint-plugin-vue";
|
||||||
|
import ts from "typescript-eslint";
|
||||||
|
import eslintPluginPrettier from "eslint-plugin-prettier";
|
||||||
|
|
||||||
|
export default ts.config(
|
||||||
|
...ts.configs.recommended,
|
||||||
|
...ts.configs.stylistic,
|
||||||
|
...eslintPluginVue.configs["flat/essential"],
|
||||||
|
{
|
||||||
|
files: ["**/*.vue"],
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
parser: "@typescript-eslint/parser",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
"**/vendor/*",
|
||||||
|
"**/import-png.d.ts",
|
||||||
|
"**/chill.webpack.config.js",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plugins: {
|
||||||
|
prettier: eslintPluginPrettier,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
"prettier/prettier": "error",
|
||||||
|
// override/add rules settings here, such as:
|
||||||
|
"vue/multi-word-component-names": "off",
|
||||||
|
"@typescript-eslint/no-require-imports": "off",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
13
package.json
13
package.json
@ -13,26 +13,36 @@
|
|||||||
"@ckeditor/ckeditor5-markdown-gfm": "^41.4.2",
|
"@ckeditor/ckeditor5-markdown-gfm": "^41.4.2",
|
||||||
"@ckeditor/ckeditor5-theme-lark": "^41.4.2",
|
"@ckeditor/ckeditor5-theme-lark": "^41.4.2",
|
||||||
"@ckeditor/ckeditor5-vue": "^5.1.0",
|
"@ckeditor/ckeditor5-vue": "^5.1.0",
|
||||||
|
"@eslint/js": "^9.14.0",
|
||||||
|
"@luminateone/eslint-baseline": "^1.0.9",
|
||||||
"@symfony/webpack-encore": "^4.1.0",
|
"@symfony/webpack-encore": "^4.1.0",
|
||||||
"@tsconfig/node14": "^1.0.1",
|
"@tsconfig/node14": "^1.0.1",
|
||||||
"@types/dompurify": "^3.0.5",
|
"@types/dompurify": "^3.0.5",
|
||||||
|
"@types/eslint__js": "^8.42.3",
|
||||||
|
"@typescript-eslint/parser": "^8.12.2",
|
||||||
"bindings": "^1.5.0",
|
"bindings": "^1.5.0",
|
||||||
"bootstrap": "5.2.3",
|
"bootstrap": "5.2.3",
|
||||||
"chokidar": "^3.5.1",
|
"chokidar": "^3.5.1",
|
||||||
"dompurify": "^3.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",
|
"fork-awesome": "^1.1.7",
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"marked": "^12.0.1",
|
"marked": "^12.0.1",
|
||||||
"node-sass": "^8.0.0",
|
"node-sass": "^8.0.0",
|
||||||
"popper.js": "^1.16.1",
|
"popper.js": "^1.16.1",
|
||||||
"postcss-loader": "^7.0.2",
|
"postcss-loader": "^7.0.2",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
"sass-loader": "^14.0.0",
|
"sass-loader": "^14.0.0",
|
||||||
"select2": "^4.0.13",
|
"select2": "^4.0.13",
|
||||||
"select2-bootstrap-theme": "0.1.0-beta.10",
|
"select2-bootstrap-theme": "0.1.0-beta.10",
|
||||||
"style-loader": "^3.3.1",
|
"style-loader": "^3.3.1",
|
||||||
"ts-loader": "^9.3.1",
|
"ts-loader": "^9.3.1",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.6.3",
|
||||||
|
"typescript-eslint": "^8.13.0",
|
||||||
"vue-loader": "^17.0.0",
|
"vue-loader": "^17.0.0",
|
||||||
"webpack": "^5.75.0",
|
"webpack": "^5.75.0",
|
||||||
"webpack-cli": "^5.0.1"
|
"webpack-cli": "^5.0.1"
|
||||||
@ -68,6 +78,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev-server": "encore dev-server",
|
"dev-server": "encore dev-server",
|
||||||
"dev": "encore dev",
|
"dev": "encore dev",
|
||||||
|
"prettier": "prettier --write \"**/*.{js,ts,vue}\"",
|
||||||
"watch": "encore dev --watch",
|
"watch": "encore dev --watch",
|
||||||
"build": "encore production --progress"
|
"build": "encore production --progress"
|
||||||
},
|
},
|
||||||
|
@ -1 +1 @@
|
|||||||
require('./chillactivity.scss');
|
require("./chillactivity.scss");
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<concerned-groups v-if="hasPerson"></concerned-groups>
|
<concerned-groups v-if="hasPerson" />
|
||||||
<social-issues-acc v-if="hasSocialIssues"></social-issues-acc>
|
<social-issues-acc v-if="hasSocialIssues" />
|
||||||
<location v-if="hasLocation"></location>
|
<location v-if="hasLocation" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ConcernedGroups from './components/ConcernedGroups.vue';
|
import ConcernedGroups from "./components/ConcernedGroups.vue";
|
||||||
import SocialIssuesAcc from './components/SocialIssuesAcc.vue';
|
import SocialIssuesAcc from "./components/SocialIssuesAcc.vue";
|
||||||
import Location from './components/Location.vue';
|
import Location from "./components/Location.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
props: ['hasSocialIssues', 'hasLocation', 'hasPerson'],
|
props: ["hasSocialIssues", "hasLocation", "hasPerson"],
|
||||||
components: {
|
components: {
|
||||||
ConcernedGroups,
|
ConcernedGroups,
|
||||||
SocialIssuesAcc,
|
SocialIssuesAcc,
|
||||||
Location
|
Location,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,37 +1,38 @@
|
|||||||
import { getSocialIssues } from 'ChillPersonAssets/vuejs/AccompanyingCourse/api.js';
|
import { getSocialIssues } from "ChillPersonAssets/vuejs/AccompanyingCourse/api.js";
|
||||||
import { fetchResults } from 'ChillMainAssets/lib/api/apiMethods';
|
import { fetchResults } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load socialActions by socialIssue (id)
|
* Load socialActions by socialIssue (id)
|
||||||
*/
|
*/
|
||||||
const getSocialActionByIssue = (id) => {
|
const getSocialActionByIssue = (id) => {
|
||||||
const url = `/api/1.0/person/social/social-action/by-social-issue/${id}.json`;
|
const url = `/api/1.0/person/social/social-action/by-social-issue/${id}.json`;
|
||||||
return fetch(url)
|
return fetch(url).then((response) => {
|
||||||
.then(response => {
|
if (response.ok) {
|
||||||
if (response.ok) { return response.json(); }
|
return response.json();
|
||||||
throw Error('Error with request resource response');
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getLocations = () => fetchResults('/api/1.0/main/location.json');
|
const getLocations = () => fetchResults("/api/1.0/main/location.json");
|
||||||
|
|
||||||
const getLocationTypes = () => fetchResults('/api/1.0/main/location-type.json');
|
const getLocationTypes = () => fetchResults("/api/1.0/main/location-type.json");
|
||||||
|
|
||||||
const getUserCurrentLocation =
|
const getUserCurrentLocation = () =>
|
||||||
() => fetch('/api/1.0/main/user-current-location.json')
|
fetch("/api/1.0/main/user-current-location.json").then((response) => {
|
||||||
.then(response => {
|
if (response.ok) {
|
||||||
if (response.ok) { return response.json(); }
|
return response.json();
|
||||||
throw Error('Error with request resource response');
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load Location Type by defaultFor
|
* Load Location Type by defaultFor
|
||||||
* @param {string} entity - can be "person" or "thirdparty"
|
* @param {string} entity - can be "person" or "thirdparty"
|
||||||
*/
|
*/
|
||||||
const getLocationTypeByDefaultFor = (entity) => {
|
const getLocationTypeByDefaultFor = (entity) => {
|
||||||
return getLocationTypes().then(results =>
|
return getLocationTypes().then(
|
||||||
results.filter(t => t.defaultFor === entity)[0]
|
(results) => results.filter((t) => t.defaultFor === entity)[0],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,15 +46,16 @@ const getLocationTypeByDefaultFor = (entity) => {
|
|||||||
const postLocation = (body) => {
|
const postLocation = (body) => {
|
||||||
const url = `/api/1.0/main/location.json`;
|
const url = `/api/1.0/main/location.json`;
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
"Content-Type": "application/json;charset=utf-8",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(body)
|
body: JSON.stringify(body),
|
||||||
})
|
}).then((response) => {
|
||||||
.then(response => {
|
if (response.ok) {
|
||||||
if (response.ok) { return response.json(); }
|
return response.json();
|
||||||
throw Error('Error with request resource response');
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,5 +66,5 @@ export {
|
|||||||
getLocationTypes,
|
getLocationTypes,
|
||||||
getLocationTypeByDefaultFor,
|
getLocationTypeByDefaultFor,
|
||||||
postLocation,
|
postLocation,
|
||||||
getUserCurrentLocation
|
getUserCurrentLocation,
|
||||||
};
|
};
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<teleport to="#add-persons" v-if="isComponentVisible">
|
<teleport to="#add-persons" v-if="isComponentVisible">
|
||||||
|
|
||||||
<div class="flex-bloc concerned-groups" :class="getContext">
|
<div class="flex-bloc concerned-groups" :class="getContext">
|
||||||
<persons-bloc
|
<persons-bloc
|
||||||
v-for="bloc in contextPersonsBlocs"
|
v-for="bloc in contextPersonsBlocs"
|
||||||
v-bind:key="bloc.key"
|
:key="bloc.key"
|
||||||
v-bind:bloc="bloc"
|
:bloc="bloc"
|
||||||
v-bind:blocWidth="getBlocWidth"
|
:bloc-width="getBlocWidth"
|
||||||
v-bind:setPersonsInBloc="setPersonsInBloc">
|
:set-persons-in-bloc="setPersonsInBloc"
|
||||||
</persons-bloc>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0">
|
<div
|
||||||
|
v-if="
|
||||||
|
getContext === 'accompanyingCourse' &&
|
||||||
|
suggestedEntities.length > 0
|
||||||
|
"
|
||||||
|
>
|
||||||
<ul class="list-suggest add-items inline">
|
<ul class="list-suggest add-items inline">
|
||||||
<li v-for="(p, i) in suggestedEntities" @click="addSuggestedEntity(p)" :key="`suggestedEntities-${i}`">
|
<li
|
||||||
<person-text v-if="p.type === 'person'" :person="p"></person-text>
|
v-for="(p, i) in suggestedEntities"
|
||||||
|
@click="addSuggestedEntity(p)"
|
||||||
|
:key="`suggestedEntities-${i}`"
|
||||||
|
>
|
||||||
|
<person-text v-if="p.type === 'person'" :person="p" />
|
||||||
<span v-else>{{ p.text }}</span>
|
<span v-else>{{ p.text }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -22,114 +30,126 @@
|
|||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li class="add-persons">
|
<li class="add-persons">
|
||||||
<add-persons
|
<add-persons
|
||||||
buttonTitle="activity.add_persons"
|
button-title="activity.add_persons"
|
||||||
modalTitle="activity.add_persons"
|
modal-title="activity.add_persons"
|
||||||
v-bind:key="addPersons.key"
|
:key="addPersons.key"
|
||||||
v-bind:options="addPersonsOptions"
|
:options="addPersonsOptions"
|
||||||
@addNewPersons="addNewPersons"
|
@add-new-persons="addNewPersons"
|
||||||
ref="addPersons">
|
ref="addPersons"
|
||||||
</add-persons>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</teleport>
|
</teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapGetters } from 'vuex';
|
import { mapState, mapGetters } from "vuex";
|
||||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
|
||||||
import PersonsBloc from './ConcernedGroups/PersonsBloc.vue';
|
import PersonsBloc from "./ConcernedGroups/PersonsBloc.vue";
|
||||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ConcernedGroups",
|
name: "ConcernedGroups",
|
||||||
components: {
|
components: {
|
||||||
AddPersons,
|
AddPersons,
|
||||||
PersonsBloc,
|
PersonsBloc,
|
||||||
PersonText
|
PersonText,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
personsBlocs: [
|
personsBlocs: [
|
||||||
{ key: 'persons',
|
{
|
||||||
title: 'activity.bloc_persons',
|
key: "persons",
|
||||||
|
title: "activity.bloc_persons",
|
||||||
persons: [],
|
persons: [],
|
||||||
included: false
|
included: false,
|
||||||
},
|
},
|
||||||
{ key: 'personsAssociated',
|
{
|
||||||
title: 'activity.bloc_persons_associated',
|
key: "personsAssociated",
|
||||||
|
title: "activity.bloc_persons_associated",
|
||||||
persons: [],
|
persons: [],
|
||||||
included: window.activity ? window.activity.activityType.personsVisible !== 0 : true
|
included: window.activity
|
||||||
|
? window.activity.activityType.personsVisible !== 0
|
||||||
|
: true,
|
||||||
},
|
},
|
||||||
{ key: 'personsNotAssociated',
|
{
|
||||||
title: 'activity.bloc_persons_not_associated',
|
key: "personsNotAssociated",
|
||||||
|
title: "activity.bloc_persons_not_associated",
|
||||||
persons: [],
|
persons: [],
|
||||||
included: window.activity ? window.activity.activityType.personsVisible !== 0 : true
|
included: window.activity
|
||||||
|
? window.activity.activityType.personsVisible !== 0
|
||||||
|
: true,
|
||||||
},
|
},
|
||||||
{ key: 'thirdparty',
|
{
|
||||||
title: 'activity.bloc_thirdparty',
|
key: "thirdparty",
|
||||||
|
title: "activity.bloc_thirdparty",
|
||||||
persons: [],
|
persons: [],
|
||||||
included: window.activity ? window.activity.activityType.thirdPartiesVisible !== 0 : true
|
included: window.activity
|
||||||
|
? window.activity.activityType.thirdPartiesVisible !== 0
|
||||||
|
: true,
|
||||||
},
|
},
|
||||||
{ key: 'users',
|
{
|
||||||
title: 'activity.bloc_users',
|
key: "users",
|
||||||
|
title: "activity.bloc_users",
|
||||||
persons: [],
|
persons: [],
|
||||||
included: window.activity ? window.activity.activityType.usersVisible !== 0 : true
|
included: window.activity
|
||||||
|
? window.activity.activityType.usersVisible !== 0
|
||||||
|
: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
addPersons: {
|
addPersons: {
|
||||||
key: 'activity'
|
key: "activity",
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isComponentVisible() {
|
isComponentVisible() {
|
||||||
return window.activity
|
return window.activity
|
||||||
? (window.activity.activityType.personsVisible !== 0 || window.activity.activityType.thirdPartiesVisible !== 0 || window.activity.activityType.usersVisible !== 0)
|
? window.activity.activityType.personsVisible !== 0 ||
|
||||||
: true
|
window.activity.activityType.thirdPartiesVisible !== 0 ||
|
||||||
|
window.activity.activityType.usersVisible !== 0
|
||||||
|
: true;
|
||||||
},
|
},
|
||||||
...mapState({
|
...mapState({
|
||||||
persons: state => state.activity.persons,
|
persons: (state) => state.activity.persons,
|
||||||
thirdParties: state => state.activity.thirdParties,
|
thirdParties: (state) => state.activity.thirdParties,
|
||||||
users: state => state.activity.users,
|
users: (state) => state.activity.users,
|
||||||
accompanyingCourse: state => state.activity.accompanyingPeriod
|
accompanyingCourse: (state) => state.activity.accompanyingPeriod,
|
||||||
}),
|
}),
|
||||||
...mapGetters([
|
...mapGetters(["suggestedEntities"]),
|
||||||
'suggestedEntities'
|
|
||||||
]),
|
|
||||||
getContext() {
|
getContext() {
|
||||||
return (this.accompanyingCourse) ? "accompanyingCourse" : "person";
|
return this.accompanyingCourse ? "accompanyingCourse" : "person";
|
||||||
},
|
},
|
||||||
contextPersonsBlocs() {
|
contextPersonsBlocs() {
|
||||||
return this.personsBlocs.filter(bloc => bloc.included !== false);
|
return this.personsBlocs.filter((bloc) => bloc.included !== false);
|
||||||
},
|
},
|
||||||
addPersonsOptions() {
|
addPersonsOptions() {
|
||||||
let optionsType = [];
|
let optionsType = [];
|
||||||
if (window.activity) {
|
if (window.activity) {
|
||||||
if (window.activity.activityType.personsVisible !== 0) {
|
if (window.activity.activityType.personsVisible !== 0) {
|
||||||
optionsType.push('person')
|
optionsType.push("person");
|
||||||
}
|
}
|
||||||
if (window.activity.activityType.thirdPartiesVisible !== 0) {
|
if (window.activity.activityType.thirdPartiesVisible !== 0) {
|
||||||
optionsType.push('thirdparty')
|
optionsType.push("thirdparty");
|
||||||
}
|
}
|
||||||
if (window.activity.activityType.usersVisible !== 0) {
|
if (window.activity.activityType.usersVisible !== 0) {
|
||||||
optionsType.push('user')
|
optionsType.push("user");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
optionsType = ['person', 'thirdparty', 'user'];
|
optionsType = ["person", "thirdparty", "user"];
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: optionsType,
|
type: optionsType,
|
||||||
priority: null,
|
priority: null,
|
||||||
uniq: false,
|
uniq: false,
|
||||||
button: {
|
button: {
|
||||||
size: 'btn-sm'
|
size: "btn-sm",
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
getBlocWidth() {
|
getBlocWidth() {
|
||||||
return Math.round(100/(this.contextPersonsBlocs.length)) + '%';
|
return Math.round(100 / this.contextPersonsBlocs.length) + "%";
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.setPersonsInBloc();
|
this.setPersonsInBloc();
|
||||||
@ -140,31 +160,31 @@ export default {
|
|||||||
if (this.accompanyingCourse) {
|
if (this.accompanyingCourse) {
|
||||||
groups = this.splitPersonsInGroups();
|
groups = this.splitPersonsInGroups();
|
||||||
}
|
}
|
||||||
this.personsBlocs.forEach(bloc => {
|
this.personsBlocs.forEach((bloc) => {
|
||||||
if (this.accompanyingCourse) {
|
if (this.accompanyingCourse) {
|
||||||
switch (bloc.key) {
|
switch (bloc.key) {
|
||||||
case 'personsAssociated':
|
case "personsAssociated":
|
||||||
bloc.persons = groups.personsAssociated;
|
bloc.persons = groups.personsAssociated;
|
||||||
bloc.included = true;
|
bloc.included = true;
|
||||||
break;
|
break;
|
||||||
case 'personsNotAssociated':
|
case "personsNotAssociated":
|
||||||
bloc.persons = groups.personsNotAssociated;
|
bloc.persons = groups.personsNotAssociated;
|
||||||
bloc.included = true;
|
bloc.included = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (bloc.key) {
|
switch (bloc.key) {
|
||||||
case 'persons':
|
case "persons":
|
||||||
bloc.persons = this.persons;
|
bloc.persons = this.persons;
|
||||||
bloc.included = true;
|
bloc.included = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (bloc.key) {
|
switch (bloc.key) {
|
||||||
case 'thirdparty':
|
case "thirdparty":
|
||||||
bloc.persons = this.thirdParties;
|
bloc.persons = this.thirdParties;
|
||||||
break;
|
break;
|
||||||
case 'users':
|
case "users":
|
||||||
bloc.persons = this.users;
|
bloc.persons = this.users;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -174,23 +194,25 @@ export default {
|
|||||||
let personsAssociated = [];
|
let personsAssociated = [];
|
||||||
let personsNotAssociated = this.persons;
|
let personsNotAssociated = this.persons;
|
||||||
let participations = this.getCourseParticipations();
|
let participations = this.getCourseParticipations();
|
||||||
this.persons.forEach(person => {
|
this.persons.forEach((person) => {
|
||||||
participations.forEach(participation => {
|
participations.forEach((participation) => {
|
||||||
if (person.id === participation.id) {
|
if (person.id === participation.id) {
|
||||||
//console.log(person.id);
|
//console.log(person.id);
|
||||||
personsAssociated.push(person);
|
personsAssociated.push(person);
|
||||||
personsNotAssociated = personsNotAssociated.filter(p => p !== person);
|
personsNotAssociated = personsNotAssociated.filter(
|
||||||
|
(p) => p !== person,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
'personsAssociated': personsAssociated,
|
personsAssociated: personsAssociated,
|
||||||
'personsNotAssociated': personsNotAssociated
|
personsNotAssociated: personsNotAssociated,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getCourseParticipations() {
|
getCourseParticipations() {
|
||||||
let participations = [];
|
let participations = [];
|
||||||
this.accompanyingCourse.participations.forEach(participation => {
|
this.accompanyingCourse.participations.forEach((participation) => {
|
||||||
if (!participation.endDate) {
|
if (!participation.endDate) {
|
||||||
participations.push(participation.person);
|
participations.push(participation.person);
|
||||||
}
|
}
|
||||||
@ -198,22 +220,23 @@ export default {
|
|||||||
return participations;
|
return participations;
|
||||||
},
|
},
|
||||||
addNewPersons({ selected, modal }) {
|
addNewPersons({ selected, modal }) {
|
||||||
console.log('@@@ CLICK button addNewPersons', selected);
|
console.log("@@@ CLICK button addNewPersons", selected);
|
||||||
selected.forEach((item) => {
|
selected.forEach((item) => {
|
||||||
this.$store.dispatch('addPersonsInvolved', item);
|
this.$store.dispatch("addPersonsInvolved", item);
|
||||||
}, this
|
}, this);
|
||||||
);
|
|
||||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
this.$refs.addPersons.resetSearch(); // to cast child method
|
||||||
modal.showModal = false;
|
modal.showModal = false;
|
||||||
this.setPersonsInBloc();
|
this.setPersonsInBloc();
|
||||||
},
|
},
|
||||||
addSuggestedEntity(person) {
|
addSuggestedEntity(person) {
|
||||||
this.$store.dispatch('addPersonsInvolved', { result: person, type: 'person' });
|
this.$store.dispatch("addPersonsInvolved", {
|
||||||
|
result: person,
|
||||||
|
type: "person",
|
||||||
|
});
|
||||||
this.setPersonsInBloc();
|
this.setPersonsInBloc();
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped></style>
|
||||||
</style>
|
|
||||||
|
@ -2,21 +2,20 @@
|
|||||||
<li>
|
<li>
|
||||||
<span :title="person.text" @click.prevent="$emit('remove', person)">
|
<span :title="person.text" @click.prevent="$emit('remove', person)">
|
||||||
<span class="chill_denomination">
|
<span class="chill_denomination">
|
||||||
<person-text :person="person" :isCut="true"></person-text>
|
<person-text :person="person" :is-cut="true" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PersonBadge",
|
name: "PersonBadge",
|
||||||
props: ['person'],
|
props: ["person"],
|
||||||
components: {
|
components: {
|
||||||
PersonText
|
PersonText,
|
||||||
},
|
},
|
||||||
// computed: {
|
// computed: {
|
||||||
// textCutted() {
|
// textCutted() {
|
||||||
@ -24,9 +23,8 @@ export default {
|
|||||||
// return this.person.text.slice(0,15) + more;
|
// return this.person.text.slice(0,15) + more;
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
emits: ['remove'],
|
emits: ["remove"],
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped></style>
|
||||||
</style>
|
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
<ul class="list-suggest remove-items">
|
<ul class="list-suggest remove-items">
|
||||||
<person-badge
|
<person-badge
|
||||||
v-for="person in bloc.persons"
|
v-for="person in bloc.persons"
|
||||||
v-bind:key="person.id"
|
:key="person.id"
|
||||||
v-bind:person="person"
|
:person="person"
|
||||||
@remove="removePerson">
|
@remove="removePerson"
|
||||||
</person-badge>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -19,23 +19,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PersonBadge from './PersonBadge.vue';
|
import PersonBadge from "./PersonBadge.vue";
|
||||||
export default {
|
export default {
|
||||||
name: "PersonsBloc",
|
name: "PersonsBloc",
|
||||||
components: {
|
components: {
|
||||||
PersonBadge
|
PersonBadge,
|
||||||
},
|
},
|
||||||
props: ['bloc', 'setPersonsInBloc', 'blocWidth'],
|
props: ["bloc", "setPersonsInBloc", "blocWidth"],
|
||||||
methods: {
|
methods: {
|
||||||
removePerson(item) {
|
removePerson(item) {
|
||||||
console.log('@@ CLICK remove person: item', item);
|
console.log("@@ CLICK remove person: item", item);
|
||||||
this.$store.dispatch('removePersonInvolved', item);
|
this.$store.dispatch("removePersonInvolved", item);
|
||||||
this.setPersonsInBloc();
|
this.setPersonsInBloc();
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss"></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -22,9 +22,8 @@
|
|||||||
group-values="locations"
|
group-values="locations"
|
||||||
group-label="locationGroup"
|
group-label="locationGroup"
|
||||||
v-model="location"
|
v-model="location"
|
||||||
>
|
/>
|
||||||
</VueMultiselect>
|
<new-location :available-locations="availableLocations" />
|
||||||
<new-location v-bind:availableLocations="availableLocations"></new-location>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</teleport>
|
</teleport>
|
||||||
@ -43,9 +42,8 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
locationClassList:
|
locationClassList: `col-form-label col-sm-4 ${document.querySelector("input#chill_activitybundle_activity_location").getAttribute("required") ? "required" : ""}`,
|
||||||
`col-form-label col-sm-4 ${document.querySelector('input#chill_activitybundle_activity_location').getAttribute('required') ? 'required' : ''}`,
|
};
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["activity", "availableLocations"]),
|
...mapState(["activity", "availableLocations"]),
|
||||||
@ -61,16 +59,16 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
labelAccompanyingCourseLocation(value) {
|
labelAccompanyingCourseLocation(value) {
|
||||||
return `${value.address.text} (${value.locationType.title.fr})`
|
return `${value.address.text} (${value.locationType.title.fr})`;
|
||||||
},
|
},
|
||||||
customLabel(value) {
|
customLabel(value) {
|
||||||
return value.locationType
|
return value.locationType
|
||||||
? value.name
|
? value.name
|
||||||
? value.name === '__AccompanyingCourseLocation__'
|
? value.name === "__AccompanyingCourseLocation__"
|
||||||
? this.labelAccompanyingCourseLocation(value)
|
? this.labelAccompanyingCourseLocation(value)
|
||||||
: `${value.name} (${value.locationType.title.fr})`
|
: `${value.name} (${value.locationType.title.fr})`
|
||||||
: value.locationType.title.fr
|
: value.locationType.title.fr
|
||||||
: '';
|
: "";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -3,84 +3,129 @@
|
|||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-sm btn-create" @click="openModal">
|
<a class="btn btn-sm btn-create" @click="openModal">
|
||||||
{{ $t('activity.create_new_location') }}
|
{{ $t("activity.create_new_location") }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<teleport to="body">
|
<teleport to="body">
|
||||||
<modal v-if="modal.showModal"
|
<modal
|
||||||
:modalDialogClass="modal.modalDialogClass"
|
v-if="modal.showModal"
|
||||||
@close="modal.showModal = false">
|
:modal-dialog-class="modal.modalDialogClass"
|
||||||
|
@close="modal.showModal = false"
|
||||||
<template v-slot:header>
|
>
|
||||||
<h3 class="modal-title">{{ $t('activity.create_new_location') }}</h3>
|
<template #header>
|
||||||
|
<h3 class="modal-title">
|
||||||
|
{{ $t("activity.create_new_location") }}
|
||||||
|
</h3>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:body>
|
<template #body>
|
||||||
<form>
|
<form>
|
||||||
<div class="alert alert-warning" v-if="errors.length">
|
<div class="alert alert-warning" v-if="errors.length">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(e, i) in errors" :key="i">{{ e }}</li>
|
<li v-for="(e, i) in errors" :key="i">
|
||||||
|
{{ e }}
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-floating mb-3">
|
<div class="form-floating mb-3">
|
||||||
<select class="form-select form-select-lg" id="type" required v-model="selectType">
|
<select
|
||||||
<option selected disabled value="">{{ $t('activity.choose_location_type') }}</option>
|
class="form-select form-select-lg"
|
||||||
<option v-for="t in locationTypes" :value="t" :key="t.id">
|
id="type"
|
||||||
|
required
|
||||||
|
v-model="selectType"
|
||||||
|
>
|
||||||
|
<option selected disabled value="">
|
||||||
|
{{ $t("activity.choose_location_type") }}
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
v-for="t in locationTypes"
|
||||||
|
:value="t"
|
||||||
|
:key="t.id"
|
||||||
|
>
|
||||||
{{ t.title.fr }}
|
{{ t.title.fr }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<label>{{ $t('activity.location_fields.type') }}</label>
|
<label>{{
|
||||||
|
$t("activity.location_fields.type")
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-floating mb-3">
|
<div class="form-floating mb-3">
|
||||||
<input class="form-control form-control-lg" id="name" v-model="inputName" placeholder />
|
<input
|
||||||
<label for="name">{{ $t('activity.location_fields.name') }}</label>
|
class="form-control form-control-lg"
|
||||||
|
id="name"
|
||||||
|
v-model="inputName"
|
||||||
|
placeholder
|
||||||
|
/>
|
||||||
|
<label for="name">{{
|
||||||
|
$t("activity.location_fields.name")
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<add-address
|
<add-address
|
||||||
:context="addAddress.context"
|
:context="addAddress.context"
|
||||||
:options="addAddress.options"
|
:options="addAddress.options"
|
||||||
:addressChangedCallback="submitNewAddress"
|
:address-changed-callback="submitNewAddress"
|
||||||
v-if="showAddAddress"
|
v-if="showAddAddress"
|
||||||
ref="addAddress">
|
ref="addAddress"
|
||||||
</add-address>
|
/>
|
||||||
|
|
||||||
<div class="form-floating mb-3" v-if="showContactData">
|
<div class="form-floating mb-3" v-if="showContactData">
|
||||||
<input class="form-control form-control-lg" id="phonenumber1" v-model="inputPhonenumber1" placeholder />
|
<input
|
||||||
<label for="phonenumber1">{{ $t('activity.location_fields.phonenumber1') }}</label>
|
class="form-control form-control-lg"
|
||||||
|
id="phonenumber1"
|
||||||
|
v-model="inputPhonenumber1"
|
||||||
|
placeholder
|
||||||
|
/>
|
||||||
|
<label for="phonenumber1">{{
|
||||||
|
$t("activity.location_fields.phonenumber1")
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-floating mb-3" v-if="hasPhonenumber1">
|
<div class="form-floating mb-3" v-if="hasPhonenumber1">
|
||||||
<input class="form-control form-control-lg" id="phonenumber2" v-model="inputPhonenumber2" placeholder />
|
<input
|
||||||
<label for="phonenumber2">{{ $t('activity.location_fields.phonenumber2') }}</label>
|
class="form-control form-control-lg"
|
||||||
|
id="phonenumber2"
|
||||||
|
v-model="inputPhonenumber2"
|
||||||
|
placeholder
|
||||||
|
/>
|
||||||
|
<label for="phonenumber2">{{
|
||||||
|
$t("activity.location_fields.phonenumber2")
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-floating mb-3" v-if="showContactData">
|
<div class="form-floating mb-3" v-if="showContactData">
|
||||||
<input class="form-control form-control-lg" id="email" v-model="inputEmail" placeholder />
|
<input
|
||||||
<label for="email">{{ $t('activity.location_fields.email') }}</label>
|
class="form-control form-control-lg"
|
||||||
|
id="email"
|
||||||
|
v-model="inputEmail"
|
||||||
|
placeholder
|
||||||
|
/>
|
||||||
|
<label for="email">{{
|
||||||
|
$t("activity.location_fields.email")
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:footer>
|
<template #footer>
|
||||||
<button class="btn btn-save"
|
<button
|
||||||
|
class="btn btn-save"
|
||||||
@click.prevent="saveNewLocation"
|
@click.prevent="saveNewLocation"
|
||||||
>
|
>
|
||||||
{{ $t('action.save') }}
|
{{ $t("action.save") }}
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</modal>
|
</modal>
|
||||||
</teleport>
|
</teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Modal from 'ChillMainAssets/vuejs/_components/Modal.vue';
|
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
||||||
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
|
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { getLocationTypes } from "../../api";
|
import { getLocationTypes } from "../../api";
|
||||||
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
|
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "NewLocation",
|
name: "NewLocation",
|
||||||
@ -88,7 +133,7 @@ export default {
|
|||||||
Modal,
|
Modal,
|
||||||
AddAddress,
|
AddAddress,
|
||||||
},
|
},
|
||||||
props: ['availableLocations'],
|
props: ["availableLocations"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
errors: [],
|
errors: [],
|
||||||
@ -103,35 +148,42 @@ export default {
|
|||||||
locationTypes: [],
|
locationTypes: [],
|
||||||
modal: {
|
modal: {
|
||||||
showModal: false,
|
showModal: false,
|
||||||
modalDialogClass: "modal-dialog-scrollable modal-xl"
|
modalDialogClass: "modal-dialog-scrollable modal-xl",
|
||||||
},
|
},
|
||||||
addAddress: {
|
addAddress: {
|
||||||
options: {
|
options: {
|
||||||
button: {
|
button: {
|
||||||
text: { create: 'activity.create_address', edit: 'activity.edit_address' },
|
text: {
|
||||||
size: 'btn-sm'
|
create: "activity.create_address",
|
||||||
|
edit: "activity.edit_address",
|
||||||
|
},
|
||||||
|
size: "btn-sm",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
create: "activity.create_address",
|
||||||
|
edit: "activity.edit_address",
|
||||||
},
|
},
|
||||||
title: { create: 'activity.create_address', edit: 'activity.edit_address' },
|
|
||||||
},
|
},
|
||||||
context: {
|
context: {
|
||||||
target: { //name, id
|
target: {
|
||||||
|
//name, id
|
||||||
},
|
},
|
||||||
edit: false,
|
edit: false,
|
||||||
addressId: null,
|
addressId: null,
|
||||||
defaults: window.addaddress
|
defaults: window.addaddress,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['activity']),
|
...mapState(["activity"]),
|
||||||
selectType: {
|
selectType: {
|
||||||
get() {
|
get() {
|
||||||
return this.selected.type;
|
return this.selected.type;
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.selected.type = value;
|
this.selected.type = value;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
inputName: {
|
inputName: {
|
||||||
get() {
|
get() {
|
||||||
@ -139,7 +191,7 @@ export default {
|
|||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.selected.name = value;
|
this.selected.name = value;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
inputEmail: {
|
inputEmail: {
|
||||||
get() {
|
get() {
|
||||||
@ -147,7 +199,7 @@ export default {
|
|||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.selected.email = value;
|
this.selected.email = value;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
inputPhonenumber1: {
|
inputPhonenumber1: {
|
||||||
get() {
|
get() {
|
||||||
@ -155,7 +207,7 @@ export default {
|
|||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.selected.phonenumber1 = value;
|
this.selected.phonenumber1 = value;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
inputPhonenumber2: {
|
inputPhonenumber2: {
|
||||||
get() {
|
get() {
|
||||||
@ -163,15 +215,18 @@ export default {
|
|||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.selected.phonenumber2 = value;
|
this.selected.phonenumber2 = value;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
hasPhonenumber1() {
|
hasPhonenumber1() {
|
||||||
return this.selected.phonenumber1 !== null && this.selected.phonenumber1 !== "";
|
return (
|
||||||
|
this.selected.phonenumber1 !== null &&
|
||||||
|
this.selected.phonenumber1 !== ""
|
||||||
|
);
|
||||||
},
|
},
|
||||||
showAddAddress() {
|
showAddAddress() {
|
||||||
let cond = false;
|
let cond = false;
|
||||||
if (this.selected.type) {
|
if (this.selected.type) {
|
||||||
if (this.selected.type.addressRequired !== 'never') {
|
if (this.selected.type.addressRequired !== "never") {
|
||||||
cond = true;
|
cond = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,7 +235,7 @@ export default {
|
|||||||
showContactData() {
|
showContactData() {
|
||||||
let cond = false;
|
let cond = false;
|
||||||
if (this.selected.type) {
|
if (this.selected.type) {
|
||||||
if (this.selected.type.contactData !== 'never') {
|
if (this.selected.type.contactData !== "never") {
|
||||||
cond = true;
|
cond = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,28 +250,39 @@ export default {
|
|||||||
let cond = true;
|
let cond = true;
|
||||||
this.errors = [];
|
this.errors = [];
|
||||||
if (!this.selected.type) {
|
if (!this.selected.type) {
|
||||||
this.errors.push('Type de localisation requis');
|
this.errors.push("Type de localisation requis");
|
||||||
cond = false;
|
cond = false;
|
||||||
} else {
|
} else {
|
||||||
if (this.selected.type.addressRequired === 'required' && !this.selected.addressId) {
|
if (
|
||||||
this.errors.push('Adresse requise');
|
this.selected.type.addressRequired === "required" &&
|
||||||
|
!this.selected.addressId
|
||||||
|
) {
|
||||||
|
this.errors.push("Adresse requise");
|
||||||
cond = false;
|
cond = false;
|
||||||
}
|
}
|
||||||
if (this.selected.type.contactData === 'required' && !this.selected.phonenumber1) {
|
if (
|
||||||
this.errors.push('Numéro de téléphone requis');
|
this.selected.type.contactData === "required" &&
|
||||||
|
!this.selected.phonenumber1
|
||||||
|
) {
|
||||||
|
this.errors.push("Numéro de téléphone requis");
|
||||||
cond = false;
|
cond = false;
|
||||||
}
|
}
|
||||||
if (this.selected.type.contactData === 'required' && !this.selected.email) {
|
if (
|
||||||
this.errors.push('Adresse email requise');
|
this.selected.type.contactData === "required" &&
|
||||||
|
!this.selected.email
|
||||||
|
) {
|
||||||
|
this.errors.push("Adresse email requise");
|
||||||
cond = false;
|
cond = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cond;
|
return cond;
|
||||||
},
|
},
|
||||||
getLocationTypesList() {
|
getLocationTypesList() {
|
||||||
getLocationTypes().then(results => {
|
getLocationTypes().then((results) => {
|
||||||
this.locationTypes = results.filter(t => t.availableForUsers === true);
|
this.locationTypes = results.filter(
|
||||||
})
|
(t) => t.availableForUsers === true,
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
openModal() {
|
openModal() {
|
||||||
this.modal.showModal = true;
|
this.modal.showModal = true;
|
||||||
@ -224,11 +290,11 @@ export default {
|
|||||||
saveNewLocation() {
|
saveNewLocation() {
|
||||||
if (this.checkForm()) {
|
if (this.checkForm()) {
|
||||||
let body = {
|
let body = {
|
||||||
type: 'location',
|
type: "location",
|
||||||
name: this.selected.name,
|
name: this.selected.name,
|
||||||
locationType: {
|
locationType: {
|
||||||
id: this.selected.type.id,
|
id: this.selected.type.id,
|
||||||
type: 'location-type'
|
type: "location-type",
|
||||||
},
|
},
|
||||||
phonenumber1: this.selected.phonenumber1,
|
phonenumber1: this.selected.phonenumber1,
|
||||||
phonenumber2: this.selected.phonenumber2,
|
phonenumber2: this.selected.phonenumber2,
|
||||||
@ -237,36 +303,36 @@ export default {
|
|||||||
if (this.selected.addressId) {
|
if (this.selected.addressId) {
|
||||||
body = Object.assign(body, {
|
body = Object.assign(body, {
|
||||||
address: {
|
address: {
|
||||||
id: this.selected.addressId
|
id: this.selected.addressId,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
makeFetch('POST', '/api/1.0/main/location.json', body)
|
makeFetch("POST", "/api/1.0/main/location.json", body)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
this.$store.dispatch('addAvailableLocationGroup', {
|
this.$store.dispatch("addAvailableLocationGroup", {
|
||||||
locationGroup: 'Localisations nouvellement créées',
|
locationGroup: "Localisations nouvellement créées",
|
||||||
locations: [response]
|
locations: [response],
|
||||||
});
|
});
|
||||||
this.$store.dispatch('updateLocation', response);
|
this.$store.dispatch("updateLocation", response);
|
||||||
this.modal.showModal = false;
|
this.modal.showModal = false;
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
if (error.name === 'ValidationException') {
|
if (error.name === "ValidationException") {
|
||||||
for (let v of error.violations) {
|
for (let v of error.violations) {
|
||||||
this.errors.push(v);
|
this.errors.push(v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.errors.push('An error occurred');
|
this.errors.push("An error occurred");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
submitNewAddress(payload) {
|
submitNewAddress(payload) {
|
||||||
this.selected.addressId = payload.addressId;
|
this.selected.addressId = payload.addressId;
|
||||||
this.addAddress.context.addressId = payload.addressId;
|
this.addAddress.context.addressId = payload.addressId;
|
||||||
this.addAddress.context.edit = true;
|
this.addAddress.context.edit = true;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<teleport to="#social-issues-acc">
|
<teleport to="#social-issues-acc">
|
||||||
|
|
||||||
<div class="mb-3 row">
|
<div class="mb-3 row">
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<label :class="socialIssuesClassList">{{ $t('activity.social_issues') }}</label>
|
<label :class="socialIssuesClassList">{{
|
||||||
|
$t("activity.social_issues")
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
|
|
||||||
<check-social-issue
|
<check-social-issue
|
||||||
v-for="issue in socialIssuesList"
|
v-for="issue in socialIssuesList"
|
||||||
:key="issue.id"
|
:key="issue.id"
|
||||||
:issue="issue"
|
:issue="issue"
|
||||||
:selection="socialIssuesSelected"
|
:selection="socialIssuesSelected"
|
||||||
@updateSelected="updateIssuesSelected">
|
@update-selected="updateIssuesSelected"
|
||||||
</check-social-issue>
|
/>
|
||||||
|
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
<VueMultiselect
|
<VueMultiselect
|
||||||
@ -33,72 +33,81 @@
|
|||||||
:loading="issueIsLoading"
|
:loading="issueIsLoading"
|
||||||
:placeholder="$t('activity.choose_other_social_issue')"
|
:placeholder="$t('activity.choose_other_social_issue')"
|
||||||
:options="socialIssuesOther"
|
:options="socialIssuesOther"
|
||||||
@select="addIssueInList">
|
@select="addIssueInList"
|
||||||
</VueMultiselect>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3 row">
|
<div class="mb-3 row">
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<label :class="socialActionsClassList">{{ $t('activity.social_actions') }}</label>
|
<label :class="socialActionsClassList">{{
|
||||||
|
$t("activity.social_actions")
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
|
|
||||||
<div v-if="actionIsLoading === true">
|
<div v-if="actionIsLoading === true">
|
||||||
<i class="chill-green fa fa-circle-o-notch fa-spin fa-lg"></i>
|
<i class="chill-green fa fa-circle-o-notch fa-spin fa-lg" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span v-else-if="socialIssuesSelected.length === 0" class="inline-choice chill-no-data-statement mt-3">
|
<span
|
||||||
{{ $t('activity.select_first_a_social_issue') }}
|
v-else-if="socialIssuesSelected.length === 0"
|
||||||
|
class="inline-choice chill-no-data-statement mt-3"
|
||||||
|
>
|
||||||
|
{{ $t("activity.select_first_a_social_issue") }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<template v-else-if="socialActionsList.length > 0">
|
<template v-else-if="socialActionsList.length > 0">
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
socialIssuesSelected.length ||
|
||||||
|
socialActionsSelected.length
|
||||||
|
"
|
||||||
|
>
|
||||||
<check-social-action
|
<check-social-action
|
||||||
v-if="socialIssuesSelected.length || socialActionsSelected.length"
|
|
||||||
v-for="action in socialActionsList"
|
v-for="action in socialActionsList"
|
||||||
:key="action.id"
|
:key="action.id"
|
||||||
:action="action"
|
:action="action"
|
||||||
:selection="socialActionsSelected"
|
:selection="socialActionsSelected"
|
||||||
@updateSelected="updateActionsSelected">
|
@update-selected="updateActionsSelected"
|
||||||
</check-social-action>
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<span v-else-if="actionAreLoaded && socialActionsList.length === 0" class="inline-choice chill-no-data-statement mt-3">
|
<span
|
||||||
{{ $t('activity.social_action_list_empty') }}
|
v-else-if="
|
||||||
|
actionAreLoaded && socialActionsList.length === 0
|
||||||
|
"
|
||||||
|
class="inline-choice chill-no-data-statement mt-3"
|
||||||
|
>
|
||||||
|
{{ $t("activity.social_action_list_empty") }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</teleport>
|
</teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import VueMultiselect from 'vue-multiselect';
|
import VueMultiselect from "vue-multiselect";
|
||||||
import CheckSocialIssue from './SocialIssuesAcc/CheckSocialIssue.vue';
|
import CheckSocialIssue from "./SocialIssuesAcc/CheckSocialIssue.vue";
|
||||||
import CheckSocialAction from './SocialIssuesAcc/CheckSocialAction.vue';
|
import CheckSocialAction from "./SocialIssuesAcc/CheckSocialAction.vue";
|
||||||
import { getSocialIssues, getSocialActionByIssue } from '../api.js';
|
import { getSocialIssues, getSocialActionByIssue } from "../api.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "SocialIssuesAcc",
|
name: "SocialIssuesAcc",
|
||||||
components: {
|
components: {
|
||||||
CheckSocialIssue,
|
CheckSocialIssue,
|
||||||
CheckSocialAction,
|
CheckSocialAction,
|
||||||
VueMultiselect
|
VueMultiselect,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
issueIsLoading: false,
|
issueIsLoading: false,
|
||||||
actionIsLoading: false,
|
actionIsLoading: false,
|
||||||
actionAreLoaded: false,
|
actionAreLoaded: false,
|
||||||
socialIssuesClassList:
|
socialIssuesClassList: `col-form-label ${document.querySelector("input#chill_activitybundle_activity_socialIssues").getAttribute("required") ? "required" : ""}`,
|
||||||
`col-form-label ${document.querySelector('input#chill_activitybundle_activity_socialIssues').getAttribute('required') ? 'required' : ''}`,
|
socialActionsClassList: `col-form-label ${document.querySelector("input#chill_activitybundle_activity_socialActions").getAttribute("required") ? "required" : ""}`,
|
||||||
socialActionsClassList:
|
};
|
||||||
`col-form-label ${document.querySelector('input#chill_activitybundle_activity_socialActions').getAttribute('required') ? 'required' : ''}`,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
socialIssuesList() {
|
socialIssuesList() {
|
||||||
@ -115,109 +124,115 @@ export default {
|
|||||||
},
|
},
|
||||||
socialActionsSelected() {
|
socialActionsSelected() {
|
||||||
return this.$store.state.activity.socialActions;
|
return this.$store.state.activity.socialActions;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
/* Load others issues in multiselect
|
/* Load others issues in multiselect
|
||||||
*/
|
*/
|
||||||
this.issueIsLoading = true;
|
this.issueIsLoading = true;
|
||||||
this.actionAreLoaded = false;
|
this.actionAreLoaded = false;
|
||||||
getSocialIssues().then(response => new Promise((resolve, reject) => {
|
getSocialIssues().then(
|
||||||
this.$store.commit('updateIssuesOther', response.results);
|
(response) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
this.$store.commit("updateIssuesOther", response.results);
|
||||||
|
|
||||||
/* Add in list the issues already associated (if not yet listed)
|
/* Add in list the issues already associated (if not yet listed)
|
||||||
*/
|
*/
|
||||||
this.socialIssuesSelected.forEach(issue => {
|
this.socialIssuesSelected.forEach((issue) => {
|
||||||
if (this.socialIssuesList.filter(i => i.id === issue.id).length !== 1) {
|
if (
|
||||||
this.$store.commit('addIssueInList', issue);
|
this.socialIssuesList.filter(
|
||||||
|
(i) => i.id === issue.id,
|
||||||
|
).length !== 1
|
||||||
|
) {
|
||||||
|
this.$store.commit("addIssueInList", issue);
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
/* Remove from multiselect the issues that are not yet in checkbox list
|
/* Remove from multiselect the issues that are not yet in checkbox list
|
||||||
*/
|
*/
|
||||||
this.socialIssuesList.forEach(issue => {
|
this.socialIssuesList.forEach((issue) => {
|
||||||
this.$store.commit('removeIssueInOther', issue);
|
this.$store.commit("removeIssueInOther", issue);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
/* Filter issues
|
/* Filter issues
|
||||||
*/
|
*/
|
||||||
this.$store.commit('filterList', 'issues');
|
this.$store.commit("filterList", "issues");
|
||||||
|
|
||||||
/* Add in list the actions already associated (if not yet listed)
|
/* Add in list the actions already associated (if not yet listed)
|
||||||
*/
|
*/
|
||||||
this.socialActionsSelected.forEach(action => {
|
this.socialActionsSelected.forEach((action) => {
|
||||||
this.$store.commit('addActionInList', action);
|
this.$store.commit("addActionInList", action);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
/* Filter issues
|
/* Filter issues
|
||||||
*/
|
*/
|
||||||
this.$store.commit('filterList', 'actions');
|
this.$store.commit("filterList", "actions");
|
||||||
|
|
||||||
this.issueIsLoading = false;
|
this.issueIsLoading = false;
|
||||||
this.actionAreLoaded = true;
|
this.actionAreLoaded = true;
|
||||||
this.updateActionsList();
|
this.updateActionsList();
|
||||||
resolve();
|
resolve();
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
/* When choosing an issue in multiselect, add it in checkboxes (as selected),
|
/* When choosing an issue in multiselect, add it in checkboxes (as selected),
|
||||||
remove it from multiselect, and add socialActions concerned
|
remove it from multiselect, and add socialActions concerned
|
||||||
*/
|
*/
|
||||||
addIssueInList(value) {
|
addIssueInList(value) {
|
||||||
//console.log('addIssueInList', value);
|
//console.log('addIssueInList', value);
|
||||||
this.$store.commit('addIssueInList', value);
|
this.$store.commit("addIssueInList", value);
|
||||||
this.$store.commit('removeIssueInOther', value);
|
this.$store.commit("removeIssueInOther", value);
|
||||||
this.$store.dispatch('addIssueSelected', value);
|
this.$store.dispatch("addIssueSelected", value);
|
||||||
this.updateActionsList();
|
this.updateActionsList();
|
||||||
},
|
},
|
||||||
/* Update value for selected issues checkboxes
|
/* Update value for selected issues checkboxes
|
||||||
*/
|
*/
|
||||||
updateIssuesSelected(issues) {
|
updateIssuesSelected(issues) {
|
||||||
//console.log('updateIssuesSelected', issues);
|
//console.log('updateIssuesSelected', issues);
|
||||||
this.$store.dispatch('updateIssuesSelected', issues);
|
this.$store.dispatch("updateIssuesSelected", issues);
|
||||||
this.updateActionsList();
|
this.updateActionsList();
|
||||||
},
|
},
|
||||||
/* Update value for selected actions checkboxes
|
/* Update value for selected actions checkboxes
|
||||||
*/
|
*/
|
||||||
updateActionsSelected(actions) {
|
updateActionsSelected(actions) {
|
||||||
//console.log('updateActionsSelected', actions);
|
//console.log('updateActionsSelected', actions);
|
||||||
this.$store.dispatch('updateActionsSelected', actions);
|
this.$store.dispatch("updateActionsSelected", actions);
|
||||||
},
|
},
|
||||||
/* Add socialActions concerned: after reset, loop on each issue selected
|
/* Add socialActions concerned: after reset, loop on each issue selected
|
||||||
to get social actions concerned
|
to get social actions concerned
|
||||||
*/
|
*/
|
||||||
updateActionsList() {
|
updateActionsList() {
|
||||||
this.resetActionsList();
|
this.resetActionsList();
|
||||||
this.socialIssuesSelected.forEach(item => {
|
this.socialIssuesSelected.forEach((item) => {
|
||||||
|
|
||||||
this.actionIsLoading = true;
|
this.actionIsLoading = true;
|
||||||
getSocialActionByIssue(item.id)
|
getSocialActionByIssue(item.id).then(
|
||||||
.then(actions => new Promise((resolve, reject) => {
|
(actions) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
actions.results.forEach(action => {
|
actions.results.forEach((action) => {
|
||||||
this.$store.commit('addActionInList', action);
|
this.$store.commit("addActionInList", action);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
this.$store.commit('filterList', 'actions');
|
this.$store.commit("filterList", "actions");
|
||||||
|
|
||||||
this.actionIsLoading = false;
|
this.actionIsLoading = false;
|
||||||
this.actionAreLoaded = true;
|
this.actionAreLoaded = true;
|
||||||
resolve();
|
resolve();
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}, this);
|
}, this);
|
||||||
},
|
},
|
||||||
/* Reset socialActions List: flush list and restore selected actions
|
/* Reset socialActions List: flush list and restore selected actions
|
||||||
*/
|
*/
|
||||||
resetActionsList() {
|
resetActionsList() {
|
||||||
this.$store.commit('resetActionsList');
|
this.$store.commit("resetActionsList");
|
||||||
this.actionAreLoaded = false;
|
this.actionAreLoaded = false;
|
||||||
this.socialActionsSelected.forEach(item => {
|
this.socialActionsSelected.forEach((item) => {
|
||||||
this.$store.commit('addActionInList', item);
|
this.$store.commit("addActionInList", item);
|
||||||
}, this);
|
}, this);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="inline-choice">
|
<span class="inline-choice">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
|
<input
|
||||||
<input class="form-check-input"
|
class="form-check-input"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
v-model="selected"
|
v-model="selected"
|
||||||
name="action"
|
name="action"
|
||||||
v-bind:id="action.id"
|
:id="action.id"
|
||||||
v-bind:value="action"
|
:value="action"
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" v-bind:for="action.id">
|
<label class="form-check-label" :for="action.id">
|
||||||
<span class="badge bg-light text-dark">{{ action.text }}</span>
|
<span class="badge bg-light text-dark">{{ action.text }}</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@ -20,25 +19,25 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "CheckSocialAction",
|
name: "CheckSocialAction",
|
||||||
props: [ 'action', 'selection' ],
|
props: ["action", "selection"],
|
||||||
emits: [ 'updateSelected' ],
|
emits: ["updateSelected"],
|
||||||
computed: {
|
computed: {
|
||||||
selected: {
|
selected: {
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$emit('updateSelected', value);
|
this.$emit("updateSelected", value);
|
||||||
},
|
},
|
||||||
get() {
|
get() {
|
||||||
return this.selection;
|
return this.selection;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import 'ChillMainAssets/module/bootstrap/shared';
|
@import "ChillMainAssets/module/bootstrap/shared";
|
||||||
@import 'ChillPersonAssets/chill/scss/mixins';
|
@import "ChillPersonAssets/chill/scss/mixins";
|
||||||
@import 'ChillMainAssets/chill/scss/chill_variables';
|
@import "ChillMainAssets/chill/scss/chill_variables";
|
||||||
span.badge {
|
span.badge {
|
||||||
@include badge_social($social-action-color);
|
@include badge_social($social-action-color);
|
||||||
font-size: 95%;
|
font-size: 95%;
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="inline-choice">
|
<span class="inline-choice">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
|
<input
|
||||||
<input class="form-check-input"
|
class="form-check-input"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
v-model="selected"
|
v-model="selected"
|
||||||
name="issue"
|
name="issue"
|
||||||
v-bind:id="issue.id"
|
:id="issue.id"
|
||||||
v-bind:value="issue"
|
:value="issue"
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" v-bind:for="issue.id">
|
<label class="form-check-label" :for="issue.id">
|
||||||
<span class="badge bg-chill-l-gray text-dark">{{ issue.text }}</span>
|
<span class="badge bg-chill-l-gray text-dark">{{
|
||||||
|
issue.text
|
||||||
|
}}</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@ -20,25 +21,25 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "CheckSocialIssue",
|
name: "CheckSocialIssue",
|
||||||
props: [ 'issue', 'selection' ],
|
props: ["issue", "selection"],
|
||||||
emits: [ 'updateSelected' ],
|
emits: ["updateSelected"],
|
||||||
computed: {
|
computed: {
|
||||||
selected: {
|
selected: {
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$emit('updateSelected', value);
|
this.$emit("updateSelected", value);
|
||||||
},
|
},
|
||||||
get() {
|
get() {
|
||||||
return this.selection;
|
return this.selection;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import 'ChillMainAssets/module/bootstrap/shared';
|
@import "ChillMainAssets/module/bootstrap/shared";
|
||||||
@import 'ChillPersonAssets/chill/scss/mixins';
|
@import "ChillPersonAssets/chill/scss/mixins";
|
||||||
@import 'ChillMainAssets/chill/scss/chill_variables';
|
@import "ChillMainAssets/chill/scss/chill_variables";
|
||||||
span.badge {
|
span.badge {
|
||||||
@include badge_social($social-issue-color);
|
@include badge_social($social-issue-color);
|
||||||
font-size: 95%;
|
font-size: 95%;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
|
import { personMessages } from "ChillPersonAssets/vuejs/_js/i18n";
|
||||||
import { multiSelectMessages } from 'ChillMainAssets/vuejs/_js/i18n'
|
import { multiSelectMessages } from "ChillMainAssets/vuejs/_js/i18n";
|
||||||
|
|
||||||
const activityMessages = {
|
const activityMessages = {
|
||||||
fr: {
|
fr: {
|
||||||
@ -9,7 +9,8 @@ const activityMessages = {
|
|||||||
social_issues: "Problématiques sociales",
|
social_issues: "Problématiques sociales",
|
||||||
choose_other_social_issue: "Ajouter une autre problématique sociale...",
|
choose_other_social_issue: "Ajouter une autre problématique sociale...",
|
||||||
social_actions: "Actions d'accompagnement",
|
social_actions: "Actions d'accompagnement",
|
||||||
select_first_a_social_issue: "Sélectionnez d'abord une problématique sociale",
|
select_first_a_social_issue:
|
||||||
|
"Sélectionnez d'abord une problématique sociale",
|
||||||
social_action_list_empty: "Aucune action sociale disponible",
|
social_action_list_empty: "Aucune action sociale disponible",
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -32,14 +33,12 @@ const activityMessages = {
|
|||||||
phonenumber2: "Autre téléphone",
|
phonenumber2: "Autre téléphone",
|
||||||
email: "Adresse courriel",
|
email: "Adresse courriel",
|
||||||
},
|
},
|
||||||
create_address: 'Créer une adresse',
|
create_address: "Créer une adresse",
|
||||||
edit_address: "Modifier l'adresse"
|
edit_address: "Modifier l'adresse",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
Object.assign(activityMessages.fr, personMessages.fr, multiSelectMessages.fr);
|
Object.assign(activityMessages.fr, personMessages.fr, multiSelectMessages.fr);
|
||||||
|
|
||||||
export {
|
export { activityMessages };
|
||||||
activityMessages
|
|
||||||
};
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import { createApp } from 'vue';
|
import { createApp } from "vue";
|
||||||
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
|
import { _createI18n } from "ChillMainAssets/vuejs/_js/i18n";
|
||||||
import { activityMessages } from './i18n'
|
import { activityMessages } from "./i18n";
|
||||||
import store from './store'
|
import store from "./store";
|
||||||
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
import PickTemplate from "ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue";
|
||||||
import {fetchTemplates} from 'ChillDocGeneratorAssets/api/pickTemplate.js';
|
import { fetchTemplates } from "ChillDocGeneratorAssets/api/pickTemplate.js";
|
||||||
|
|
||||||
import App from './App.vue';
|
import App from "./App.vue";
|
||||||
|
|
||||||
const i18n = _createI18n(activityMessages);
|
const i18n = _createI18n(activityMessages);
|
||||||
|
|
||||||
// app for activity
|
// app for activity
|
||||||
|
|
||||||
const hasSocialIssues = document.querySelector('#social-issues-acc') !== null;
|
const hasSocialIssues = document.querySelector("#social-issues-acc") !== null;
|
||||||
const hasLocation = document.querySelector('#location') !== null;
|
const hasLocation = document.querySelector("#location") !== null;
|
||||||
const hasPerson = document.querySelector('#add-persons') !== null;
|
const hasPerson = document.querySelector("#add-persons") !== null;
|
||||||
|
|
||||||
const app = createApp({
|
const app = createApp({
|
||||||
template: `<app
|
template: `<app
|
||||||
@ -27,20 +27,19 @@ const app = createApp({
|
|||||||
hasLocation,
|
hasLocation,
|
||||||
hasPerson,
|
hasPerson,
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.use(store)
|
.use(store)
|
||||||
.use(i18n)
|
.use(i18n)
|
||||||
.component('app', App)
|
.component("app", App)
|
||||||
.mount('#activity');
|
.mount("#activity");
|
||||||
|
|
||||||
|
|
||||||
// app for picking template
|
// app for picking template
|
||||||
|
|
||||||
const i18nGendoc = _createI18n({});
|
const i18nGendoc = _createI18n({});
|
||||||
|
|
||||||
document.querySelectorAll('div[data-docgen-template-picker]').forEach(el => {
|
document.querySelectorAll("div[data-docgen-template-picker]").forEach((el) => {
|
||||||
fetchTemplates(el.dataset.entityClass).then(templates => {
|
fetchTemplates(el.dataset.entityClass).then((templates) => {
|
||||||
const picker = {
|
const picker = {
|
||||||
template:
|
template:
|
||||||
'<pick-template :templates="this.templates" :preventDefaultMoveToGenerate="true" ' +
|
'<pick-template :templates="this.templates" :preventDefaultMoveToGenerate="true" ' +
|
||||||
@ -52,35 +51,36 @@ document.querySelectorAll('div[data-docgen-template-picker]').forEach(el => {
|
|||||||
return {
|
return {
|
||||||
templates: templates,
|
templates: templates,
|
||||||
entityId: el.dataset.entityId,
|
entityId: el.dataset.entityId,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
generateDoc({ event, link, template }) {
|
generateDoc({ event, link, template }) {
|
||||||
console.log('generateDoc');
|
console.log("generateDoc");
|
||||||
console.log('link', link);
|
console.log("link", link);
|
||||||
console.log('template', template);
|
console.log("template", template);
|
||||||
|
|
||||||
let hiddenInput = document.querySelector("input[data-template-id]");
|
let hiddenInput = document.querySelector("input[data-template-id]");
|
||||||
|
|
||||||
if (hiddenInput === null) {
|
if (hiddenInput === null) {
|
||||||
console.error('hidden input not found');
|
console.error("hidden input not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hiddenInput.value = template;
|
hiddenInput.value = template;
|
||||||
|
|
||||||
let form = document.querySelector('form[name="chill_activitybundle_activity"');
|
let form = document.querySelector(
|
||||||
|
'form[name="chill_activitybundle_activity"',
|
||||||
|
);
|
||||||
|
|
||||||
if (form === null) {
|
if (form === null) {
|
||||||
console.error('form not found');
|
console.error("form not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
createApp(picker).use(i18nGendoc).mount(el);
|
createApp(picker).use(i18nGendoc).mount(el);
|
||||||
})
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
import 'es6-promise/auto';
|
import "es6-promise/auto";
|
||||||
import { createStore } from 'vuex';
|
import { createStore } from "vuex";
|
||||||
import { postLocation } from './api';
|
import { postLocation } from "./api";
|
||||||
import prepareLocations from './store.locations.js';
|
import prepareLocations from "./store.locations.js";
|
||||||
|
|
||||||
const debug = process.env.NODE_ENV !== 'production';
|
const debug = process.env.NODE_ENV !== "production";
|
||||||
//console.log('window.activity', window.activity);
|
//console.log('window.activity', window.activity);
|
||||||
|
|
||||||
const addIdToValue = (string, id) => {
|
const addIdToValue = (string, id) => {
|
||||||
let array = string ? string.split(',') : [];
|
let array = string ? string.split(",") : [];
|
||||||
array.push(id.toString());
|
array.push(id.toString());
|
||||||
let str = array.join();
|
let str = array.join();
|
||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeIdFromValue = (string, id) => {
|
const removeIdFromValue = (string, id) => {
|
||||||
let array = string.split(',');
|
let array = string.split(",");
|
||||||
array = array.filter(el => el !== id.toString());
|
array = array.filter((el) => el !== id.toString());
|
||||||
let str = array.join();
|
let str = array.join();
|
||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
@ -30,7 +30,10 @@ const store = createStore({
|
|||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
suggestedEntities(state) {
|
suggestedEntities(state) {
|
||||||
if (typeof state.activity.accompanyingPeriod === "undefined" || state.activity.accompanyingPeriod === null) {
|
if (
|
||||||
|
typeof state.activity.accompanyingPeriod === "undefined" ||
|
||||||
|
state.activity.accompanyingPeriod === null
|
||||||
|
) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const allEntities = [
|
const allEntities = [
|
||||||
@ -44,7 +47,7 @@ const store = createStore({
|
|||||||
];
|
];
|
||||||
return Array.from(
|
return Array.from(
|
||||||
uniqueIds,
|
uniqueIds,
|
||||||
(id) => allEntities.filter((r) => `${r.type}-${r.id}` === id)[0]
|
(id) => allEntities.filter((r) => `${r.type}-${r.id}` === id)[0],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
suggestedPersons(state) {
|
suggestedPersons(state) {
|
||||||
@ -62,7 +65,7 @@ const store = createStore({
|
|||||||
}
|
}
|
||||||
const existingPersonIds = state.activity.persons.map((p) => p.id);
|
const existingPersonIds = state.activity.persons.map((p) => p.id);
|
||||||
const existingThirdPartyIds = state.activity.thirdParties.map(
|
const existingThirdPartyIds = state.activity.thirdParties.map(
|
||||||
(p) => p.id
|
(p) => p.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
return [state.activity.accompanyingPeriod.requestor].filter(
|
return [state.activity.accompanyingPeriod.requestor].filter(
|
||||||
@ -72,7 +75,7 @@ const store = createStore({
|
|||||||
state.activity.activityType.personsVisible !== 0) ||
|
state.activity.activityType.personsVisible !== 0) ||
|
||||||
(r.type === "thirdparty" &&
|
(r.type === "thirdparty" &&
|
||||||
!existingThirdPartyIds.includes(r.id) &&
|
!existingThirdPartyIds.includes(r.id) &&
|
||||||
state.activity.activityType.thirdPartiesVisible !== 0)
|
state.activity.activityType.thirdPartiesVisible !== 0),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
suggestedUser(state) {
|
suggestedUser(state) {
|
||||||
@ -80,14 +83,14 @@ const store = createStore({
|
|||||||
return state.activity.activityType.usersVisible === 0
|
return state.activity.activityType.usersVisible === 0
|
||||||
? []
|
? []
|
||||||
: [state.activity.accompanyingPeriod.user].filter(
|
: [state.activity.accompanyingPeriod.user].filter(
|
||||||
(u) => u !== null && !existingUserIds.includes(u.id)
|
(u) => u !== null && !existingUserIds.includes(u.id),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
suggestedResources(state) {
|
suggestedResources(state) {
|
||||||
const resources = state.activity.accompanyingPeriod.resources;
|
const resources = state.activity.accompanyingPeriod.resources;
|
||||||
const existingPersonIds = state.activity.persons.map((p) => p.id);
|
const existingPersonIds = state.activity.persons.map((p) => p.id);
|
||||||
const existingThirdPartyIds = state.activity.thirdParties.map(
|
const existingThirdPartyIds = state.activity.thirdParties.map(
|
||||||
(p) => p.id
|
(p) => p.id,
|
||||||
);
|
);
|
||||||
return state.activity.accompanyingPeriod.resources
|
return state.activity.accompanyingPeriod.resources
|
||||||
.map((r) => r.resource)
|
.map((r) => r.resource)
|
||||||
@ -98,11 +101,13 @@ const store = createStore({
|
|||||||
state.activity.activityType.personsVisible !== 0) ||
|
state.activity.activityType.personsVisible !== 0) ||
|
||||||
(r.type === "thirdparty" &&
|
(r.type === "thirdparty" &&
|
||||||
!existingThirdPartyIds.includes(r.id) &&
|
!existingThirdPartyIds.includes(r.id) &&
|
||||||
state.activity.activityType.thirdPartiesVisible !== 0)
|
state.activity.activityType.thirdPartiesVisible !== 0),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
socialActionsListSorted(state) {
|
socialActionsListSorted(state) {
|
||||||
return [ ...state.socialActionsList].sort((a, b) => a.ordering - b.ordering);
|
return [...state.socialActionsList].sort(
|
||||||
|
(a, b) => a.ordering - b.ordering,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
@ -126,7 +131,7 @@ const store = createStore({
|
|||||||
removeIssueInOther(state, issue) {
|
removeIssueInOther(state, issue) {
|
||||||
//console.log('remove issue other', issue.id);
|
//console.log('remove issue other', issue.id);
|
||||||
state.socialIssuesOther = state.socialIssuesOther.filter(
|
state.socialIssuesOther = state.socialIssuesOther.filter(
|
||||||
(i) => i.id !== issue.id
|
(i) => i.id !== issue.id,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
resetActionsList(state) {
|
resetActionsList(state) {
|
||||||
@ -145,18 +150,15 @@ const store = createStore({
|
|||||||
// remove duplicates entries
|
// remove duplicates entries
|
||||||
list = list.filter(
|
list = list.filter(
|
||||||
(value, index) =>
|
(value, index) =>
|
||||||
list.findIndex((array) => array.id === value.id) ===
|
list.findIndex((array) => array.id === value.id) === index,
|
||||||
index
|
|
||||||
);
|
);
|
||||||
// alpha sort
|
// alpha sort
|
||||||
list.sort((a, b) =>
|
list.sort((a, b) => (a.text > b.text ? 1 : b.text > a.text ? -1 : 0));
|
||||||
a.text > b.text ? 1 : b.text > a.text ? -1 : 0
|
|
||||||
);
|
|
||||||
return list;
|
return list;
|
||||||
};
|
};
|
||||||
if (list === "issues") {
|
if (list === "issues") {
|
||||||
state.activity.accompanyingPeriod.socialIssues = filterList(
|
state.activity.accompanyingPeriod.socialIssues = filterList(
|
||||||
state.activity.accompanyingPeriod.socialIssues
|
state.activity.accompanyingPeriod.socialIssues,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (list === "actions") {
|
if (list === "actions") {
|
||||||
@ -184,18 +186,17 @@ const store = createStore({
|
|||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "person":
|
case "person":
|
||||||
state.activity.persons = state.activity.persons.filter(
|
state.activity.persons = state.activity.persons.filter(
|
||||||
(person) => person !== payload
|
(person) => person !== payload,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "thirdparty":
|
case "thirdparty":
|
||||||
state.activity.thirdParties =
|
state.activity.thirdParties = state.activity.thirdParties.filter(
|
||||||
state.activity.thirdParties.filter(
|
(thirdparty) => thirdparty !== payload,
|
||||||
(thirdparty) => thirdparty !== payload
|
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "user":
|
case "user":
|
||||||
state.activity.users = state.activity.users.filter(
|
state.activity.users = state.activity.users.filter(
|
||||||
(user) => user !== payload
|
(user) => user !== payload,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -206,39 +207,33 @@ const store = createStore({
|
|||||||
},
|
},
|
||||||
addAvailableLocationGroup(state, group) {
|
addAvailableLocationGroup(state, group) {
|
||||||
state.availableLocations.push(group);
|
state.availableLocations.push(group);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
addIssueSelected({ commit }, issue) {
|
addIssueSelected({ commit }, issue) {
|
||||||
let aSocialIssues = document.getElementById(
|
let aSocialIssues = document.getElementById(
|
||||||
"chill_activitybundle_activity_socialIssues"
|
"chill_activitybundle_activity_socialIssues",
|
||||||
);
|
);
|
||||||
aSocialIssues.value = addIdToValue(aSocialIssues.value, issue.id);
|
aSocialIssues.value = addIdToValue(aSocialIssues.value, issue.id);
|
||||||
commit("addIssueSelected", issue);
|
commit("addIssueSelected", issue);
|
||||||
},
|
},
|
||||||
updateIssuesSelected({ commit }, payload) {
|
updateIssuesSelected({ commit }, payload) {
|
||||||
let aSocialIssues = document.getElementById(
|
let aSocialIssues = document.getElementById(
|
||||||
"chill_activitybundle_activity_socialIssues"
|
"chill_activitybundle_activity_socialIssues",
|
||||||
);
|
);
|
||||||
aSocialIssues.value = "";
|
aSocialIssues.value = "";
|
||||||
payload.forEach((item) => {
|
payload.forEach((item) => {
|
||||||
aSocialIssues.value = addIdToValue(
|
aSocialIssues.value = addIdToValue(aSocialIssues.value, item.id);
|
||||||
aSocialIssues.value,
|
|
||||||
item.id
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
commit("updateIssuesSelected", payload);
|
commit("updateIssuesSelected", payload);
|
||||||
},
|
},
|
||||||
updateActionsSelected({ commit }, payload) {
|
updateActionsSelected({ commit }, payload) {
|
||||||
let aSocialActions = document.getElementById(
|
let aSocialActions = document.getElementById(
|
||||||
"chill_activitybundle_activity_socialActions"
|
"chill_activitybundle_activity_socialActions",
|
||||||
);
|
);
|
||||||
aSocialActions.value = "";
|
aSocialActions.value = "";
|
||||||
payload.forEach((item) => {
|
payload.forEach((item) => {
|
||||||
aSocialActions.value = addIdToValue(
|
aSocialActions.value = addIdToValue(aSocialActions.value, item.id);
|
||||||
aSocialActions.value,
|
|
||||||
item.id
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
commit("updateActionsSelected", payload);
|
commit("updateActionsSelected", payload);
|
||||||
},
|
},
|
||||||
@ -250,30 +245,24 @@ const store = createStore({
|
|||||||
switch (payload.result.type) {
|
switch (payload.result.type) {
|
||||||
case "person":
|
case "person":
|
||||||
let aPersons = document.getElementById(
|
let aPersons = document.getElementById(
|
||||||
"chill_activitybundle_activity_persons"
|
"chill_activitybundle_activity_persons",
|
||||||
);
|
|
||||||
aPersons.value = addIdToValue(
|
|
||||||
aPersons.value,
|
|
||||||
payload.result.id
|
|
||||||
);
|
);
|
||||||
|
aPersons.value = addIdToValue(aPersons.value, payload.result.id);
|
||||||
break;
|
break;
|
||||||
case "thirdparty":
|
case "thirdparty":
|
||||||
let aThirdParties = document.getElementById(
|
let aThirdParties = document.getElementById(
|
||||||
"chill_activitybundle_activity_thirdParties"
|
"chill_activitybundle_activity_thirdParties",
|
||||||
);
|
);
|
||||||
aThirdParties.value = addIdToValue(
|
aThirdParties.value = addIdToValue(
|
||||||
aThirdParties.value,
|
aThirdParties.value,
|
||||||
payload.result.id
|
payload.result.id,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "user":
|
case "user":
|
||||||
let aUsers = document.getElementById(
|
let aUsers = document.getElementById(
|
||||||
"chill_activitybundle_activity_users"
|
"chill_activitybundle_activity_users",
|
||||||
);
|
|
||||||
aUsers.value = addIdToValue(
|
|
||||||
aUsers.value,
|
|
||||||
payload.result.id
|
|
||||||
);
|
);
|
||||||
|
aUsers.value = addIdToValue(aUsers.value, payload.result.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
commit("addPersonsInvolved", payload);
|
commit("addPersonsInvolved", payload);
|
||||||
@ -283,25 +272,22 @@ const store = createStore({
|
|||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "person":
|
case "person":
|
||||||
let aPersons = document.getElementById(
|
let aPersons = document.getElementById(
|
||||||
"chill_activitybundle_activity_persons"
|
"chill_activitybundle_activity_persons",
|
||||||
);
|
|
||||||
aPersons.value = removeIdFromValue(
|
|
||||||
aPersons.value,
|
|
||||||
payload.id
|
|
||||||
);
|
);
|
||||||
|
aPersons.value = removeIdFromValue(aPersons.value, payload.id);
|
||||||
break;
|
break;
|
||||||
case "thirdparty":
|
case "thirdparty":
|
||||||
let aThirdParties = document.getElementById(
|
let aThirdParties = document.getElementById(
|
||||||
"chill_activitybundle_activity_thirdParties"
|
"chill_activitybundle_activity_thirdParties",
|
||||||
);
|
);
|
||||||
aThirdParties.value = removeIdFromValue(
|
aThirdParties.value = removeIdFromValue(
|
||||||
aThirdParties.value,
|
aThirdParties.value,
|
||||||
payload.id
|
payload.id,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "user":
|
case "user":
|
||||||
let aUsers = document.getElementById(
|
let aUsers = document.getElementById(
|
||||||
"chill_activitybundle_activity_users"
|
"chill_activitybundle_activity_users",
|
||||||
);
|
);
|
||||||
aUsers.value = removeIdFromValue(aUsers.value, payload.id);
|
aUsers.value = removeIdFromValue(aUsers.value, payload.id);
|
||||||
break;
|
break;
|
||||||
@ -311,32 +297,30 @@ const store = createStore({
|
|||||||
updateLocation({ commit }, value) {
|
updateLocation({ commit }, value) {
|
||||||
console.log("### action: updateLocation", value);
|
console.log("### action: updateLocation", value);
|
||||||
let hiddenLocation = document.getElementById(
|
let hiddenLocation = document.getElementById(
|
||||||
"chill_activitybundle_activity_location"
|
"chill_activitybundle_activity_location",
|
||||||
);
|
);
|
||||||
if (value.onthefly) {
|
if (value.onthefly) {
|
||||||
const body = {
|
const body = {
|
||||||
"type": "location",
|
type: "location",
|
||||||
"name": value.name === '__AccompanyingCourseLocation__' ? null : value.name,
|
name:
|
||||||
"locationType": {
|
value.name === "__AccompanyingCourseLocation__" ? null : value.name,
|
||||||
"id": value.locationType.id,
|
locationType: {
|
||||||
"type": "location-type"
|
id: value.locationType.id,
|
||||||
}
|
type: "location-type",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
if (value.address.id) {
|
if (value.address.id) {
|
||||||
Object.assign(body, {
|
Object.assign(body, {
|
||||||
"address": {
|
address: {
|
||||||
"id": value.address.id
|
id: value.address.id,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
postLocation(body)
|
postLocation(body)
|
||||||
.then(
|
.then((location) => (hiddenLocation.value = location.id))
|
||||||
location => hiddenLocation.value = location.id
|
.catch((err) => {
|
||||||
).catch(
|
|
||||||
err => {
|
|
||||||
console.log(err.message);
|
console.log(err.message);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
hiddenLocation.value = value.id;
|
hiddenLocation.value = value.id;
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,41 @@
|
|||||||
import {getLocations, getLocationTypeByDefaultFor, getUserCurrentLocation} from "./api";
|
import {
|
||||||
|
getLocations,
|
||||||
|
getLocationTypeByDefaultFor,
|
||||||
|
getUserCurrentLocation,
|
||||||
|
} from "./api";
|
||||||
|
|
||||||
const makeConcernedPersonsLocation = (locationType, store) => {
|
const makeConcernedPersonsLocation = (locationType, store) => {
|
||||||
let locations = [];
|
let locations = [];
|
||||||
store.getters.suggestedEntities.forEach(
|
store.getters.suggestedEntities.forEach((e) => {
|
||||||
(e) => {
|
if (e.type === "person" && e.current_household_address !== null) {
|
||||||
if (e.type === 'person' && e.current_household_address !== null){
|
|
||||||
locations.push({
|
locations.push({
|
||||||
type: 'location',
|
type: "location",
|
||||||
id: -store.getters.suggestedEntities.indexOf(e) * 10,
|
id: -store.getters.suggestedEntities.indexOf(e) * 10,
|
||||||
onthefly: true,
|
onthefly: true,
|
||||||
name: e.text,
|
name: e.text,
|
||||||
address: {
|
address: {
|
||||||
id: e.current_household_address.address_id,
|
id: e.current_household_address.address_id,
|
||||||
},
|
},
|
||||||
locationType: locationType
|
locationType: locationType,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
)
|
|
||||||
return locations;
|
return locations;
|
||||||
};
|
};
|
||||||
const makeConcernedThirdPartiesLocation = (locationType, store) => {
|
const makeConcernedThirdPartiesLocation = (locationType, store) => {
|
||||||
let locations = [];
|
let locations = [];
|
||||||
store.getters.suggestedEntities.forEach(
|
store.getters.suggestedEntities.forEach((e) => {
|
||||||
(e) => {
|
if (e.type === "thirdparty" && e.address !== null) {
|
||||||
if (e.type === 'thirdparty' && e.address !== null){
|
|
||||||
locations.push({
|
locations.push({
|
||||||
type: 'location',
|
type: "location",
|
||||||
id: -store.getters.suggestedEntities.indexOf(e) * 10,
|
id: -store.getters.suggestedEntities.indexOf(e) * 10,
|
||||||
onthefly: true,
|
onthefly: true,
|
||||||
name: e.text,
|
name: e.text,
|
||||||
address: { id: e.address.address_id },
|
address: { id: e.address.address_id },
|
||||||
locationType: locationType
|
locationType: locationType,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
)
|
|
||||||
return locations;
|
return locations;
|
||||||
};
|
};
|
||||||
const makeAccompanyingPeriodLocation = (locationType, store) => {
|
const makeAccompanyingPeriodLocation = (locationType, store) => {
|
||||||
@ -44,78 +44,86 @@ const makeAccompanyingPeriodLocation = (locationType, store) => {
|
|||||||
}
|
}
|
||||||
const accPeriodLocation = store.state.activity.accompanyingPeriod.location;
|
const accPeriodLocation = store.state.activity.accompanyingPeriod.location;
|
||||||
return {
|
return {
|
||||||
type: 'location',
|
type: "location",
|
||||||
id: -1,
|
id: -1,
|
||||||
onthefly: true,
|
onthefly: true,
|
||||||
name: '__AccompanyingCourseLocation__',
|
name: "__AccompanyingCourseLocation__",
|
||||||
address: {
|
address: {
|
||||||
id: accPeriodLocation.address_id,
|
id: accPeriodLocation.address_id,
|
||||||
text: `${accPeriodLocation.text} - ${accPeriodLocation.postcode.code} ${accPeriodLocation.postcode.name}`
|
text: `${accPeriodLocation.text} - ${accPeriodLocation.postcode.code} ${accPeriodLocation.postcode.name}`,
|
||||||
},
|
},
|
||||||
locationType: locationType
|
locationType: locationType,
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function prepareLocations(store) {
|
export default function prepareLocations(store) {
|
||||||
|
|
||||||
// find the locations
|
// find the locations
|
||||||
let allLocations = getLocations().then(
|
let allLocations = getLocations().then((results) => {
|
||||||
(results) => {
|
store.commit("addAvailableLocationGroup", {
|
||||||
store.commit('addAvailableLocationGroup', {
|
locationGroup: "Autres localisations",
|
||||||
locationGroup: 'Autres localisations',
|
locations: results,
|
||||||
locations: results
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
let currentLocation = getUserCurrentLocation().then(
|
let currentLocation = getUserCurrentLocation().then((userCurrentLocation) => {
|
||||||
userCurrentLocation => {
|
|
||||||
if (null !== userCurrentLocation) {
|
if (null !== userCurrentLocation) {
|
||||||
store.commit('addAvailableLocationGroup', {
|
store.commit("addAvailableLocationGroup", {
|
||||||
locationGroup: 'Ma localisation',
|
locationGroup: "Ma localisation",
|
||||||
locations: [userCurrentLocation]
|
locations: [userCurrentLocation],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
let partiesLocations = [], partyPromise;
|
let partiesLocations = [],
|
||||||
['person', 'thirdparty'].forEach(kind => {
|
partyPromise;
|
||||||
|
["person", "thirdparty"].forEach((kind) => {
|
||||||
partyPromise = getLocationTypeByDefaultFor(kind).then(
|
partyPromise = getLocationTypeByDefaultFor(kind).then(
|
||||||
(kindLocationType) => {
|
(kindLocationType) => {
|
||||||
if (kindLocationType) {
|
if (kindLocationType) {
|
||||||
let concernedKindLocations;
|
let concernedKindLocations;
|
||||||
if (kind === 'person') {
|
if (kind === "person") {
|
||||||
concernedKindLocations = makeConcernedPersonsLocation(kindLocationType, store);
|
concernedKindLocations = makeConcernedPersonsLocation(
|
||||||
|
kindLocationType,
|
||||||
|
store,
|
||||||
|
);
|
||||||
// add location for the parcours into suggestions
|
// add location for the parcours into suggestions
|
||||||
const personLocation = makeAccompanyingPeriodLocation(kindLocationType, store);
|
const personLocation = makeAccompanyingPeriodLocation(
|
||||||
store.commit('addAvailableLocationGroup', {
|
kindLocationType,
|
||||||
locationGroup: 'Localisation du parcours',
|
store,
|
||||||
locations: [personLocation]
|
);
|
||||||
|
store.commit("addAvailableLocationGroup", {
|
||||||
|
locationGroup: "Localisation du parcours",
|
||||||
|
locations: [personLocation],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
concernedKindLocations = makeConcernedThirdPartiesLocation(kindLocationType, store);
|
concernedKindLocations = makeConcernedThirdPartiesLocation(
|
||||||
|
kindLocationType,
|
||||||
|
store,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
store.commit('addAvailableLocationGroup', {
|
store.commit("addAvailableLocationGroup", {
|
||||||
locationGroup: kind === 'person' ? 'Usagers concernés' : 'Tiers concernés',
|
locationGroup:
|
||||||
|
kind === "person" ? "Usagers concernés" : "Tiers concernés",
|
||||||
locations: concernedKindLocations,
|
locations: concernedKindLocations,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
partiesLocations.push(partyPromise);
|
partiesLocations.push(partyPromise);
|
||||||
});
|
});
|
||||||
|
|
||||||
// when all location are loaded
|
// when all location are loaded
|
||||||
Promise.all([allLocations, currentLocation, ...partiesLocations]).then(() => {
|
Promise.all([allLocations, currentLocation, ...partiesLocations]).then(() => {
|
||||||
console.log('current location in activity', store.state.activity.location);
|
console.log("current location in activity", store.state.activity.location);
|
||||||
console.log('default loation id', window.default_location_id);
|
console.log("default loation id", window.default_location_id);
|
||||||
if (window.default_location_id) {
|
if (window.default_location_id) {
|
||||||
for (let group of store.state.availableLocations) {
|
for (let group of store.state.availableLocations) {
|
||||||
let location = group.locations.find((l) => l.id === window.default_location_id);
|
let location = group.locations.find(
|
||||||
|
(l) => l.id === window.default_location_id,
|
||||||
|
);
|
||||||
if (location !== undefined && store.state.activity.location === null) {
|
if (location !== undefined && store.state.activity.location === null) {
|
||||||
store.dispatch('updateLocation', location);
|
store.dispatch("updateLocation", location);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
// this file loads all assets from the Chill person bundle
|
// this file loads all assets from the Chill person bundle
|
||||||
module.exports = function(encore, entries)
|
module.exports = function (encore, entries) {
|
||||||
{
|
entries.push(__dirname + "/Resources/public/chill/index.js");
|
||||||
entries.push(__dirname + '/Resources/public/chill/index.js');
|
|
||||||
|
|
||||||
encore.addAliases({
|
encore.addAliases({
|
||||||
ChillActivityAssets: __dirname + '/Resources/public'
|
ChillActivityAssets: __dirname + "/Resources/public",
|
||||||
});
|
});
|
||||||
|
|
||||||
encore.addEntry('page_edit_activity', __dirname + '/Resources/public/page/edit_activity/index.scss');
|
encore.addEntry(
|
||||||
|
"page_edit_activity",
|
||||||
|
__dirname + "/Resources/public/page/edit_activity/index.scss",
|
||||||
|
);
|
||||||
|
|
||||||
encore.addEntry('vue_activity', __dirname + '/Resources/public/vuejs/Activity/index.js');
|
encore.addEntry(
|
||||||
|
"vue_activity",
|
||||||
|
__dirname + "/Resources/public/vuejs/Activity/index.js",
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -1 +1 @@
|
|||||||
require('./chillbudget.scss');
|
require("./chillbudget.scss");
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
// this file loads all assets from the Chill budget bundle
|
// this file loads all assets from the Chill budget bundle
|
||||||
module.exports = function(encore, entries)
|
module.exports = function (encore, entries) {
|
||||||
{
|
|
||||||
encore.addAliases({
|
encore.addAliases({
|
||||||
ChillBudgetAssets: __dirname + '/Resources/public'
|
ChillBudgetAssets: __dirname + "/Resources/public",
|
||||||
});
|
});
|
||||||
|
|
||||||
encore.addEntry('page_budget', __dirname + '/Resources/public/page/index.js');
|
encore.addEntry("page_budget", __dirname + "/Resources/public/page/index.js");
|
||||||
};
|
};
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
import './scss/badge.scss';
|
import "./scss/badge.scss";
|
||||||
import './scss/calendar-list.scss';
|
import "./scss/calendar-list.scss";
|
||||||
|
@ -1 +1 @@
|
|||||||
require('./scss/calendar.scss');
|
require("./scss/calendar.scss");
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
|
import { createApp } from "vue";
|
||||||
import { createApp } from 'vue';
|
import Answer from "ChillCalendarAssets/vuejs/Invite/Answer";
|
||||||
import Answer from 'ChillCalendarAssets/vuejs/Invite/Answer';
|
import { _createI18n } from "ChillMainAssets/vuejs/_js/i18n";
|
||||||
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n';
|
|
||||||
|
|
||||||
const i18n = _createI18n({});
|
const i18n = _createI18n({});
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function (e) {
|
document.addEventListener("DOMContentLoaded", function (e) {
|
||||||
console.log('dom loaded answer');
|
console.log("dom loaded answer");
|
||||||
document.querySelectorAll('div[invite-answer]').forEach(function (el) {
|
document.querySelectorAll("div[invite-answer]").forEach(function (el) {
|
||||||
console.log('element found', el);
|
console.log("element found", el);
|
||||||
|
|
||||||
const app = createApp({
|
const app = createApp({
|
||||||
components: {
|
components: {
|
||||||
@ -18,14 +17,15 @@ document.addEventListener('DOMContentLoaded', function (e) {
|
|||||||
return {
|
return {
|
||||||
status: el.dataset.status,
|
status: el.dataset.status,
|
||||||
calendarId: Number.parseInt(el.dataset.calendarId),
|
calendarId: Number.parseInt(el.dataset.calendarId),
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
template: '<answer :calendarId="calendarId" :status="status" @statusChanged="onStatusChanged"></answer>',
|
template:
|
||||||
|
'<answer :calendarId="calendarId" :status="status" @statusChanged="onStatusChanged"></answer>',
|
||||||
methods: {
|
methods: {
|
||||||
onStatusChanged: function (newStatus) {
|
onStatusChanged: function (newStatus) {
|
||||||
this.$data.status = newStatus;
|
this.$data.status = newStatus;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(i18n).mount(el);
|
app.use(i18n).mount(el);
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
import {EventInput} from '@fullcalendar/core';
|
import { EventInput } from "@fullcalendar/core";
|
||||||
import {DateTime, Location, User, UserAssociatedInterface} from '../../../ChillMainBundle/Resources/public/types' ;
|
import {
|
||||||
|
DateTime,
|
||||||
|
Location,
|
||||||
|
User,
|
||||||
|
UserAssociatedInterface,
|
||||||
|
} from "../../../ChillMainBundle/Resources/public/types";
|
||||||
import { Person } from "../../../ChillPersonBundle/Resources/public/types";
|
import { Person } from "../../../ChillPersonBundle/Resources/public/types";
|
||||||
|
|
||||||
export interface CalendarRange {
|
export interface CalendarRange {
|
||||||
@ -22,8 +27,8 @@ export interface CalendarRangeCreate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CalendarRangeEdit {
|
export interface CalendarRangeEdit {
|
||||||
startDate?: DateTime,
|
startDate?: DateTime;
|
||||||
endDate?: DateTime
|
endDate?: DateTime;
|
||||||
location?: Location;
|
location?: Location;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,19 +54,23 @@ export interface CalendarRemote {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type EventInputCalendarRange = EventInput & {
|
export type EventInputCalendarRange = EventInput & {
|
||||||
id: string,
|
id: string;
|
||||||
userId: number,
|
userId: number;
|
||||||
userLabel: string,
|
userLabel: string;
|
||||||
calendarRangeId: number,
|
calendarRangeId: number;
|
||||||
locationId: number,
|
locationId: number;
|
||||||
locationName: string,
|
locationName: string;
|
||||||
start: string,
|
start: string;
|
||||||
end: string,
|
end: string;
|
||||||
is: "range"
|
is: "range";
|
||||||
};
|
};
|
||||||
|
|
||||||
export function isEventInputCalendarRange(toBeDetermined: EventInputCalendarRange | EventInput): toBeDetermined is EventInputCalendarRange {
|
export function isEventInputCalendarRange(
|
||||||
return typeof toBeDetermined.is === "string" && toBeDetermined.is === "range";
|
toBeDetermined: EventInputCalendarRange | EventInput,
|
||||||
|
): toBeDetermined is EventInputCalendarRange {
|
||||||
|
return (
|
||||||
|
typeof toBeDetermined.is === "string" && toBeDetermined.is === "range"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
@ -1,63 +1,82 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<teleport to="#mainUser">
|
<teleport to="#mainUser">
|
||||||
|
|
||||||
<h2 class="chill-red">Utilisateur principal</h2>
|
<h2 class="chill-red">Utilisateur principal</h2>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="null !== this.$store.getters.getMainUser">
|
<div v-if="null !== this.$store.getters.getMainUser">
|
||||||
<calendar-active :user="this.$store.getters.getMainUser" ></calendar-active>
|
<calendar-active :user="this.$store.getters.getMainUser" />
|
||||||
</div>
|
</div>
|
||||||
<pick-entity
|
<pick-entity
|
||||||
:multiple="false"
|
:multiple="false"
|
||||||
:types="['user']"
|
:types="['user']"
|
||||||
:uniqid="'main_user_calendar'"
|
:uniqid="'main_user_calendar'"
|
||||||
:picked="null !== this.$store.getters.getMainUser ? [this.$store.getters.getMainUser] : []"
|
:picked="
|
||||||
:removableIfSet="false"
|
null !== this.$store.getters.getMainUser
|
||||||
:displayPicked="false"
|
? [this.$store.getters.getMainUser]
|
||||||
|
: []
|
||||||
|
"
|
||||||
|
:removable-if-set="false"
|
||||||
|
:display-picked="false"
|
||||||
:suggested="this.suggestedUsers"
|
:suggested="this.suggestedUsers"
|
||||||
:label="'main_user'"
|
:label="'main_user'"
|
||||||
@addNewEntity="setMainUser"
|
@add-new-entity="setMainUser"
|
||||||
></pick-entity>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</teleport>
|
</teleport>
|
||||||
|
|
||||||
<concerned-groups></concerned-groups>
|
<concerned-groups />
|
||||||
|
|
||||||
<teleport to="#schedule">
|
<teleport to="#schedule">
|
||||||
<div class="row mb-3" v-if="activity.startDate !== null">
|
<div class="row mb-3" v-if="activity.startDate !== null">
|
||||||
<label class="col-form-label col-sm-4">Date</label>
|
<label class="col-form-label col-sm-4">Date</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
{{ $d(activity.startDate, 'long') }} - {{ $d(activity.endDate, 'hoursOnly') }}
|
{{ $d(activity.startDate, "long") }} -
|
||||||
<span v-if="activity.calendarRange === null">(Pas de plage de disponibilité sélectionnée)</span>
|
{{ $d(activity.endDate, "hoursOnly") }}
|
||||||
|
<span v-if="activity.calendarRange === null"
|
||||||
|
>(Pas de plage de disponibilité sélectionnée)</span
|
||||||
|
>
|
||||||
<span v-else>(Une plage de disponibilité sélectionnée)</span>
|
<span v-else>(Une plage de disponibilité sélectionnée)</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</teleport>
|
</teleport>
|
||||||
|
|
||||||
<location></location>
|
<location />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<teleport to="#fullCalendar">
|
<teleport to="#fullCalendar">
|
||||||
<div class="calendar-actives">
|
<div class="calendar-actives">
|
||||||
<template class="" v-for="u in getActiveUsers" :key="u.id">
|
<template v-for="u in getActiveUsers" :key="u.id">
|
||||||
<calendar-active :user="u" :invite="this.$store.getters.getInviteForUser(u)"></calendar-active>
|
<calendar-active
|
||||||
|
:user="u"
|
||||||
|
:invite="this.$store.getters.getInviteForUser(u)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="display-options row justify-content-between" style="margin-top: 1rem;">
|
<div
|
||||||
|
class="display-options row justify-content-between"
|
||||||
|
style="margin-top: 1rem"
|
||||||
|
>
|
||||||
<div class="col-sm-9 col-xs-12">
|
<div class="col-sm-9 col-xs-12">
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3">
|
||||||
<label class="input-group-text" for="slotDuration">Durée des créneaux</label>
|
<label class="input-group-text" for="slotDuration"
|
||||||
<select v-model="slotDuration" id="slotDuration" class="form-select">
|
>Durée des créneaux</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
v-model="slotDuration"
|
||||||
|
id="slotDuration"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
<option value="00:05:00">5 minutes</option>
|
<option value="00:05:00">5 minutes</option>
|
||||||
<option value="00:10:00">10 minutes</option>
|
<option value="00:10:00">10 minutes</option>
|
||||||
<option value="00:15:00">15 minutes</option>
|
<option value="00:15:00">15 minutes</option>
|
||||||
<option value="00:30:00">30 minutes</option>
|
<option value="00:30:00">30 minutes</option>
|
||||||
</select>
|
</select>
|
||||||
<label class="input-group-text" for="slotMinTime">De</label>
|
<label class="input-group-text" for="slotMinTime">De</label>
|
||||||
<select v-model="slotMinTime" id="slotMinTime" class="form-select">
|
<select
|
||||||
|
v-model="slotMinTime"
|
||||||
|
id="slotMinTime"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
<option value="00:00:00">0h</option>
|
<option value="00:00:00">0h</option>
|
||||||
<option value="01:00:00">1h</option>
|
<option value="01:00:00">1h</option>
|
||||||
<option value="02:00:00">2h</option>
|
<option value="02:00:00">2h</option>
|
||||||
@ -73,7 +92,11 @@
|
|||||||
<option value="12:00:00">12h</option>
|
<option value="12:00:00">12h</option>
|
||||||
</select>
|
</select>
|
||||||
<label class="input-group-text" for="slotMaxTime">À</label>
|
<label class="input-group-text" for="slotMaxTime">À</label>
|
||||||
<select v-model="slotMaxTime" id="slotMaxTime" class="form-select">
|
<select
|
||||||
|
v-model="slotMaxTime"
|
||||||
|
id="slotMaxTime"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
<option value="12:00:00">12h</option>
|
<option value="12:00:00">12h</option>
|
||||||
<option value="13:00:00">13h</option>
|
<option value="13:00:00">13h</option>
|
||||||
<option value="14:00:00">14h</option>
|
<option value="14:00:00">14h</option>
|
||||||
@ -94,21 +117,44 @@
|
|||||||
<div class="float-end">
|
<div class="float-end">
|
||||||
<div class="form-check input-group">
|
<div class="form-check input-group">
|
||||||
<span class="input-group-text">
|
<span class="input-group-text">
|
||||||
<input id="showHideWE" class="mt-0" type="checkbox" v-model="hideWeekends">
|
<input
|
||||||
|
id="showHideWE"
|
||||||
|
class="mt-0"
|
||||||
|
type="checkbox"
|
||||||
|
v-model="hideWeekends"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
<label for="showHideWE" class="form-check-label input-group-text">Week-ends</label>
|
<label
|
||||||
|
for="showHideWE"
|
||||||
|
class="form-check-label input-group-text"
|
||||||
|
>Week-ends</label
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<FullCalendar ref="fullCalendar" :options="calendarOptions">
|
<FullCalendar ref="fullCalendar" :options="calendarOptions">
|
||||||
<template v-slot:eventContent='arg'>
|
<template #eventContent="arg">
|
||||||
<span>
|
<span>
|
||||||
<b v-if="arg.event.extendedProps.is === 'remote'">{{ arg.event.title}}</b>
|
<b v-if="arg.event.extendedProps.is === 'remote'">{{
|
||||||
<b v-else-if="arg.event.extendedProps.is === 'range'">{{ arg.timeText }} {{ arg.event.extendedProps.locationName }} <small>{{ arg.event.extendedProps.userLabel }}</small></b>
|
arg.event.title
|
||||||
<b v-else-if="arg.event.extendedProps.is === 'current'">{{ arg.timeText }} {{ $t('current_selected')}} </b>
|
}}</b>
|
||||||
<b v-else-if="arg.event.extendedProps.is === 'local'">{{ arg.event.title}}</b>
|
<b v-else-if="arg.event.extendedProps.is === 'range'"
|
||||||
<b v-else>{{ arg.timeText }} {{ $t('current_selected')}} </b>
|
>{{ arg.timeText }}
|
||||||
|
{{ arg.event.extendedProps.locationName }}
|
||||||
|
<small>{{
|
||||||
|
arg.event.extendedProps.userLabel
|
||||||
|
}}</small></b
|
||||||
|
>
|
||||||
|
<b v-else-if="arg.event.extendedProps.is === 'current'"
|
||||||
|
>{{ arg.timeText }} {{ $t("current_selected") }}
|
||||||
|
</b>
|
||||||
|
<b v-else-if="arg.event.extendedProps.is === 'local'">{{
|
||||||
|
arg.event.title
|
||||||
|
}}</b>
|
||||||
|
<b v-else
|
||||||
|
>{{ arg.timeText }} {{ $t("current_selected") }}
|
||||||
|
</b>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</FullCalendar>
|
</FullCalendar>
|
||||||
@ -116,16 +162,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ConcernedGroups from 'ChillActivityAssets/vuejs/Activity/components/ConcernedGroups.vue';
|
import ConcernedGroups from "ChillActivityAssets/vuejs/Activity/components/ConcernedGroups.vue";
|
||||||
import Location from 'ChillActivityAssets/vuejs/Activity/components/Location.vue';
|
import Location from "ChillActivityAssets/vuejs/Activity/components/Location.vue";
|
||||||
import frLocale from '@fullcalendar/core/locales/fr';
|
import frLocale from "@fullcalendar/core/locales/fr";
|
||||||
import FullCalendar from '@fullcalendar/vue3';
|
import FullCalendar from "@fullcalendar/vue3";
|
||||||
import dayGridPlugin from '@fullcalendar/daygrid';
|
import dayGridPlugin from "@fullcalendar/daygrid";
|
||||||
import interactionPlugin from '@fullcalendar/interaction';
|
import interactionPlugin from "@fullcalendar/interaction";
|
||||||
import timeGridPlugin from '@fullcalendar/timegrid';
|
import timeGridPlugin from "@fullcalendar/timegrid";
|
||||||
import listPlugin from '@fullcalendar/list';
|
import listPlugin from "@fullcalendar/list";
|
||||||
import CalendarActive from './Components/CalendarActive';
|
import CalendarActive from "./Components/CalendarActive";
|
||||||
import PickEntity from 'ChillMainAssets/vuejs/PickEntity/PickEntity.vue';
|
import PickEntity from "ChillMainAssets/vuejs/PickEntity/PickEntity.vue";
|
||||||
import { mapGetters, mapState } from "vuex";
|
import { mapGetters, mapState } from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -141,24 +187,30 @@ export default {
|
|||||||
return {
|
return {
|
||||||
errorMsg: [],
|
errorMsg: [],
|
||||||
showMyCalendar: false,
|
showMyCalendar: false,
|
||||||
slotDuration: '00:05:00',
|
slotDuration: "00:05:00",
|
||||||
slotMinTime: '09:00:00',
|
slotMinTime: "09:00:00",
|
||||||
slotMaxTime: '18:00:00',
|
slotMaxTime: "18:00:00",
|
||||||
hideWeekEnds: true,
|
hideWeekEnds: true,
|
||||||
previousUser: [],
|
previousUser: [],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['getMainUser']),
|
...mapGetters(["getMainUser"]),
|
||||||
...mapState(['activity']),
|
...mapState(["activity"]),
|
||||||
events() {
|
events() {
|
||||||
return this.$store.getters.getEventSources;
|
return this.$store.getters.getEventSources;
|
||||||
},
|
},
|
||||||
calendarOptions() {
|
calendarOptions() {
|
||||||
return {
|
return {
|
||||||
locale: frLocale,
|
locale: frLocale,
|
||||||
plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin, dayGridPlugin, listPlugin],
|
plugins: [
|
||||||
initialView: 'timeGridWeek',
|
dayGridPlugin,
|
||||||
|
interactionPlugin,
|
||||||
|
timeGridPlugin,
|
||||||
|
dayGridPlugin,
|
||||||
|
listPlugin,
|
||||||
|
],
|
||||||
|
initialView: "timeGridWeek",
|
||||||
initialDate: this.$store.getters.getInitialDate,
|
initialDate: this.$store.getters.getInitialDate,
|
||||||
eventSources: this.events,
|
eventSources: this.events,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
@ -173,9 +225,9 @@ export default {
|
|||||||
editable: true,
|
editable: true,
|
||||||
weekends: !this.hideWeekEnds,
|
weekends: !this.hideWeekEnds,
|
||||||
headerToolbar: {
|
headerToolbar: {
|
||||||
left: 'prev,next today',
|
left: "prev,next today",
|
||||||
center: 'title',
|
center: "title",
|
||||||
right: 'timeGridWeek,timeGridDay,listWeek',
|
right: "timeGridWeek,timeGridDay,listWeek",
|
||||||
},
|
},
|
||||||
views: {
|
views: {
|
||||||
timeGrid: {
|
timeGrid: {
|
||||||
@ -195,9 +247,9 @@ export default {
|
|||||||
suggestedUsers() {
|
suggestedUsers() {
|
||||||
const suggested = [];
|
const suggested = [];
|
||||||
|
|
||||||
this.$data.previousUser.forEach(u => {
|
this.$data.previousUser.forEach((u) => {
|
||||||
if (u.id !== this.$store.getters.getMainUser.id) {
|
if (u.id !== this.$store.getters.getMainUser.id) {
|
||||||
suggested.push(u)
|
suggested.push(u);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -207,81 +259,120 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
setMainUser({ entity }) {
|
setMainUser({ entity }) {
|
||||||
const user = entity;
|
const user = entity;
|
||||||
console.log('setMainUser APP', entity);
|
console.log("setMainUser APP", entity);
|
||||||
|
|
||||||
if (user.id !== this.$store.getters.getMainUser && (
|
if (
|
||||||
this.$store.state.activity.calendarRange !== null
|
user.id !== this.$store.getters.getMainUser &&
|
||||||
|| this.$store.state.activity.startDate !== null
|
(this.$store.state.activity.calendarRange !== null ||
|
||||||
|| this.$store.state.activity.endDate !== null
|
this.$store.state.activity.startDate !== null ||
|
||||||
|
this.$store.state.activity.endDate !== null)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!window.confirm(
|
||||||
|
this.$t("change_main_user_will_reset_event_data"),
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
if (!window.confirm(this.$t('change_main_user_will_reset_event_data'))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the previous user, if any, in the previous user list (in use for suggestion)
|
// add the previous user, if any, in the previous user list (in use for suggestion)
|
||||||
if (null !== this.$store.getters.getMainUser) {
|
if (null !== this.$store.getters.getMainUser) {
|
||||||
const suggestedUids = new Set(this.$data.previousUser.map(u => u.id));
|
const suggestedUids = new Set(
|
||||||
|
this.$data.previousUser.map((u) => u.id),
|
||||||
|
);
|
||||||
if (!suggestedUids.has(this.$store.getters.getMainUser.id)) {
|
if (!suggestedUids.has(this.$store.getters.getMainUser.id)) {
|
||||||
this.$data.previousUser.push(this.$store.getters.getMainUser);
|
this.$data.previousUser.push(
|
||||||
|
this.$store.getters.getMainUser,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.dispatch('setMainUser', user);
|
this.$store.dispatch("setMainUser", user);
|
||||||
this.$store.commit('showUserOnCalendar', {user, ranges: true, remotes: true});
|
this.$store.commit("showUserOnCalendar", {
|
||||||
|
user,
|
||||||
|
ranges: true,
|
||||||
|
remotes: true,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
removeMainUser(user) {
|
removeMainUser(user) {
|
||||||
console.log('removeMainUser APP', user);
|
console.log("removeMainUser APP", user);
|
||||||
|
|
||||||
window.alert(this.$t('main_user_is_mandatory'));
|
window.alert(this.$t("main_user_is_mandatory"));
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
onDatesSet(event) {
|
onDatesSet(event) {
|
||||||
console.log('onDatesSet', event);
|
console.log("onDatesSet", event);
|
||||||
this.$store.dispatch('setCurrentDatesView', {start: event.start, end: event.end});
|
this.$store.dispatch("setCurrentDatesView", {
|
||||||
|
start: event.start,
|
||||||
|
end: event.end,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
onDateSelect(payload) {
|
onDateSelect(payload) {
|
||||||
console.log('onDateSelect', payload);
|
console.log("onDateSelect", payload);
|
||||||
|
|
||||||
// show an alert if changing mainUser
|
// show an alert if changing mainUser
|
||||||
if ((this.$store.getters.getMainUser !== null
|
if (
|
||||||
&& this.$store.state.me.id !== this.$store.getters.getMainUser.id)
|
(this.$store.getters.getMainUser !== null &&
|
||||||
|| this.$store.getters.getMainUser === null) {
|
this.$store.state.me.id !==
|
||||||
if (!window.confirm(this.$t('will_change_main_user_for_me'))) {
|
this.$store.getters.getMainUser.id) ||
|
||||||
|
this.$store.getters.getMainUser === null
|
||||||
|
) {
|
||||||
|
if (!window.confirm(this.$t("will_change_main_user_for_me"))) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
this.$store.commit('showUserOnCalendar', {user: this.$store.state.me, remotes: true, ranges: true})
|
this.$store.commit("showUserOnCalendar", {
|
||||||
|
user: this.$store.state.me,
|
||||||
|
remotes: true,
|
||||||
|
ranges: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.dispatch('setEventTimes', {start: payload.start, end: payload.end});
|
this.$store.dispatch("setEventTimes", {
|
||||||
|
start: payload.start,
|
||||||
|
end: payload.end,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
onEventChange(payload) {
|
onEventChange(payload) {
|
||||||
console.log('onEventChange', payload);
|
console.log("onEventChange", payload);
|
||||||
if (this.$store.state.activity.calendarRange !== null) {
|
if (this.$store.state.activity.calendarRange !== null) {
|
||||||
throw new Error("not allowed to edit a calendar associated with a calendar range");
|
throw new Error(
|
||||||
|
"not allowed to edit a calendar associated with a calendar range",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.$store.dispatch('setEventTimes', {start: payload.event.start, end: payload.event.end});
|
this.$store.dispatch("setEventTimes", {
|
||||||
|
start: payload.event.start,
|
||||||
|
end: payload.event.end,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
onEventClick(payload) {
|
onEventClick(payload) {
|
||||||
if (payload.event.extendedProps.is !== 'range') {
|
if (payload.event.extendedProps.is !== "range") {
|
||||||
// do nothing when clicking on remote
|
// do nothing when clicking on remote
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// show an alert if changing mainUser
|
// show an alert if changing mainUser
|
||||||
if (this.$store.getters.getMainUser !== null
|
if (
|
||||||
&& payload.event.extendedProps.userId !== this.$store.getters.getMainUser.id) {
|
this.$store.getters.getMainUser !== null &&
|
||||||
if (!window.confirm(this.$t('this_calendar_range_will_change_main_user'))) {
|
payload.event.extendedProps.userId !==
|
||||||
|
this.$store.getters.getMainUser.id
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!window.confirm(
|
||||||
|
this.$t("this_calendar_range_will_change_main_user"),
|
||||||
|
)
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.dispatch('associateCalendarToRange', {range: payload.event});
|
this.$store.dispatch("associateCalendarToRange", {
|
||||||
|
range: payload.event,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -3,68 +3,107 @@
|
|||||||
<span class="badge-user">
|
<span class="badge-user">
|
||||||
{{ user.text }}
|
{{ user.text }}
|
||||||
<template v-if="invite !== null">
|
<template v-if="invite !== null">
|
||||||
<i v-if="invite.status === 'accepted'" class="fa fa-check"></i>
|
<i v-if="invite.status === 'accepted'" class="fa fa-check" />
|
||||||
<i v-else-if="invite.status === 'declined'" class="fa fa-times"></i>
|
<i
|
||||||
<i v-else-if="invite.status === 'pending'" class="fa fa-question-o"></i>
|
v-else-if="invite.status === 'declined'"
|
||||||
<i v-else-if="invite.status === 'tentative'" class="fa fa-question"></i>
|
class="fa fa-times"
|
||||||
|
/>
|
||||||
|
<i
|
||||||
|
v-else-if="invite.status === 'pending'"
|
||||||
|
class="fa fa-question-o"
|
||||||
|
/>
|
||||||
|
<i
|
||||||
|
v-else-if="invite.status === 'tentative'"
|
||||||
|
class="fa fa-question"
|
||||||
|
/>
|
||||||
<span v-else="">{{ invite.status }}</span>
|
<span v-else="">{{ invite.status }}</span>
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
<span class="form-check-inline form-switch">
|
<span class="form-check-inline form-switch">
|
||||||
<input class="form-check-input" type="checkbox" id="flexSwitchCheckDefault" v-model="rangeShow">
|
<input
|
||||||
<label class="form-check-label" for="flexSwitchCheckDefault" title="Disponibilités"><i class="fa fa-calendar-check-o"></i></label>
|
class="form-check-input"
|
||||||
|
type="checkbox"
|
||||||
|
id="flexSwitchCheckDefault"
|
||||||
|
v-model="rangeShow"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
for="flexSwitchCheckDefault"
|
||||||
|
title="Disponibilités"
|
||||||
|
><i class="fa fa-calendar-check-o"
|
||||||
|
/></label>
|
||||||
</span>
|
</span>
|
||||||
<span class="form-check-inline form-switch">
|
<span class="form-check-inline form-switch">
|
||||||
<input class="form-check-input" type="checkbox" id="flexSwitchCheckDefault" v-model="remoteShow">
|
<input
|
||||||
<label class="form-check-label" for="flexSwitchCheckDefault" title="Agenda"><i class="fa fa-calendar"></i></label>
|
class="form-check-input"
|
||||||
|
type="checkbox"
|
||||||
|
id="flexSwitchCheckDefault"
|
||||||
|
v-model="remoteShow"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
for="flexSwitchCheckDefault"
|
||||||
|
title="Agenda"
|
||||||
|
><i class="fa fa-calendar"
|
||||||
|
/></label>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapGetters} from 'vuex';
|
import { mapGetters } from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CalendarActive",
|
name: "CalendarActive",
|
||||||
props: {
|
props: {
|
||||||
user: {
|
user: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
invite: {
|
invite: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: null,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
style() {
|
style() {
|
||||||
return {
|
return {
|
||||||
backgroundColor: this.$store.getters.getUserData(this.user).mainColor,
|
backgroundColor: this.$store.getters.getUserData(this.user)
|
||||||
|
.mainColor,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
rangeShow: {
|
rangeShow: {
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit('showUserOnCalendar', {user: this.user, ranges: value});
|
this.$store.commit("showUserOnCalendar", {
|
||||||
|
user: this.user,
|
||||||
|
ranges: value,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
get() {
|
get() {
|
||||||
return this.$store.getters.isRangeShownOnCalendarForUser(this.user);
|
return this.$store.getters.isRangeShownOnCalendarForUser(
|
||||||
}
|
this.user,
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
remoteShow: {
|
remoteShow: {
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$store.commit('showUserOnCalendar', {user: this.user, remotes: value});
|
this.$store.commit("showUserOnCalendar", {
|
||||||
|
user: this.user,
|
||||||
|
remotes: value,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
get() {
|
get() {
|
||||||
return this.$store.getters.isRemoteShownOnCalendarForUser(this.user);
|
return this.$store.getters.isRemoteShownOnCalendarForUser(
|
||||||
}
|
this.user,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
||||||
.calendar-active {
|
.calendar-active {
|
||||||
margin: 0 0.25rem 0.25rem 0;
|
margin: 0 0.25rem 0.25rem 0;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {fetchResults} from '../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods';
|
import { fetchResults } from "../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||||
import {datetimeToISO} from '../../../../../ChillMainBundle/Resources/public/chill/js/date';
|
import { datetimeToISO } from "../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
||||||
import {User} from '../../../../../ChillMainBundle/Resources/public/types';
|
import { User } from "../../../../../ChillMainBundle/Resources/public/types";
|
||||||
import {CalendarLight, CalendarRange, CalendarRemote} from '../../types';
|
import { CalendarLight, CalendarRange, CalendarRemote } from "../../types";
|
||||||
|
|
||||||
// re-export whoami
|
// re-export whoami
|
||||||
export { whoami } from "../../../../../ChillMainBundle/Resources/public/lib/api/user";
|
export { whoami } from "../../../../../ChillMainBundle/Resources/public/lib/api/user";
|
||||||
@ -13,26 +13,38 @@ export {whoami} from "../../../../../ChillMainBundle/Resources/public/lib/api/us
|
|||||||
* @param Date end
|
* @param Date end
|
||||||
* @return Promise
|
* @return Promise
|
||||||
*/
|
*/
|
||||||
export const fetchCalendarRangeForUser = (user: User, start: Date, end: Date): Promise<CalendarRange[]> => {
|
export const fetchCalendarRangeForUser = (
|
||||||
|
user: User,
|
||||||
|
start: Date,
|
||||||
|
end: Date,
|
||||||
|
): Promise<CalendarRange[]> => {
|
||||||
const uri = `/api/1.0/calendar/calendar-range-available/${user.id}.json`;
|
const uri = `/api/1.0/calendar/calendar-range-available/${user.id}.json`;
|
||||||
const dateFrom = datetimeToISO(start);
|
const dateFrom = datetimeToISO(start);
|
||||||
const dateTo = datetimeToISO(end);
|
const dateTo = datetimeToISO(end);
|
||||||
|
|
||||||
return fetchResults<CalendarRange>(uri, { dateFrom, dateTo });
|
return fetchResults<CalendarRange>(uri, { dateFrom, dateTo });
|
||||||
}
|
};
|
||||||
|
|
||||||
export const fetchCalendarRemoteForUser = (user: User, start: Date, end: Date): Promise<CalendarRemote[]> => {
|
export const fetchCalendarRemoteForUser = (
|
||||||
|
user: User,
|
||||||
|
start: Date,
|
||||||
|
end: Date,
|
||||||
|
): Promise<CalendarRemote[]> => {
|
||||||
const uri = `/api/1.0/calendar/proxy/calendar/by-user/${user.id}/events`;
|
const uri = `/api/1.0/calendar/proxy/calendar/by-user/${user.id}/events`;
|
||||||
const dateFrom = datetimeToISO(start);
|
const dateFrom = datetimeToISO(start);
|
||||||
const dateTo = datetimeToISO(end);
|
const dateTo = datetimeToISO(end);
|
||||||
|
|
||||||
return fetchResults<CalendarRemote>(uri, { dateFrom, dateTo });
|
return fetchResults<CalendarRemote>(uri, { dateFrom, dateTo });
|
||||||
}
|
};
|
||||||
|
|
||||||
export const fetchCalendarLocalForUser = (user: User, start: Date, end: Date): Promise<CalendarLight[]> => {
|
export const fetchCalendarLocalForUser = (
|
||||||
|
user: User,
|
||||||
|
start: Date,
|
||||||
|
end: Date,
|
||||||
|
): Promise<CalendarLight[]> => {
|
||||||
const uri = `/api/1.0/calendar/calendar/by-user/${user.id}.json`;
|
const uri = `/api/1.0/calendar/calendar/by-user/${user.id}.json`;
|
||||||
const dateFrom = datetimeToISO(start);
|
const dateFrom = datetimeToISO(start);
|
||||||
const dateTo = datetimeToISO(end);
|
const dateTo = datetimeToISO(end);
|
||||||
|
|
||||||
return fetchResults<CalendarLight>(uri, { dateFrom, dateTo });
|
return fetchResults<CalendarLight>(uri, { dateFrom, dateTo });
|
||||||
}
|
};
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
|
const COLORS = [
|
||||||
const COLORS = [ /* from https://colorbrewer2.org/#type=qualitative&scheme=Set3&n=12 */
|
/* from https://colorbrewer2.org/#type=qualitative&scheme=Set3&n=12 */
|
||||||
'#8dd3c7',
|
"#8dd3c7",
|
||||||
'#ffffb3',
|
"#ffffb3",
|
||||||
'#bebada',
|
"#bebada",
|
||||||
'#fb8072',
|
"#fb8072",
|
||||||
'#80b1d3',
|
"#80b1d3",
|
||||||
'#fdb462',
|
"#fdb462",
|
||||||
'#b3de69',
|
"#b3de69",
|
||||||
'#fccde5',
|
"#fccde5",
|
||||||
'#d9d9d9',
|
"#d9d9d9",
|
||||||
'#bc80bd',
|
"#bc80bd",
|
||||||
'#ccebc5',
|
"#ccebc5",
|
||||||
'#ffed6f'
|
"#ffed6f",
|
||||||
];
|
];
|
||||||
|
|
||||||
export {
|
export { COLORS };
|
||||||
COLORS,
|
|
||||||
};
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {personMessages} from 'ChillPersonAssets/vuejs/_js/i18n'
|
import { personMessages } from "ChillPersonAssets/vuejs/_js/i18n";
|
||||||
import {calendarUserSelectorMessages} from '../_components/CalendarUserSelector/js/i18n';
|
import { calendarUserSelectorMessages } from "../_components/CalendarUserSelector/js/i18n";
|
||||||
import {activityMessages} from 'ChillActivityAssets/vuejs/Activity/i18n';
|
import { activityMessages } from "ChillActivityAssets/vuejs/Activity/i18n";
|
||||||
|
|
||||||
const appMessages = {
|
const appMessages = {
|
||||||
fr: {
|
fr: {
|
||||||
@ -13,20 +13,22 @@ const appMessages = {
|
|||||||
bloc_thirdparty: "Tiers professionnels",
|
bloc_thirdparty: "Tiers professionnels",
|
||||||
bloc_users: "T(M)S",
|
bloc_users: "T(M)S",
|
||||||
},
|
},
|
||||||
this_calendar_range_will_change_main_user: "Cette plage de disponibilité n'est pas celle de l'utilisateur principal. Si vous continuez, l'utilisateur principal sera adapté. Êtes-vous sûr·e ?",
|
this_calendar_range_will_change_main_user:
|
||||||
will_change_main_user_for_me: "Vous ne pouvez pas écrire dans le calendrier d'un autre utilisateur. Voulez-vous être l'utilisateur principal de ce rendez-vous ?",
|
"Cette plage de disponibilité n'est pas celle de l'utilisateur principal. Si vous continuez, l'utilisateur principal sera adapté. Êtes-vous sûr·e ?",
|
||||||
main_user_is_mandatory: "L'utilisateur principal est requis. Vous pouvez le modifier, mais pas le supprimer",
|
will_change_main_user_for_me:
|
||||||
change_main_user_will_reset_event_data: "Modifier l'utilisateur principal nécessite de choisir une autre plage de disponibilité ou un autre horaire. Ces informations seront perdues. Êtes-vous sûr·e de vouloir continuer ?",
|
"Vous ne pouvez pas écrire dans le calendrier d'un autre utilisateur. Voulez-vous être l'utilisateur principal de ce rendez-vous ?",
|
||||||
list_three_days: 'Liste 3 jours',
|
main_user_is_mandatory:
|
||||||
current_selected: 'Rendez-vous fixé',
|
"L'utilisateur principal est requis. Vous pouvez le modifier, mais pas le supprimer",
|
||||||
|
change_main_user_will_reset_event_data:
|
||||||
|
"Modifier l'utilisateur principal nécessite de choisir une autre plage de disponibilité ou un autre horaire. Ces informations seront perdues. Êtes-vous sûr·e de vouloir continuer ?",
|
||||||
|
list_three_days: "Liste 3 jours",
|
||||||
|
current_selected: "Rendez-vous fixé",
|
||||||
main_user: "Utilisateur principal",
|
main_user: "Utilisateur principal",
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
Object.assign(appMessages.fr, personMessages.fr);
|
Object.assign(appMessages.fr, personMessages.fr);
|
||||||
Object.assign(appMessages.fr, calendarUserSelectorMessages.fr);
|
Object.assign(appMessages.fr, calendarUserSelectorMessages.fr);
|
||||||
Object.assign(appMessages.fr, activityMessages.fr);
|
Object.assign(appMessages.fr, activityMessages.fr);
|
||||||
|
|
||||||
export {
|
export { appMessages };
|
||||||
appMessages
|
|
||||||
};
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { createApp } from 'vue';
|
import { createApp } from "vue";
|
||||||
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
|
import { _createI18n } from "ChillMainAssets/vuejs/_js/i18n";
|
||||||
import { appMessages } from './i18n'
|
import { appMessages } from "./i18n";
|
||||||
import store from './store'
|
import store from "./store";
|
||||||
|
|
||||||
import App from './App.vue';
|
import App from "./App.vue";
|
||||||
|
|
||||||
const i18n = _createI18n(appMessages);
|
const i18n = _createI18n(appMessages);
|
||||||
|
|
||||||
@ -12,5 +12,5 @@ const app = createApp({
|
|||||||
})
|
})
|
||||||
.use(store)
|
.use(store)
|
||||||
.use(i18n)
|
.use(i18n)
|
||||||
.component('app', App)
|
.component("app", App)
|
||||||
.mount('#calendar');
|
.mount("#calendar");
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import {
|
import { addIdToValue, removeIdFromValue } from "./utils";
|
||||||
addIdToValue,
|
|
||||||
removeIdFromValue,
|
|
||||||
} from './utils';
|
|
||||||
import {
|
import {
|
||||||
fetchCalendarRangeForUser,
|
fetchCalendarRangeForUser,
|
||||||
fetchCalendarRemoteForUser,
|
fetchCalendarRemoteForUser,
|
||||||
fetchCalendarLocalForUser,
|
fetchCalendarLocalForUser,
|
||||||
} from './../api';
|
} from "./../api";
|
||||||
import {datetimeToISO} from 'ChillMainAssets/chill/js/date';
|
import { datetimeToISO } from "ChillMainAssets/chill/js/date";
|
||||||
import {postLocation} from 'ChillActivityAssets/vuejs/Activity/api';
|
import { postLocation } from "ChillActivityAssets/vuejs/Activity/api";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will store a unique key for each value, and prevent to launch the same
|
* This will store a unique key for each value, and prevent to launch the same
|
||||||
@ -25,9 +22,9 @@ const fetchings = new Set();
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
setCurrentDatesView({ commit, dispatch }, { start, end }) {
|
setCurrentDatesView({ commit, dispatch }, { start, end }) {
|
||||||
commit('setCurrentDatesView', {start, end});
|
commit("setCurrentDatesView", { start, end });
|
||||||
|
|
||||||
return dispatch('fetchCalendarEvents');
|
return dispatch("fetchCalendarEvents");
|
||||||
},
|
},
|
||||||
fetchCalendarEvents({ state, getters, dispatch }) {
|
fetchCalendarEvents({ state, getters, dispatch }) {
|
||||||
if (state.currentView.start === null && state.currentView.end === null) {
|
if (state.currentView.start === null && state.currentView.end === null) {
|
||||||
@ -39,29 +36,32 @@ export default {
|
|||||||
let unique = `${uid}, ${state.currentView.start.toISOString()}, ${state.currentView.end.toISOString()}`;
|
let unique = `${uid}, ${state.currentView.start.toISOString()}, ${state.currentView.end.toISOString()}`;
|
||||||
|
|
||||||
if (fetchings.has(unique)) {
|
if (fetchings.has(unique)) {
|
||||||
console.log('prevent from fetching for a user', unique);
|
console.log("prevent from fetching for a user", unique);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchings.add(unique);
|
fetchings.add(unique);
|
||||||
|
|
||||||
promises.push(
|
promises.push(
|
||||||
dispatch(
|
dispatch("fetchCalendarRangeForUser", {
|
||||||
'fetchCalendarRangeForUser',
|
user: state.usersData.get(uid).user,
|
||||||
{user: state.usersData.get(uid).user, start: state.currentView.start, end: state.currentView.end}
|
start: state.currentView.start,
|
||||||
)
|
end: state.currentView.end,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
promises.push(
|
promises.push(
|
||||||
dispatch(
|
dispatch("fetchCalendarRemotesForUser", {
|
||||||
'fetchCalendarRemotesForUser',
|
user: state.usersData.get(uid).user,
|
||||||
{user: state.usersData.get(uid).user, start: state.currentView.start, end: state.currentView.end}
|
start: state.currentView.start,
|
||||||
)
|
end: state.currentView.end,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
promises.push(
|
promises.push(
|
||||||
dispatch(
|
dispatch("fetchCalendarLocalsForUser", {
|
||||||
'fetchCalendarLocalsForUser',
|
user: state.usersData.get(uid).user,
|
||||||
{user: state.usersData.get(uid).user, start: state.currentView.start, end: state.currentView.end}
|
start: state.currentView.start,
|
||||||
)
|
end: state.currentView.end,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ export default {
|
|||||||
fetchCalendarRangeForUser({ commit, getters }, { user, start, end }) {
|
fetchCalendarRangeForUser({ commit, getters }, { user, start, end }) {
|
||||||
if (!getters.isCalendarRangeLoadedForUser({ user, start, end })) {
|
if (!getters.isCalendarRangeLoadedForUser({ user, start, end })) {
|
||||||
return fetchCalendarRangeForUser(user, start, end).then((ranges) => {
|
return fetchCalendarRangeForUser(user, start, end).then((ranges) => {
|
||||||
commit('addCalendarRangesForUser', {user, ranges, start, end});
|
commit("addCalendarRangesForUser", { user, ranges, start, end });
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
@ -79,7 +79,7 @@ export default {
|
|||||||
fetchCalendarRemotesForUser({ commit, getters }, { user, start, end }) {
|
fetchCalendarRemotesForUser({ commit, getters }, { user, start, end }) {
|
||||||
if (!getters.isCalendarRemoteLoadedForUser({ user, start, end })) {
|
if (!getters.isCalendarRemoteLoadedForUser({ user, start, end })) {
|
||||||
return fetchCalendarRemoteForUser(user, start, end).then((remotes) => {
|
return fetchCalendarRemoteForUser(user, start, end).then((remotes) => {
|
||||||
commit('addCalendarRemotesForUser', {user, remotes, start, end});
|
commit("addCalendarRemotesForUser", { user, remotes, start, end });
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
@ -88,52 +88,72 @@ export default {
|
|||||||
fetchCalendarLocalsForUser({ commit, getters }, { user, start, end }) {
|
fetchCalendarLocalsForUser({ commit, getters }, { user, start, end }) {
|
||||||
if (!getters.isCalendarRemoteLoadedForUser({ user, start, end })) {
|
if (!getters.isCalendarRemoteLoadedForUser({ user, start, end })) {
|
||||||
return fetchCalendarLocalForUser(user, start, end).then((locals) => {
|
return fetchCalendarLocalForUser(user, start, end).then((locals) => {
|
||||||
commit('addCalendarLocalsForUser', {user, locals, start, end});
|
commit("addCalendarLocalsForUser", { user, locals, start, end });
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addPersonsInvolved({ commit, dispatch }, payload) {
|
addPersonsInvolved({ commit, dispatch }, payload) {
|
||||||
console.log('### action addPersonsInvolved', payload.result.type);
|
console.log("### action addPersonsInvolved", payload.result.type);
|
||||||
console.log('### action addPersonsInvolved payload result', payload.result);
|
console.log("### action addPersonsInvolved payload result", payload.result);
|
||||||
switch (payload.result.type) {
|
switch (payload.result.type) {
|
||||||
case 'person':
|
case "person":
|
||||||
let aPersons = document.getElementById("chill_activitybundle_activity_persons");
|
let aPersons = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_persons",
|
||||||
|
);
|
||||||
aPersons.value = addIdToValue(aPersons.value, payload.result.id);
|
aPersons.value = addIdToValue(aPersons.value, payload.result.id);
|
||||||
break;
|
break;
|
||||||
case 'thirdparty':
|
case "thirdparty":
|
||||||
let aThirdParties = document.getElementById("chill_activitybundle_activity_professionals");
|
let aThirdParties = document.getElementById(
|
||||||
aThirdParties.value = addIdToValue(aThirdParties.value, payload.result.id);
|
"chill_activitybundle_activity_professionals",
|
||||||
|
);
|
||||||
|
aThirdParties.value = addIdToValue(
|
||||||
|
aThirdParties.value,
|
||||||
|
payload.result.id,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'user':
|
case "user":
|
||||||
let aUsers = document.getElementById("chill_activitybundle_activity_users");
|
let aUsers = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_users",
|
||||||
|
);
|
||||||
aUsers.value = addIdToValue(aUsers.value, payload.result.id);
|
aUsers.value = addIdToValue(aUsers.value, payload.result.id);
|
||||||
commit('showUserOnCalendar', {user: payload.result, ranges: false, remotes: true});
|
commit("showUserOnCalendar", {
|
||||||
dispatch('fetchCalendarEvents');
|
user: payload.result,
|
||||||
|
ranges: false,
|
||||||
|
remotes: true,
|
||||||
|
});
|
||||||
|
dispatch("fetchCalendarEvents");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
;
|
commit("addPersonsInvolved", payload);
|
||||||
commit('addPersonsInvolved', payload);
|
|
||||||
},
|
},
|
||||||
removePersonInvolved({ commit }, payload) {
|
removePersonInvolved({ commit }, payload) {
|
||||||
//console.log('### action removePersonInvolved', payload);
|
//console.log('### action removePersonInvolved', payload);
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case 'person':
|
case "person":
|
||||||
let aPersons = document.getElementById("chill_activitybundle_activity_persons");
|
let aPersons = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_persons",
|
||||||
|
);
|
||||||
aPersons.value = removeIdFromValue(aPersons.value, payload.id);
|
aPersons.value = removeIdFromValue(aPersons.value, payload.id);
|
||||||
break;
|
break;
|
||||||
case 'thirdparty':
|
case "thirdparty":
|
||||||
let aThirdParties = document.getElementById("chill_activitybundle_activity_professionals");
|
let aThirdParties = document.getElementById(
|
||||||
aThirdParties.value = removeIdFromValue(aThirdParties.value, payload.id);
|
"chill_activitybundle_activity_professionals",
|
||||||
|
);
|
||||||
|
aThirdParties.value = removeIdFromValue(
|
||||||
|
aThirdParties.value,
|
||||||
|
payload.id,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'user':
|
case "user":
|
||||||
let aUsers = document.getElementById("chill_activitybundle_activity_users");
|
let aUsers = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_users",
|
||||||
|
);
|
||||||
aUsers.value = removeIdFromValue(aUsers.value, payload.id);
|
aUsers.value = removeIdFromValue(aUsers.value, payload.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
;
|
commit("removePersonInvolved", payload);
|
||||||
commit('removePersonInvolved', payload);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Calendar
|
// Calendar
|
||||||
@ -149,30 +169,48 @@ export default {
|
|||||||
* @param end
|
* @param end
|
||||||
*/
|
*/
|
||||||
setEventTimes({ commit, state, getters }, { start, end }) {
|
setEventTimes({ commit, state, getters }, { start, end }) {
|
||||||
console.log('### action createEvent', {start, end});
|
console.log("### action createEvent", { start, end });
|
||||||
let startDateInput = document.getElementById("chill_activitybundle_activity_startDate");
|
let startDateInput = document.getElementById(
|
||||||
startDateInput.value = null !== start ? datetimeToISO(start) : '';
|
"chill_activitybundle_activity_startDate",
|
||||||
let endDateInput = document.getElementById("chill_activitybundle_activity_endDate");
|
);
|
||||||
endDateInput.value = null !== end ? datetimeToISO(end) : '';
|
startDateInput.value = null !== start ? datetimeToISO(start) : "";
|
||||||
let calendarRangeInput = document.getElementById("chill_activitybundle_activity_calendarRange");
|
let endDateInput = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_endDate",
|
||||||
|
);
|
||||||
|
endDateInput.value = null !== end ? datetimeToISO(end) : "";
|
||||||
|
let calendarRangeInput = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_calendarRange",
|
||||||
|
);
|
||||||
calendarRangeInput.value = "";
|
calendarRangeInput.value = "";
|
||||||
|
|
||||||
if (getters.getMainUser === null || getters.getMainUser.id !== state.me.id) {
|
if (
|
||||||
let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser");
|
getters.getMainUser === null ||
|
||||||
|
getters.getMainUser.id !== state.me.id
|
||||||
|
) {
|
||||||
|
let mainUserInput = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_mainUser",
|
||||||
|
);
|
||||||
mainUserInput.value = state.me.id;
|
mainUserInput.value = state.me.id;
|
||||||
commit('setMainUser', state.me);
|
commit("setMainUser", state.me);
|
||||||
}
|
}
|
||||||
|
|
||||||
commit('setEventTimes', {start, end});
|
commit("setEventTimes", { start, end });
|
||||||
},
|
},
|
||||||
associateCalendarToRange({ state, commit, dispatch, getters }, { range }) {
|
associateCalendarToRange({ state, commit, dispatch, getters }, { range }) {
|
||||||
console.log('### action associateCAlendarToRange', range);
|
console.log("### action associateCAlendarToRange", range);
|
||||||
let startDateInput = document.getElementById("chill_activitybundle_activity_startDate");
|
let startDateInput = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_startDate",
|
||||||
|
);
|
||||||
startDateInput.value = null !== range ? datetimeToISO(range.start) : "";
|
startDateInput.value = null !== range ? datetimeToISO(range.start) : "";
|
||||||
let endDateInput = document.getElementById("chill_activitybundle_activity_endDate");
|
let endDateInput = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_endDate",
|
||||||
|
);
|
||||||
endDateInput.value = null !== range ? datetimeToISO(range.end) : "";
|
endDateInput.value = null !== range ? datetimeToISO(range.end) : "";
|
||||||
let calendarRangeInput = document.getElementById("chill_activitybundle_activity_calendarRange");
|
let calendarRangeInput = document.getElementById(
|
||||||
calendarRangeInput.value = null !== range ? Number(range.extendedProps.calendarRangeId) : "";
|
"chill_activitybundle_activity_calendarRange",
|
||||||
|
);
|
||||||
|
calendarRangeInput.value =
|
||||||
|
null !== range ? Number(range.extendedProps.calendarRangeId) : "";
|
||||||
|
|
||||||
if (null !== range) {
|
if (null !== range) {
|
||||||
let location = getters.getLocationById(range.extendedProps.locationId);
|
let location = getters.getLocationById(range.extendedProps.locationId);
|
||||||
@ -181,63 +219,68 @@ export default {
|
|||||||
console.error("location not found!", range.extendedProps.locationId);
|
console.error("location not found!", range.extendedProps.locationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch('updateLocation', location);
|
dispatch("updateLocation", location);
|
||||||
|
|
||||||
const userId = range.extendedProps.userId;
|
const userId = range.extendedProps.userId;
|
||||||
if (state.activity.mainUser !== null && state.activity.mainUser.id !== userId) {
|
if (
|
||||||
dispatch('setMainUser', state.usersData.get(userId).user);
|
state.activity.mainUser !== null &&
|
||||||
|
state.activity.mainUser.id !== userId
|
||||||
|
) {
|
||||||
|
dispatch("setMainUser", state.usersData.get(userId).user);
|
||||||
|
|
||||||
// TODO: remove persons involved with this user
|
// TODO: remove persons involved with this user
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commit('associateCalendarToRange', {range});
|
commit("associateCalendarToRange", { range });
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
},
|
},
|
||||||
setMainUser({ commit, dispatch, state }, mainUser) {
|
setMainUser({ commit, dispatch, state }, mainUser) {
|
||||||
console.log('setMainUser', mainUser);
|
console.log("setMainUser", mainUser);
|
||||||
|
|
||||||
let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser");
|
let mainUserInput = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_mainUser",
|
||||||
|
);
|
||||||
mainUserInput.value = Number(mainUser.id);
|
mainUserInput.value = Number(mainUser.id);
|
||||||
|
|
||||||
return dispatch('associateCalendarToRange', { range: null }).then(() => {
|
return dispatch("associateCalendarToRange", { range: null }).then(() => {
|
||||||
commit('setMainUser', mainUser);
|
commit("setMainUser", mainUser);
|
||||||
|
|
||||||
return dispatch('fetchCalendarEvents');
|
return dispatch("fetchCalendarEvents");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Location
|
// Location
|
||||||
updateLocation({ commit }, value) {
|
updateLocation({ commit }, value) {
|
||||||
console.log('### action: updateLocation', value);
|
console.log("### action: updateLocation", value);
|
||||||
let hiddenLocation = document.getElementById("chill_activitybundle_activity_location");
|
let hiddenLocation = document.getElementById(
|
||||||
|
"chill_activitybundle_activity_location",
|
||||||
|
);
|
||||||
if (value.onthefly) {
|
if (value.onthefly) {
|
||||||
const body = {
|
const body = {
|
||||||
"type": "location",
|
type: "location",
|
||||||
"name": value.name === '__AccompanyingCourseLocation__' ? null : value.name,
|
name:
|
||||||
"locationType": {
|
value.name === "__AccompanyingCourseLocation__" ? null : value.name,
|
||||||
"id": value.locationType.id,
|
locationType: {
|
||||||
"type": "location-type"
|
id: value.locationType.id,
|
||||||
}
|
type: "location-type",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
if (value.address.id) {
|
if (value.address.id) {
|
||||||
Object.assign(body, {
|
Object.assign(body, {
|
||||||
"address": {
|
address: {
|
||||||
"id": value.address.id
|
id: value.address.id,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
postLocation(body)
|
postLocation(body)
|
||||||
.then(
|
.then((location) => (hiddenLocation.value = location.id))
|
||||||
location => hiddenLocation.value = location.id
|
.catch((err) => {
|
||||||
).catch(
|
|
||||||
err => {
|
|
||||||
console.log(err.message);
|
console.log(err.message);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
hiddenLocation.value = value.id;
|
hiddenLocation.value = value.id;
|
||||||
}
|
}
|
||||||
commit("updateLocation", value);
|
commit("updateLocation", value);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
@ -18,7 +18,7 @@ export default {
|
|||||||
if (null === state.activity.start) {
|
if (null === state.activity.start) {
|
||||||
return new Date();
|
return new Date();
|
||||||
}
|
}
|
||||||
throw 'transform date to object ?';
|
throw "transform date to object ?";
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Compute the event sources to show on the FullCalendar
|
* Compute the event sources to show on the FullCalendar
|
||||||
@ -33,7 +33,7 @@ export default {
|
|||||||
// current calendar
|
// current calendar
|
||||||
if (state.activity.startDate !== null && state.activity.endDate !== null) {
|
if (state.activity.startDate !== null && state.activity.endDate !== null) {
|
||||||
const s = {
|
const s = {
|
||||||
id: 'current',
|
id: "current",
|
||||||
events: [
|
events: [
|
||||||
{
|
{
|
||||||
title: "Rendez-vous",
|
title: "Rendez-vous",
|
||||||
@ -41,8 +41,8 @@ export default {
|
|||||||
end: state.activity.endDate,
|
end: state.activity.endDate,
|
||||||
allDay: false,
|
allDay: false,
|
||||||
is: "current",
|
is: "current",
|
||||||
classNames: ['iscurrent'],
|
classNames: ["iscurrent"],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
editable: state.activity.calendarRange === null,
|
editable: state.activity.calendarRange === null,
|
||||||
};
|
};
|
||||||
@ -52,7 +52,7 @@ export default {
|
|||||||
|
|
||||||
for (const [userId, kinds] of state.currentView.users.entries()) {
|
for (const [userId, kinds] of state.currentView.users.entries()) {
|
||||||
if (!state.usersData.has(userId)) {
|
if (!state.usersData.has(userId)) {
|
||||||
console.log('try to get events on a user which not exists', userId);
|
console.log("try to get events on a user which not exists", userId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,11 +61,16 @@ export default {
|
|||||||
if (kinds.ranges && userData.calendarRanges.length > 0) {
|
if (kinds.ranges && userData.calendarRanges.length > 0) {
|
||||||
const s = {
|
const s = {
|
||||||
id: `ranges_${userId}`,
|
id: `ranges_${userId}`,
|
||||||
events: userData.calendarRanges.filter(r => state.activity.calendarRange === null || r.calendarRangeId !== state.activity.calendarRange.calendarRangeId),
|
events: userData.calendarRanges.filter(
|
||||||
|
(r) =>
|
||||||
|
state.activity.calendarRange === null ||
|
||||||
|
r.calendarRangeId !==
|
||||||
|
state.activity.calendarRange.calendarRangeId,
|
||||||
|
),
|
||||||
color: userData.mainColor,
|
color: userData.mainColor,
|
||||||
classNames: ['isrange'],
|
classNames: ["isrange"],
|
||||||
backgroundColor: 'white',
|
backgroundColor: "white",
|
||||||
textColor: 'black',
|
textColor: "black",
|
||||||
editable: false,
|
editable: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,10 +79,10 @@ export default {
|
|||||||
|
|
||||||
if (kinds.remotes && userData.remotes.length > 0) {
|
if (kinds.remotes && userData.remotes.length > 0) {
|
||||||
const s = {
|
const s = {
|
||||||
'id': `remote_${userId}`,
|
id: `remote_${userId}`,
|
||||||
events: userData.remotes,
|
events: userData.remotes,
|
||||||
color: userData.mainColor,
|
color: userData.mainColor,
|
||||||
textColor: 'black',
|
textColor: "black",
|
||||||
editable: false,
|
editable: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,10 +92,12 @@ export default {
|
|||||||
// if remotes is checked, we display also the locals calendars
|
// if remotes is checked, we display also the locals calendars
|
||||||
if (kinds.remotes && userData.locals.length > 0) {
|
if (kinds.remotes && userData.locals.length > 0) {
|
||||||
const s = {
|
const s = {
|
||||||
'id': `local_${userId}`,
|
id: `local_${userId}`,
|
||||||
events: userData.locals.filter(l => l.originId !== state.activity.id),
|
events: userData.locals.filter(
|
||||||
|
(l) => l.originId !== state.activity.id,
|
||||||
|
),
|
||||||
color: userData.mainColor,
|
color: userData.mainColor,
|
||||||
textColor: 'black',
|
textColor: "black",
|
||||||
editable: false,
|
editable: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -104,7 +111,7 @@ export default {
|
|||||||
return state.activity.startDate;
|
return state.activity.startDate;
|
||||||
},
|
},
|
||||||
getInviteForUser: (state) => (user) => {
|
getInviteForUser: (state) => (user) => {
|
||||||
return state.activity.invites.find(i => i.user.id === user.id);
|
return state.activity.invites.find((i) => i.user.id === user.id);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* get the user data for a specific user
|
* get the user data for a specific user
|
||||||
@ -138,7 +145,9 @@ export default {
|
|||||||
* @param getters
|
* @param getters
|
||||||
* @returns {(function({user: *, start: *, end: *}): (boolean))|*}
|
* @returns {(function({user: *, start: *, end: *}): (boolean))|*}
|
||||||
*/
|
*/
|
||||||
isCalendarRangeLoadedForUser: (state, getters) => ({user, start, end}) => {
|
isCalendarRangeLoadedForUser:
|
||||||
|
(state, getters) =>
|
||||||
|
({ user, start, end }) => {
|
||||||
if (!getters.hasUserData(user)) {
|
if (!getters.hasUserData(user)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -159,7 +168,9 @@ export default {
|
|||||||
* @param getters
|
* @param getters
|
||||||
* @returns {(function({user: *, start: *, end: *}): (boolean))|*}
|
* @returns {(function({user: *, start: *, end: *}): (boolean))|*}
|
||||||
*/
|
*/
|
||||||
isCalendarRemoteLoadedForUser: (state, getters) => ({user, start, end}) => {
|
isCalendarRemoteLoadedForUser:
|
||||||
|
(state, getters) =>
|
||||||
|
({ user, start, end }) => {
|
||||||
if (!getters.hasUserData(user)) {
|
if (!getters.hasUserData(user)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -180,8 +191,10 @@ export default {
|
|||||||
*/
|
*/
|
||||||
isRangeShownOnCalendarForUser: (state) => (user) => {
|
isRangeShownOnCalendarForUser: (state) => (user) => {
|
||||||
const k = state.currentView.users.get(user.id);
|
const k = state.currentView.users.get(user.id);
|
||||||
if (typeof k === 'undefined') {
|
if (typeof k === "undefined") {
|
||||||
console.error('try to determinate if calendar range is shown and user is not in currentView');
|
console.error(
|
||||||
|
"try to determinate if calendar range is shown and user is not in currentView",
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,8 +208,10 @@ export default {
|
|||||||
*/
|
*/
|
||||||
isRemoteShownOnCalendarForUser: (state) => (user) => {
|
isRemoteShownOnCalendarForUser: (state) => (user) => {
|
||||||
const k = state.currentView.users.get(user.id);
|
const k = state.currentView.users.get(user.id);
|
||||||
if (typeof k === 'undefined') {
|
if (typeof k === "undefined") {
|
||||||
console.error('try to determinate if calendar range is shown and user is not in currentView');
|
console.error(
|
||||||
|
"try to determinate if calendar range is shown and user is not in currentView",
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,8 +220,8 @@ export default {
|
|||||||
|
|
||||||
getLocationById: (state) => (id) => {
|
getLocationById: (state) => (id) => {
|
||||||
for (let group of state.availableLocations) {
|
for (let group of state.availableLocations) {
|
||||||
console.log('group', group);
|
console.log("group", group);
|
||||||
const found = group.locations.find(l => l.id === id);
|
const found = group.locations.find((l) => l.id === id);
|
||||||
if (typeof found !== "undefined") {
|
if (typeof found !== "undefined") {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
@ -216,57 +231,60 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
suggestedEntities(state, getters) {
|
suggestedEntities(state, getters) {
|
||||||
if (typeof (state.activity.accompanyingPeriod) === 'undefined') {
|
if (typeof state.activity.accompanyingPeriod === "undefined") {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const allEntities = [
|
const allEntities = [
|
||||||
...getters.suggestedPersons,
|
...getters.suggestedPersons,
|
||||||
...getters.suggestedRequestor,
|
...getters.suggestedRequestor,
|
||||||
...getters.suggestedUser,
|
...getters.suggestedUser,
|
||||||
...getters.suggestedResources
|
...getters.suggestedResources,
|
||||||
];
|
];
|
||||||
const uniqueIds = [...new Set(allEntities.map(i => `${i.type}-${i.id}`))];
|
const uniqueIds = [...new Set(allEntities.map((i) => `${i.type}-${i.id}`))];
|
||||||
return Array.from(uniqueIds, id => allEntities.filter(r => `${r.type}-${r.id}` === id)[0]);
|
return Array.from(
|
||||||
|
uniqueIds,
|
||||||
|
(id) => allEntities.filter((r) => `${r.type}-${r.id}` === id)[0],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
suggestedPersons(state) {
|
suggestedPersons(state) {
|
||||||
const existingPersonIds = state.activity.persons.map(p => p.id);
|
const existingPersonIds = state.activity.persons.map((p) => p.id);
|
||||||
return state.activity.accompanyingPeriod.participations
|
return state.activity.accompanyingPeriod.participations
|
||||||
.filter(p => p.endDate === null)
|
.filter((p) => p.endDate === null)
|
||||||
.map(p => p.person)
|
.map((p) => p.person)
|
||||||
.filter(p => !existingPersonIds.includes(p.id))
|
.filter((p) => !existingPersonIds.includes(p.id));
|
||||||
},
|
},
|
||||||
suggestedRequestor(state) {
|
suggestedRequestor(state) {
|
||||||
if (state.activity.accompanyingPeriod.requestor === null) {
|
if (state.activity.accompanyingPeriod.requestor === null) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingPersonIds = state.activity.persons.map(p => p.id);
|
const existingPersonIds = state.activity.persons.map((p) => p.id);
|
||||||
const existingThirdPartyIds = state.activity.thirdParties.map(p => p.id);
|
const existingThirdPartyIds = state.activity.thirdParties.map((p) => p.id);
|
||||||
return [state.activity.accompanyingPeriod.requestor]
|
return [state.activity.accompanyingPeriod.requestor].filter(
|
||||||
.filter(r =>
|
(r) =>
|
||||||
(r.type === 'person' && !existingPersonIds.includes(r.id)) ||
|
(r.type === "person" && !existingPersonIds.includes(r.id)) ||
|
||||||
(r.type === 'thirdparty' && !existingThirdPartyIds.includes(r.id))
|
(r.type === "thirdparty" && !existingThirdPartyIds.includes(r.id)),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
suggestedUser(state) {
|
suggestedUser(state) {
|
||||||
if (null === state.activity.users) {
|
if (null === state.activity.users) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const existingUserIds = state.activity.users.map(p => p.id);
|
const existingUserIds = state.activity.users.map((p) => p.id);
|
||||||
return [state.activity.accompanyingPeriod.user]
|
return [state.activity.accompanyingPeriod.user].filter(
|
||||||
.filter(
|
(u) => u !== null && !existingUserIds.includes(u.id),
|
||||||
u => u !== null && !existingUserIds.includes(u.id)
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
suggestedResources(state) {
|
suggestedResources(state) {
|
||||||
const resources = state.activity.accompanyingPeriod.resources;
|
const resources = state.activity.accompanyingPeriod.resources;
|
||||||
const existingPersonIds = state.activity.persons.map(p => p.id);
|
const existingPersonIds = state.activity.persons.map((p) => p.id);
|
||||||
const existingThirdPartyIds = state.activity.thirdParties.map(p => p.id);
|
const existingThirdPartyIds = state.activity.thirdParties.map((p) => p.id);
|
||||||
return state.activity.accompanyingPeriod.resources
|
return state.activity.accompanyingPeriod.resources
|
||||||
.map(r => r.resource)
|
.map((r) => r.resource)
|
||||||
.filter(r =>
|
.filter(
|
||||||
(r.type === 'person' && !existingPersonIds.includes(r.id)) ||
|
(r) =>
|
||||||
(r.type === 'thirdparty' && !existingThirdPartyIds.includes(r.id))
|
(r.type === "person" && !existingPersonIds.includes(r.id)) ||
|
||||||
|
(r.type === "thirdparty" && !existingThirdPartyIds.includes(r.id)),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import 'es6-promise/auto';
|
import "es6-promise/auto";
|
||||||
import { createStore } from 'vuex';
|
import { createStore } from "vuex";
|
||||||
import { postLocation } from 'ChillActivityAssets/vuejs/Activity/api';
|
import { postLocation } from "ChillActivityAssets/vuejs/Activity/api";
|
||||||
import getters from './getters';
|
import getters from "./getters";
|
||||||
import actions from './actions';
|
import actions from "./actions";
|
||||||
import mutations from './mutations';
|
import mutations from "./mutations";
|
||||||
import { mapEntity } from './utils';
|
import { mapEntity } from "./utils";
|
||||||
import { whoami } from '../api';
|
import { whoami } from "../api";
|
||||||
import prepareLocations from "ChillActivityAssets/vuejs/Activity/store.locations";
|
import prepareLocations from "ChillActivityAssets/vuejs/Activity/store.locations";
|
||||||
|
|
||||||
const debug = process.env.NODE_ENV !== 'production';
|
const debug = process.env.NODE_ENV !== "production";
|
||||||
|
|
||||||
const store = createStore({
|
const store = createStore({
|
||||||
strict: debug,
|
strict: debug,
|
||||||
@ -42,16 +42,24 @@ const store = createStore({
|
|||||||
actions,
|
actions,
|
||||||
});
|
});
|
||||||
|
|
||||||
whoami().then(me => {
|
whoami().then((me) => {
|
||||||
store.commit('setWhoAmiI', me);
|
store.commit("setWhoAmiI", me);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (null !== store.getters.getMainUser) {
|
if (null !== store.getters.getMainUser) {
|
||||||
store.commit('showUserOnCalendar', {ranges: true, remotes: true, user: store.getters.getMainUser});
|
store.commit("showUserOnCalendar", {
|
||||||
|
ranges: true,
|
||||||
|
remotes: true,
|
||||||
|
user: store.getters.getMainUser,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let u of store.state.activity.users) {
|
for (let u of store.state.activity.users) {
|
||||||
store.commit('showUserOnCalendar', {ranges: false, remotes: false, user: u});
|
store.commit("showUserOnCalendar", {
|
||||||
|
ranges: false,
|
||||||
|
remotes: false,
|
||||||
|
user: u,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareLocations(store);
|
prepareLocations(store);
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
calendarRangeToFullCalendarEvent,
|
calendarRangeToFullCalendarEvent,
|
||||||
remoteToFullCalendarEvent,
|
remoteToFullCalendarEvent,
|
||||||
localsToFullCalendarEvent,
|
localsToFullCalendarEvent,
|
||||||
} from './utils';
|
} from "./utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setWhoAmiI(state, me) {
|
setWhoAmiI(state, me) {
|
||||||
@ -20,13 +20,10 @@ export default {
|
|||||||
|
|
||||||
const cur = state.currentView.users.get(user.id);
|
const cur = state.currentView.users.get(user.id);
|
||||||
|
|
||||||
state.currentView.users.set(
|
state.currentView.users.set(user.id, {
|
||||||
user.id,
|
ranges: typeof ranges !== "undefined" ? ranges : cur.ranges,
|
||||||
{
|
remotes: typeof remotes !== "undefined" ? remotes : cur.remotes,
|
||||||
ranges: typeof ranges !== 'undefined' ? ranges : cur.ranges,
|
});
|
||||||
remotes: typeof remotes !== 'undefined' ? remotes : cur.remotes,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Set the event start and end to the given start and end,
|
* Set the event start and end to the given start and end,
|
||||||
@ -49,7 +46,7 @@ export default {
|
|||||||
* @param range
|
* @param range
|
||||||
*/
|
*/
|
||||||
associateCalendarToRange(state, { range }) {
|
associateCalendarToRange(state, { range }) {
|
||||||
console.log('associateCalendarToRange', range);
|
console.log("associateCalendarToRange", range);
|
||||||
|
|
||||||
if (null === range) {
|
if (null === range) {
|
||||||
state.activity.calendarRange = null;
|
state.activity.calendarRange = null;
|
||||||
@ -59,22 +56,25 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('userId', range.extendedProps.userId);
|
console.log("userId", range.extendedProps.userId);
|
||||||
|
|
||||||
const r = state.usersData.get(range.extendedProps.userId).calendarRanges
|
const r = state.usersData
|
||||||
.find(r => r.calendarRangeId === range.extendedProps.calendarRangeId);
|
.get(range.extendedProps.userId)
|
||||||
|
.calendarRanges.find(
|
||||||
|
(r) => r.calendarRangeId === range.extendedProps.calendarRangeId,
|
||||||
|
);
|
||||||
|
|
||||||
if (typeof r === 'undefined') {
|
if (typeof r === "undefined") {
|
||||||
throw Error('Could not find managed calendar range');
|
throw Error("Could not find managed calendar range");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('range found', r);
|
console.log("range found", r);
|
||||||
|
|
||||||
state.activity.startDate = range.start;
|
state.activity.startDate = range.start;
|
||||||
state.activity.endDate = range.end;
|
state.activity.endDate = range.end;
|
||||||
state.activity.calendarRange = r;
|
state.activity.calendarRange = r;
|
||||||
|
|
||||||
console.log('activity', state.activity);
|
console.log("activity", state.activity);
|
||||||
},
|
},
|
||||||
|
|
||||||
setMainUser(state, user) {
|
setMainUser(state, user) {
|
||||||
@ -85,32 +85,36 @@ export default {
|
|||||||
addPersonsInvolved(state, payload) {
|
addPersonsInvolved(state, payload) {
|
||||||
//console.log('### mutation addPersonsInvolved', payload.result.type);
|
//console.log('### mutation addPersonsInvolved', payload.result.type);
|
||||||
switch (payload.result.type) {
|
switch (payload.result.type) {
|
||||||
case 'person':
|
case "person":
|
||||||
state.activity.persons.push(payload.result);
|
state.activity.persons.push(payload.result);
|
||||||
break;
|
break;
|
||||||
case 'thirdparty':
|
case "thirdparty":
|
||||||
state.activity.thirdParties.push(payload.result);
|
state.activity.thirdParties.push(payload.result);
|
||||||
break;
|
break;
|
||||||
case 'user':
|
case "user":
|
||||||
state.activity.users.push(payload.result);
|
state.activity.users.push(payload.result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
;
|
|
||||||
},
|
},
|
||||||
removePersonInvolved(state, payload) {
|
removePersonInvolved(state, payload) {
|
||||||
//console.log('### mutation removePersonInvolved', payload.type);
|
//console.log('### mutation removePersonInvolved', payload.type);
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case 'person':
|
case "person":
|
||||||
state.activity.persons = state.activity.persons.filter(person => person !== payload);
|
state.activity.persons = state.activity.persons.filter(
|
||||||
|
(person) => person !== payload,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'thirdparty':
|
case "thirdparty":
|
||||||
state.activity.thirdParties = state.activity.thirdParties.filter(thirdparty => thirdparty !== payload);
|
state.activity.thirdParties = state.activity.thirdParties.filter(
|
||||||
|
(thirdparty) => thirdparty !== payload,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'user':
|
case "user":
|
||||||
state.activity.users = state.activity.users.filter(user => user !== payload);
|
state.activity.users = state.activity.users.filter(
|
||||||
|
(user) => user !== payload,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
;
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Add CalendarRange object for an user
|
* Add CalendarRange object for an user
|
||||||
@ -131,13 +135,13 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const eventRanges = ranges
|
const eventRanges = ranges
|
||||||
.filter(r => !state.existingEvents.has(`range_${r.id}`))
|
.filter((r) => !state.existingEvents.has(`range_${r.id}`))
|
||||||
.map(r => {
|
.map((r) => {
|
||||||
// add to existing ids
|
// add to existing ids
|
||||||
state.existingEvents.add(`range_${r.id}`);
|
state.existingEvents.add(`range_${r.id}`);
|
||||||
return r;
|
return r;
|
||||||
})
|
})
|
||||||
.map(r => calendarRangeToFullCalendarEvent(r));
|
.map((r) => calendarRangeToFullCalendarEvent(r));
|
||||||
|
|
||||||
userData.calendarRanges = userData.calendarRanges.concat(eventRanges);
|
userData.calendarRanges = userData.calendarRanges.concat(eventRanges);
|
||||||
userData.calendarRangesLoaded.push({ start, end });
|
userData.calendarRangesLoaded.push({ start, end });
|
||||||
@ -152,13 +156,13 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const eventRemotes = remotes
|
const eventRemotes = remotes
|
||||||
.filter(r => !state.existingEvents.has(`remote_${r.id}`))
|
.filter((r) => !state.existingEvents.has(`remote_${r.id}`))
|
||||||
.map(r => {
|
.map((r) => {
|
||||||
// add to existing ids
|
// add to existing ids
|
||||||
state.existingEvents.add(`remote_${r.id}`);
|
state.existingEvents.add(`remote_${r.id}`);
|
||||||
return r;
|
return r;
|
||||||
})
|
})
|
||||||
.map(r => remoteToFullCalendarEvent(r));
|
.map((r) => remoteToFullCalendarEvent(r));
|
||||||
|
|
||||||
userData.remotes = userData.remotes.concat(eventRemotes);
|
userData.remotes = userData.remotes.concat(eventRemotes);
|
||||||
userData.remotesLoaded.push({ start, end });
|
userData.remotesLoaded.push({ start, end });
|
||||||
@ -173,20 +177,20 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const eventRemotes = locals
|
const eventRemotes = locals
|
||||||
.filter(r => !state.existingEvents.has(`locals_${r.id}`))
|
.filter((r) => !state.existingEvents.has(`locals_${r.id}`))
|
||||||
.map(r => {
|
.map((r) => {
|
||||||
// add to existing ids
|
// add to existing ids
|
||||||
state.existingEvents.add(`locals_${r.id}`);
|
state.existingEvents.add(`locals_${r.id}`);
|
||||||
return r;
|
return r;
|
||||||
})
|
})
|
||||||
.map(r => localsToFullCalendarEvent(r));
|
.map((r) => localsToFullCalendarEvent(r));
|
||||||
|
|
||||||
userData.locals = userData.locals.concat(eventRemotes);
|
userData.locals = userData.locals.concat(eventRemotes);
|
||||||
userData.localsLoaded.push({ start, end });
|
userData.localsLoaded.push({ start, end });
|
||||||
},
|
},
|
||||||
// Location
|
// Location
|
||||||
updateLocation(state, value) {
|
updateLocation(state, value) {
|
||||||
console.log('### mutation: updateLocation', value);
|
console.log("### mutation: updateLocation", value);
|
||||||
state.activity.location = value;
|
state.activity.location = value;
|
||||||
},
|
},
|
||||||
addAvailableLocationGroup(state, group) {
|
addAvailableLocationGroup(state, group) {
|
||||||
|
@ -1,32 +1,35 @@
|
|||||||
import {COLORS} from '../const';
|
import { COLORS } from "../const";
|
||||||
import {ISOToDatetime} from '../../../../../../ChillMainBundle/Resources/public/chill/js/date';
|
import { ISOToDatetime } from "../../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
||||||
import {DateTime, User} from '../../../../../../ChillMainBundle/Resources/public/types';
|
import {
|
||||||
import {CalendarLight, CalendarRange, CalendarRemote} from '../../../types';
|
DateTime,
|
||||||
import type {EventInputCalendarRange} from '../../../types';
|
User,
|
||||||
import {EventInput} from '@fullcalendar/core';
|
} from "../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
|
import { CalendarLight, CalendarRange, CalendarRemote } from "../../../types";
|
||||||
|
import type { EventInputCalendarRange } from "../../../types";
|
||||||
|
import { EventInput } from "@fullcalendar/core";
|
||||||
|
|
||||||
export interface UserData {
|
export interface UserData {
|
||||||
user: User,
|
user: User;
|
||||||
calendarRanges: CalendarRange[],
|
calendarRanges: CalendarRange[];
|
||||||
calendarRangesLoaded: {}[],
|
calendarRangesLoaded: {}[];
|
||||||
remotes: CalendarRemote[],
|
remotes: CalendarRemote[];
|
||||||
remotesLoaded: {}[],
|
remotesLoaded: {}[];
|
||||||
locals: CalendarRemote[],
|
locals: CalendarRemote[];
|
||||||
localsLoaded: {}[],
|
localsLoaded: {}[];
|
||||||
mainColor: string,
|
mainColor: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addIdToValue = (string: string, id: number): string => {
|
export const addIdToValue = (string: string, id: number): string => {
|
||||||
let array = string ? string.split(',') : [];
|
const array = string ? string.split(",") : [];
|
||||||
array.push(id.toString());
|
array.push(id.toString());
|
||||||
let str = array.join();
|
const str = array.join();
|
||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeIdFromValue = (string: string, id: number) => {
|
export const removeIdFromValue = (string: string, id: number) => {
|
||||||
let array = string.split(',');
|
let array = string.split(",");
|
||||||
array = array.filter(el => el !== id.toString());
|
array = array.filter((el) => el !== id.toString());
|
||||||
let str = array.join();
|
const str = array.join();
|
||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -34,7 +37,7 @@ export const removeIdFromValue = (string: string, id: number) => {
|
|||||||
* Assign missing keys for the ConcernedGroups component
|
* Assign missing keys for the ConcernedGroups component
|
||||||
*/
|
*/
|
||||||
export const mapEntity = (entity: EventInput): EventInput => {
|
export const mapEntity = (entity: EventInput): EventInput => {
|
||||||
let calendar = { ...entity};
|
const calendar = { ...entity };
|
||||||
Object.assign(calendar, { thirdParties: entity.professionals });
|
Object.assign(calendar, { thirdParties: entity.professionals });
|
||||||
|
|
||||||
if (entity.startDate !== null) {
|
if (entity.startDate !== null) {
|
||||||
@ -64,11 +67,13 @@ export const createUserData = (user: User, colorIndex: number): UserData => {
|
|||||||
locals: [],
|
locals: [],
|
||||||
localsLoaded: [],
|
localsLoaded: [],
|
||||||
mainColor: COLORS[colorId],
|
mainColor: COLORS[colorId],
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
// TODO move this function to a more global namespace, as it is also in use in MyCalendarRange app
|
// TODO move this function to a more global namespace, as it is also in use in MyCalendarRange app
|
||||||
export const calendarRangeToFullCalendarEvent = (entity: CalendarRange): EventInputCalendarRange => {
|
export const calendarRangeToFullCalendarEvent = (
|
||||||
|
entity: CalendarRange,
|
||||||
|
): EventInputCalendarRange => {
|
||||||
return {
|
return {
|
||||||
id: `range_${entity.id}`,
|
id: `range_${entity.id}`,
|
||||||
title: "(" + entity.user.text + ")",
|
title: "(" + entity.user.text + ")",
|
||||||
@ -80,29 +85,33 @@ export const calendarRangeToFullCalendarEvent = (entity: CalendarRange): EventIn
|
|||||||
calendarRangeId: entity.id,
|
calendarRangeId: entity.id,
|
||||||
locationId: entity.location.id,
|
locationId: entity.location.id,
|
||||||
locationName: entity.location.name,
|
locationName: entity.location.name,
|
||||||
is: 'range',
|
is: "range",
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export const remoteToFullCalendarEvent = (entity: CalendarRemote): EventInput & {id: string} => {
|
export const remoteToFullCalendarEvent = (
|
||||||
|
entity: CalendarRemote,
|
||||||
|
): EventInput & { id: string } => {
|
||||||
return {
|
return {
|
||||||
id: `range_${entity.id}`,
|
id: `range_${entity.id}`,
|
||||||
title: entity.title,
|
title: entity.title,
|
||||||
start: entity.startDate.datetime8601,
|
start: entity.startDate.datetime8601,
|
||||||
end: entity.endDate.datetime8601,
|
end: entity.endDate.datetime8601,
|
||||||
allDay: entity.isAllDay,
|
allDay: entity.isAllDay,
|
||||||
is: 'remote',
|
is: "remote",
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export const localsToFullCalendarEvent = (entity: CalendarLight): EventInput & {id: string; originId: number;} => {
|
export const localsToFullCalendarEvent = (
|
||||||
|
entity: CalendarLight,
|
||||||
|
): EventInput & { id: string; originId: number } => {
|
||||||
return {
|
return {
|
||||||
id: `local_${entity.id}`,
|
id: `local_${entity.id}`,
|
||||||
title: entity.persons.map(p => p.text).join(', '),
|
title: entity.persons.map((p) => p.text).join(", "),
|
||||||
originId: entity.id,
|
originId: entity.id,
|
||||||
start: entity.startDate.datetime8601,
|
start: entity.startDate.datetime8601,
|
||||||
end: entity.endDate.datetime8601,
|
end: entity.endDate.datetime8601,
|
||||||
allDay: false,
|
allDay: false,
|
||||||
is: 'local',
|
is: "local",
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
@ -1,50 +1,81 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<button id="btnGroupDrop1" type="button" class="btn btn-misc dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
<button
|
||||||
|
id="btnGroupDrop1"
|
||||||
|
type="button"
|
||||||
|
class="btn btn-misc dropdown-toggle"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
<template v-if="status === Statuses.PENDING">
|
<template v-if="status === Statuses.PENDING">
|
||||||
<span class="fa fa-hourglass"></span> {{ $t('Give_an_answer')}}
|
<span class="fa fa-hourglass"></span> {{ $t("Give_an_answer") }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="status === Statuses.ACCEPTED">
|
<template v-else-if="status === Statuses.ACCEPTED">
|
||||||
<span class="fa fa-check"></span> {{ $t('Accepted')}}
|
<span class="fa fa-check"></span> {{ $t("Accepted") }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="status === Statuses.DECLINED">
|
<template v-else-if="status === Statuses.DECLINED">
|
||||||
<span class="fa fa-times"></span> {{ $t('Declined')}}
|
<span class="fa fa-times"></span> {{ $t("Declined") }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="status === Statuses.TENTATIVELY_ACCEPTED">
|
<template v-else-if="status === Statuses.TENTATIVELY_ACCEPTED">
|
||||||
<span class="fa fa-question"></span> {{ $t('Tentative')}}
|
<span class="fa fa-question"></span> {{ $t("Tentative") }}
|
||||||
</template>
|
</template>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
||||||
<li v-if="status !== Statuses.ACCEPTED"><a class="dropdown-item" @click="changeStatus(Statuses.ACCEPTED)"><i class="fa fa-check" aria-hidden="true"></i> {{ $t('Accept') }}</a></li>
|
<li v-if="status !== Statuses.ACCEPTED">
|
||||||
<li v-if="status !== Statuses.DECLINED"><a class="dropdown-item" @click="changeStatus(Statuses.DECLINED)"><i class="fa fa-times" aria-hidden="true"></i> {{ $t('Decline') }}</a></li>
|
<a
|
||||||
<li v-if="status !== Statuses.TENTATIVELY_ACCEPTED"><a class="dropdown-item" @click="changeStatus(Statuses.TENTATIVELY_ACCEPTED)"><i class="fa fa-question"></i> {{ $t('Tentatively_accept') }}</a></li>
|
class="dropdown-item"
|
||||||
<li v-if="status !== Statuses.PENDING"><a class="dropdown-item" @click="changeStatus(Statuses.PENDING)"><i class="fa fa-hourglass-o"></i> {{ $t('Set_pending') }}</a></li>
|
@click="changeStatus(Statuses.ACCEPTED)"
|
||||||
|
><i class="fa fa-check" aria-hidden="true"></i>
|
||||||
|
{{ $t("Accept") }}</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li v-if="status !== Statuses.DECLINED">
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
@click="changeStatus(Statuses.DECLINED)"
|
||||||
|
><i class="fa fa-times" aria-hidden="true"></i>
|
||||||
|
{{ $t("Decline") }}</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li v-if="status !== Statuses.TENTATIVELY_ACCEPTED">
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
@click="changeStatus(Statuses.TENTATIVELY_ACCEPTED)"
|
||||||
|
><i class="fa fa-question"></i>
|
||||||
|
{{ $t("Tentatively_accept") }}</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li v-if="status !== Statuses.PENDING">
|
||||||
|
<a class="dropdown-item" @click="changeStatus(Statuses.PENDING)"
|
||||||
|
><i class="fa fa-hourglass-o"></i>
|
||||||
|
{{ $t("Set_pending") }}</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {defineComponent, PropType} from 'vue';
|
import { defineComponent, PropType } from "vue";
|
||||||
|
|
||||||
const ACCEPTED = 'accepted';
|
const ACCEPTED = "accepted";
|
||||||
const DECLINED = 'declined';
|
const DECLINED = "declined";
|
||||||
const PENDING = 'pending';
|
const PENDING = "pending";
|
||||||
const TENTATIVELY_ACCEPTED = 'tentative';
|
const TENTATIVELY_ACCEPTED = "tentative";
|
||||||
|
|
||||||
const i18n = {
|
const i18n = {
|
||||||
messages: {
|
messages: {
|
||||||
fr: {
|
fr: {
|
||||||
"Give_an_answer": "Répondre",
|
Give_an_answer: "Répondre",
|
||||||
"Accepted": "Accepté",
|
Accepted: "Accepté",
|
||||||
"Declined": "Refusé",
|
Declined: "Refusé",
|
||||||
"Tentative": "Accepté provisoirement",
|
Tentative: "Accepté provisoirement",
|
||||||
"Accept": "Accepter",
|
Accept: "Accepter",
|
||||||
"Decline": "Refuser",
|
Decline: "Refuser",
|
||||||
"Tentatively_accept": "Accepter provisoirement",
|
Tentatively_accept: "Accepter provisoirement",
|
||||||
"Set_pending": "Ne pas répondre",
|
Set_pending: "Ne pas répondre",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@ -52,10 +83,17 @@ export default defineComponent({
|
|||||||
i18n,
|
i18n,
|
||||||
props: {
|
props: {
|
||||||
calendarId: { type: Number, required: true },
|
calendarId: { type: Number, required: true },
|
||||||
status: {type: String as PropType<"accepted" | "declined" | "pending" | "tentative">, required: true},
|
status: {
|
||||||
|
type: String as PropType<
|
||||||
|
"accepted" | "declined" | "pending" | "tentative"
|
||||||
|
>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
statusChanged(payload: "accepted" | "declined" | "pending" | "tentative") {
|
statusChanged(
|
||||||
|
payload: "accepted" | "declined" | "pending" | "tentative",
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -67,29 +105,29 @@ export default defineComponent({
|
|||||||
PENDING,
|
PENDING,
|
||||||
TENTATIVELY_ACCEPTED,
|
TENTATIVELY_ACCEPTED,
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeStatus: function (newStatus: "accepted" | "declined" | "pending" | "tentative") {
|
changeStatus: function (
|
||||||
console.log('changeStatus', newStatus);
|
newStatus: "accepted" | "declined" | "pending" | "tentative",
|
||||||
|
) {
|
||||||
|
console.log("changeStatus", newStatus);
|
||||||
const url = `/api/1.0/calendar/calendar/${this.$props.calendarId}/answer/${newStatus}.json`;
|
const url = `/api/1.0/calendar/calendar/${this.$props.calendarId}/answer/${newStatus}.json`;
|
||||||
window.fetch(url, {
|
window
|
||||||
method: 'POST',
|
.fetch(url, {
|
||||||
}).then((r: Response) => {
|
method: "POST",
|
||||||
|
})
|
||||||
|
.then((r: Response) => {
|
||||||
if (!r.ok) {
|
if (!r.ok) {
|
||||||
console.error('could not confirm answer', newStatus);
|
console.error("could not confirm answer", newStatus);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('answer sent', newStatus);
|
console.log("answer sent", newStatus);
|
||||||
this.$emit('statusChanged', newStatus);
|
this.$emit("statusChanged", newStatus);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
@ -23,14 +23,22 @@
|
|||||||
<label class="input-group-text" for="slotDuration"
|
<label class="input-group-text" for="slotDuration"
|
||||||
>Durée des créneaux</label
|
>Durée des créneaux</label
|
||||||
>
|
>
|
||||||
<select v-model="slotDuration" id="slotDuration" class="form-select">
|
<select
|
||||||
|
v-model="slotDuration"
|
||||||
|
id="slotDuration"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
<option value="00:05:00">5 minutes</option>
|
<option value="00:05:00">5 minutes</option>
|
||||||
<option value="00:10:00">10 minutes</option>
|
<option value="00:10:00">10 minutes</option>
|
||||||
<option value="00:15:00">15 minutes</option>
|
<option value="00:15:00">15 minutes</option>
|
||||||
<option value="00:30:00">30 minutes</option>
|
<option value="00:30:00">30 minutes</option>
|
||||||
</select>
|
</select>
|
||||||
<label class="input-group-text" for="slotMinTime">De</label>
|
<label class="input-group-text" for="slotMinTime">De</label>
|
||||||
<select v-model="slotMinTime" id="slotMinTime" class="form-select">
|
<select
|
||||||
|
v-model="slotMinTime"
|
||||||
|
id="slotMinTime"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
<option value="00:00:00">0h</option>
|
<option value="00:00:00">0h</option>
|
||||||
<option value="01:00:00">1h</option>
|
<option value="01:00:00">1h</option>
|
||||||
<option value="02:00:00">2h</option>
|
<option value="02:00:00">2h</option>
|
||||||
@ -46,7 +54,11 @@
|
|||||||
<option value="12:00:00">12h</option>
|
<option value="12:00:00">12h</option>
|
||||||
</select>
|
</select>
|
||||||
<label class="input-group-text" for="slotMaxTime">À</label>
|
<label class="input-group-text" for="slotMaxTime">À</label>
|
||||||
<select v-model="slotMaxTime" id="slotMaxTime" class="form-select">
|
<select
|
||||||
|
v-model="slotMaxTime"
|
||||||
|
id="slotMaxTime"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
<option value="12:00:00">12h</option>
|
<option value="12:00:00">12h</option>
|
||||||
<option value="13:00:00">13h</option>
|
<option value="13:00:00">13h</option>
|
||||||
<option value="14:00:00">14h</option>
|
<option value="14:00:00">14h</option>
|
||||||
@ -74,7 +86,9 @@
|
|||||||
v-model="showWeekends"
|
v-model="showWeekends"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<label for="showHideWE" class="form-check-label input-group-text"
|
<label
|
||||||
|
for="showHideWE"
|
||||||
|
class="form-check-label input-group-text"
|
||||||
>Week-ends</label
|
>Week-ends</label
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -88,7 +102,8 @@
|
|||||||
arg.event.title
|
arg.event.title
|
||||||
}}</b>
|
}}</b>
|
||||||
<b v-else-if="arg.event.extendedProps.is === 'range'"
|
<b v-else-if="arg.event.extendedProps.is === 'range'"
|
||||||
>{{ arg.timeText }} - {{ arg.event.extendedProps.locationName }}</b
|
>{{ arg.timeText }} -
|
||||||
|
{{ arg.event.extendedProps.locationName }}</b
|
||||||
>
|
>
|
||||||
<b v-else-if="arg.event.extendedProps.is === 'local'">{{
|
<b v-else-if="arg.event.extendedProps.is === 'local'">{{
|
||||||
arg.event.title
|
arg.event.title
|
||||||
@ -106,29 +121,45 @@
|
|||||||
|
|
||||||
<div id="copy-widget">
|
<div id="copy-widget">
|
||||||
<div class="container mt-2 mb-2">
|
<div class="container mt-2 mb-2">
|
||||||
|
|
||||||
<div class="row justify-content-between align-items-center mb-4">
|
<div class="row justify-content-between align-items-center mb-4">
|
||||||
<div class="col-xs-12 col-sm-3 col-md-2">
|
<div class="col-xs-12 col-sm-3 col-md-2">
|
||||||
<h6 class="chill-red">{{ $t("copy_range_from_to") }}</h6>
|
<h6 class="chill-red">{{ $t("copy_range_from_to") }}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-9 col-md-2">
|
<div class="col-xs-12 col-sm-9 col-md-2">
|
||||||
<select v-model="dayOrWeek" id="dayOrWeek" class="form-select">
|
<select
|
||||||
|
v-model="dayOrWeek"
|
||||||
|
id="dayOrWeek"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
<option value="day">{{ $t("from_day_to_day") }}</option>
|
<option value="day">{{ $t("from_day_to_day") }}</option>
|
||||||
<option value="week">{{ $t("from_week_to_week") }}</option>
|
<option value="week">
|
||||||
|
{{ $t("from_week_to_week") }}
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="dayOrWeek === 'day'">
|
<template v-if="dayOrWeek === 'day'">
|
||||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||||
<input class="form-control" type="date" v-model="copyFrom" />
|
<input
|
||||||
|
class="form-control"
|
||||||
|
type="date"
|
||||||
|
v-model="copyFrom"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-1 col-md-1 copy-chevron">
|
<div class="col-xs-12 col-sm-1 col-md-1 copy-chevron">
|
||||||
<i class="fa fa-angle-double-right"></i>
|
<i class="fa fa-angle-double-right"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||||
<input class="form-control" type="date" v-model="copyTo" />
|
<input
|
||||||
|
class="form-control"
|
||||||
|
type="date"
|
||||||
|
v-model="copyTo"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-5 col-md-1">
|
<div class="col-xs-12 col-sm-5 col-md-1">
|
||||||
<button class="btn btn-action float-end" @click="copyDay">
|
<button
|
||||||
|
class="btn btn-action float-end"
|
||||||
|
@click="copyDay"
|
||||||
|
>
|
||||||
{{ $t("copy_range") }}
|
{{ $t("copy_range") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -140,7 +171,11 @@
|
|||||||
id="copyFromWeek"
|
id="copyFromWeek"
|
||||||
class="form-select"
|
class="form-select"
|
||||||
>
|
>
|
||||||
<option v-for="w in lastWeeks" :value="w.value" :key="w.value">
|
<option
|
||||||
|
v-for="w in lastWeeks"
|
||||||
|
:value="w.value"
|
||||||
|
:key="w.value"
|
||||||
|
>
|
||||||
{{ w.text }}
|
{{ w.text }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
@ -149,21 +184,31 @@
|
|||||||
<i class="fa fa-angle-double-right"></i>
|
<i class="fa fa-angle-double-right"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||||
<select v-model="copyToWeek" id="copyToWeek" class="form-select">
|
<select
|
||||||
<option v-for="w in nextWeeks" :value="w.value" :key="w.value">
|
v-model="copyToWeek"
|
||||||
|
id="copyToWeek"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="w in nextWeeks"
|
||||||
|
:value="w.value"
|
||||||
|
:key="w.value"
|
||||||
|
>
|
||||||
{{ w.text }}
|
{{ w.text }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-5 col-md-1">
|
<div class="col-xs-12 col-sm-5 col-md-1">
|
||||||
<button class="btn btn-action float-end" @click="copyWeek">
|
<button
|
||||||
|
class="btn btn-action float-end"
|
||||||
|
@click="copyWeek"
|
||||||
|
>
|
||||||
{{ $t("copy_range") }}
|
{{ $t("copy_range") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- not directly seen, but include in a modal -->
|
<!-- not directly seen, but include in a modal -->
|
||||||
@ -224,7 +269,7 @@ interface Weeks {
|
|||||||
const getMonday = (week: number): Date => {
|
const getMonday = (week: number): Date => {
|
||||||
const lastMonday = new Date();
|
const lastMonday = new Date();
|
||||||
lastMonday.setDate(
|
lastMonday.setDate(
|
||||||
lastMonday.getDate() - ((lastMonday.getDay() + 6) % 7) + week * 7
|
lastMonday.getDate() - ((lastMonday.getDay() + 6) % 7) + week * 7,
|
||||||
);
|
);
|
||||||
return lastMonday;
|
return lastMonday;
|
||||||
};
|
};
|
||||||
@ -243,7 +288,7 @@ const lastWeeks = computed((): Weeks[] =>
|
|||||||
value: dateToISO(lastMonday),
|
value: dateToISO(lastMonday),
|
||||||
text: `Semaine du ${lastMonday.toLocaleDateString("fr-FR", dateOptions)}`,
|
text: `Semaine du ${lastMonday.toLocaleDateString("fr-FR", dateOptions)}`,
|
||||||
};
|
};
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const nextWeeks = computed((): Weeks[] =>
|
const nextWeeks = computed((): Weeks[] =>
|
||||||
@ -253,7 +298,7 @@ const nextWeeks = computed((): Weeks[] =>
|
|||||||
value: dateToISO(nextMonday),
|
value: dateToISO(nextMonday),
|
||||||
text: `Semaine du ${nextMonday.toLocaleDateString("fr-FR", dateOptions)}`,
|
text: `Semaine du ${nextMonday.toLocaleDateString("fr-FR", dateOptions)}`,
|
||||||
};
|
};
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const baseOptions = ref<CalendarOptions>({
|
const baseOptions = ref<CalendarOptions>({
|
||||||
@ -298,7 +343,9 @@ const pickedLocation = computed<Location | null>({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
set(newLocation: Location | null): void {
|
set(newLocation: Location | null): void {
|
||||||
store.commit("locations/setLocationPicked", newLocation, { root: true });
|
store.commit("locations/setLocationPicked", newLocation, {
|
||||||
|
root: true,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -354,7 +401,7 @@ function onDatesSet(event: DatesSetArg): void {
|
|||||||
function onDateSelect(event: DateSelectArg): void {
|
function onDateSelect(event: DateSelectArg): void {
|
||||||
if (null === pickedLocation.value) {
|
if (null === pickedLocation.value) {
|
||||||
window.alert(
|
window.alert(
|
||||||
"Indiquez une localisation avant de créer une période de disponibilité."
|
"Indiquez une localisation avant de créer une période de disponibilité.",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -376,7 +423,7 @@ function onClickDelete(event: EventApi): void {
|
|||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
"calendarRanges/deleteRange",
|
"calendarRanges/deleteRange",
|
||||||
event.extendedProps.calendarRangeId
|
event.extendedProps.calendarRangeId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<component :is="Teleport" to="body">
|
<component :is="Teleport" to="body">
|
||||||
<modal v-if="showModal"
|
<modal v-if="showModal" @close="closeModal">
|
||||||
@close="closeModal">
|
|
||||||
|
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<h3>{{ 'Modifier le lieu' }}</h3>
|
<h3>{{ "Modifier le lieu" }}</h3>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-slot:body>
|
<template v-slot:body>
|
||||||
<div>
|
<div></div>
|
||||||
|
|
||||||
</div>
|
|
||||||
<label>Localisation</label>
|
<label>Localisation</label>
|
||||||
<vue-multiselect v-model="location" :options="locations" :label="'name'" :track-by="'id'"></vue-multiselect>
|
<vue-multiselect
|
||||||
|
v-model="location"
|
||||||
|
:options="locations"
|
||||||
|
:label="'name'"
|
||||||
|
:track-by="'id'"
|
||||||
|
></vue-multiselect>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-slot:footer>
|
<template v-slot:footer>
|
||||||
<button class="btn btn-save" @click="saveAndClose">{{ 'Enregistrer' }}</button>
|
<button class="btn btn-save" @click="saveAndClose">
|
||||||
|
{{ "Enregistrer" }}
|
||||||
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</modal>
|
</modal>
|
||||||
</component>
|
</component>
|
||||||
</template>
|
</template>
|
||||||
@ -34,18 +36,11 @@ import VueMultiselect from "vue-multiselect";
|
|||||||
//import type {Teleport} from "vue";
|
//import type {Teleport} from "vue";
|
||||||
|
|
||||||
// see https://github.com/vuejs/core/issues/2855
|
// see https://github.com/vuejs/core/issues/2855
|
||||||
import {
|
import { Teleport as teleport_, TeleportProps, VNodeProps } from "vue";
|
||||||
Teleport as teleport_,
|
|
||||||
TeleportProps,
|
|
||||||
VNodeProps
|
|
||||||
} from 'vue'
|
|
||||||
|
|
||||||
const Teleport = teleport_ as {
|
|
||||||
new (): {
|
|
||||||
$props: VNodeProps & TeleportProps
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const Teleport = teleport_ as new () => {
|
||||||
|
$props: VNodeProps & TeleportProps;
|
||||||
|
};
|
||||||
|
|
||||||
const store = useStore(key);
|
const store = useStore(key);
|
||||||
|
|
||||||
@ -59,30 +54,36 @@ const locations = computed<Location[]>(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const startEdit = function (event: EventApi): void {
|
const startEdit = function (event: EventApi): void {
|
||||||
console.log('startEditing', event);
|
console.log("startEditing", event);
|
||||||
calendarRangeId.value = event.extendedProps.calendarRangeId;
|
calendarRangeId.value = event.extendedProps.calendarRangeId;
|
||||||
location.value = store.getters['locations/getLocationById'](event.extendedProps.locationId) || null;
|
location.value =
|
||||||
|
store.getters["locations/getLocationById"](
|
||||||
|
event.extendedProps.locationId,
|
||||||
|
) || null;
|
||||||
|
|
||||||
console.log('new location value', location.value);
|
console.log("new location value", location.value);
|
||||||
console.log('calendar range id', calendarRangeId.value);
|
console.log("calendar range id", calendarRangeId.value);
|
||||||
showModal.value = true;
|
showModal.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
const saveAndClose = function (e: Event): void {
|
const saveAndClose = function (e: Event): void {
|
||||||
console.log('saveEditAndClose', e);
|
console.log("saveEditAndClose", e);
|
||||||
|
|
||||||
store.dispatch('calendarRanges/patchRangeLocation', {location: location.value, calendarRangeId: calendarRangeId.value})
|
store
|
||||||
.then(_ => {showModal.value = false;})
|
.dispatch("calendarRanges/patchRangeLocation", {
|
||||||
}
|
location: location.value,
|
||||||
|
calendarRangeId: calendarRangeId.value,
|
||||||
|
})
|
||||||
|
.then((_) => {
|
||||||
|
showModal.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const closeModal = function (_: any): void {
|
const closeModal = function (_: any): void {
|
||||||
showModal.value = false;
|
showModal.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
defineExpose({ startEdit });
|
defineExpose({ startEdit });
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -8,7 +8,8 @@ const appMessages = {
|
|||||||
copy_range_from_to: "Copier les plages",
|
copy_range_from_to: "Copier les plages",
|
||||||
from_day_to_day: "d'un jour à l'autre",
|
from_day_to_day: "d'un jour à l'autre",
|
||||||
from_week_to_week: "d'une semaine à l'autre",
|
from_week_to_week: "d'une semaine à l'autre",
|
||||||
copy_range_how_to: "Créez les plages de disponibilités durant une journée et copiez-les facilement au jour suivant avec ce bouton. Si les week-ends sont cachés, le jour suivant un vendredi sera le lundi.",
|
copy_range_how_to:
|
||||||
|
"Créez les plages de disponibilités durant une journée et copiez-les facilement au jour suivant avec ce bouton. Si les week-ends sont cachés, le jour suivant un vendredi sera le lundi.",
|
||||||
new_range_to_save: "Nouvelles plages à enregistrer",
|
new_range_to_save: "Nouvelles plages à enregistrer",
|
||||||
update_range_to_save: "Plages à modifier",
|
update_range_to_save: "Plages à modifier",
|
||||||
delete_range_to_save: "Plages à supprimer",
|
delete_range_to_save: "Plages à supprimer",
|
||||||
@ -20,9 +21,7 @@ const appMessages = {
|
|||||||
week: "Semaine",
|
week: "Semaine",
|
||||||
month: "Mois",
|
month: "Mois",
|
||||||
today: "Aujourd'hui",
|
today: "Aujourd'hui",
|
||||||
}
|
},
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
appMessages
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export { appMessages };
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { createApp } from 'vue';
|
import { createApp } from "vue";
|
||||||
import { _createI18n } from '../../../../../ChillMainBundle/Resources/public/vuejs/_js/i18n'
|
import { _createI18n } from "../../../../../ChillMainBundle/Resources/public/vuejs/_js/i18n";
|
||||||
import { appMessages } from './i18n'
|
import { appMessages } from "./i18n";
|
||||||
import futureStore, {key} from './store/index'
|
import futureStore, { key } from "./store/index";
|
||||||
|
|
||||||
import App2 from './App2.vue';
|
import App2 from "./App2.vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
futureStore().then((store) => {
|
futureStore().then((store) => {
|
||||||
@ -14,6 +14,6 @@ futureStore().then((store) => {
|
|||||||
})
|
})
|
||||||
.use(store, key)
|
.use(store, key)
|
||||||
.use(i18n)
|
.use(i18n)
|
||||||
.component('app', App2)
|
.component("app", App2)
|
||||||
.mount('#myCalendar');
|
.mount("#myCalendar");
|
||||||
});
|
});
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
import 'es6-promise/auto';
|
import "es6-promise/auto";
|
||||||
import {Store, createStore} from 'vuex';
|
import { Store, createStore } from "vuex";
|
||||||
import { InjectionKey } from "vue";
|
import { InjectionKey } from "vue";
|
||||||
import me, {MeState} from './modules/me';
|
import me, { MeState } from "./modules/me";
|
||||||
import fullCalendar, {FullCalendarState} from './modules/fullcalendar';
|
import fullCalendar, { FullCalendarState } from "./modules/fullcalendar";
|
||||||
import calendarRanges, {CalendarRangesState} from './modules/calendarRanges';
|
import calendarRanges, { CalendarRangesState } from "./modules/calendarRanges";
|
||||||
import calendarRemotes, {CalendarRemotesState} from './modules/calendarRemotes';
|
import calendarRemotes, {
|
||||||
|
CalendarRemotesState,
|
||||||
|
} from "./modules/calendarRemotes";
|
||||||
import { whoami } from "../../../../../../ChillMainBundle/Resources/public/lib/api/user";
|
import { whoami } from "../../../../../../ChillMainBundle/Resources/public/lib/api/user";
|
||||||
import {User} from '../../../../../../ChillMainBundle/Resources/public/types';
|
import { User } from "../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
import locations, { LocationState } from "./modules/location";
|
import locations, { LocationState } from "./modules/location";
|
||||||
import calendarLocals, { CalendarLocalsState } from "./modules/calendarLocals";
|
import calendarLocals, { CalendarLocalsState } from "./modules/calendarLocals";
|
||||||
|
|
||||||
const debug = process.env.NODE_ENV !== 'production';
|
const debug = process.env.NODE_ENV !== "production";
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
calendarRanges: CalendarRangesState,
|
calendarRanges: CalendarRangesState;
|
||||||
calendarRemotes: CalendarRemotesState,
|
calendarRemotes: CalendarRemotesState;
|
||||||
calendarLocals: CalendarLocalsState,
|
calendarLocals: CalendarLocalsState;
|
||||||
fullCalendar: FullCalendarState,
|
fullCalendar: FullCalendarState;
|
||||||
me: MeState,
|
me: MeState;
|
||||||
locations: LocationState
|
locations: LocationState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const key: InjectionKey<Store<State>> = Symbol();
|
export const key: InjectionKey<Store<State>> = Symbol();
|
||||||
@ -35,16 +37,20 @@ const futureStore = function(): Promise<Store<State>> {
|
|||||||
calendarLocals,
|
calendarLocals,
|
||||||
locations,
|
locations,
|
||||||
},
|
},
|
||||||
mutations: {}
|
mutations: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
store.commit('me/setWhoAmi', user, {root: true});
|
store.commit("me/setWhoAmi", user, { root: true });
|
||||||
store.dispatch('locations/getLocations', null, {root: true}).then(_ => {
|
store
|
||||||
return store.dispatch('locations/getCurrentLocation', null, {root: true});
|
.dispatch("locations/getLocations", null, { root: true })
|
||||||
|
.then((_) => {
|
||||||
|
return store.dispatch("locations/getCurrentLocation", null, {
|
||||||
|
root: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.resolve(store);
|
return Promise.resolve(store);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export default futureStore;
|
export default futureStore;
|
||||||
|
@ -1,33 +1,38 @@
|
|||||||
import {State} from './../index';
|
import { State } from "./../index";
|
||||||
import {ActionContext, Module} from 'vuex';
|
import { ActionContext, Module } from "vuex";
|
||||||
import {CalendarLight} from '../../../../types';
|
import { CalendarLight } from "../../../../types";
|
||||||
import {fetchCalendarLocalForUser} from '../../../Calendar/api';
|
import { fetchCalendarLocalForUser } from "../../../Calendar/api";
|
||||||
import {EventInput} from '@fullcalendar/core';
|
import { EventInput } from "@fullcalendar/core";
|
||||||
import { localsToFullCalendarEvent } from "../../../Calendar/store/utils";
|
import { localsToFullCalendarEvent } from "../../../Calendar/store/utils";
|
||||||
import { TransportExceptionInterface } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
import { TransportExceptionInterface } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||||
import { COLORS } from "../../../Calendar/const";
|
import { COLORS } from "../../../Calendar/const";
|
||||||
|
|
||||||
export interface CalendarLocalsState {
|
export interface CalendarLocalsState {
|
||||||
locals: EventInput[],
|
locals: EventInput[];
|
||||||
localsLoaded: {start: number, end: number}[],
|
localsLoaded: { start: number; end: number }[];
|
||||||
localsIndex: Set<string>,
|
localsIndex: Set<string>;
|
||||||
key: number
|
key: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Context = ActionContext<CalendarLocalsState, State>;
|
type Context = ActionContext<CalendarLocalsState, State>;
|
||||||
|
|
||||||
export default <Module<CalendarLocalsState, State>> {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): CalendarLocalsState => ({
|
state: (): CalendarLocalsState => ({
|
||||||
locals: [],
|
locals: [],
|
||||||
localsLoaded: [],
|
localsLoaded: [],
|
||||||
localsIndex: new Set<string>(),
|
localsIndex: new Set<string>(),
|
||||||
key: 0
|
key: 0,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
isLocalsLoaded: (state: CalendarLocalsState) => ({start, end}: {start: Date, end: Date}): boolean => {
|
isLocalsLoaded:
|
||||||
for (let range of state.localsLoaded) {
|
(state: CalendarLocalsState) =>
|
||||||
if (start.getTime() === range.start && end.getTime() === range.end) {
|
({ start, end }: { start: Date; end: Date }): boolean => {
|
||||||
|
for (const range of state.localsLoaded) {
|
||||||
|
if (
|
||||||
|
start.getTime() === range.start &&
|
||||||
|
end.getTime() === range.end
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,11 +42,11 @@ export default <Module<CalendarLocalsState, State>> {
|
|||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
addLocals(state: CalendarLocalsState, ranges: CalendarLight[]) {
|
addLocals(state: CalendarLocalsState, ranges: CalendarLight[]) {
|
||||||
console.log('addLocals', ranges);
|
console.log("addLocals", ranges);
|
||||||
|
|
||||||
const toAdd = ranges
|
const toAdd = ranges
|
||||||
.map(cr => localsToFullCalendarEvent(cr))
|
.map((cr) => localsToFullCalendarEvent(cr))
|
||||||
.filter(r => !state.localsIndex.has(r.id));
|
.filter((r) => !state.localsIndex.has(r.id));
|
||||||
|
|
||||||
toAdd.forEach((r) => {
|
toAdd.forEach((r) => {
|
||||||
state.localsIndex.add(r.id);
|
state.localsIndex.add(r.id);
|
||||||
@ -49,16 +54,25 @@ export default <Module<CalendarLocalsState, State>> {
|
|||||||
});
|
});
|
||||||
state.key = state.key + toAdd.length;
|
state.key = state.key + toAdd.length;
|
||||||
},
|
},
|
||||||
addLoaded(state: CalendarLocalsState, payload: {start: Date, end: Date}) {
|
addLoaded(
|
||||||
state.localsLoaded.push({start: payload.start.getTime(), end: payload.end.getTime()});
|
state: CalendarLocalsState,
|
||||||
|
payload: { start: Date; end: Date },
|
||||||
|
) {
|
||||||
|
state.localsLoaded.push({
|
||||||
|
start: payload.start.getTime(),
|
||||||
|
end: payload.end.getTime(),
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
fetchLocals(ctx: Context, payload: {start: Date, end: Date}): Promise<null> {
|
fetchLocals(
|
||||||
|
ctx: Context,
|
||||||
|
payload: { start: Date; end: Date },
|
||||||
|
): Promise<null> {
|
||||||
const start = payload.start;
|
const start = payload.start;
|
||||||
const end = payload.end;
|
const end = payload.end;
|
||||||
|
|
||||||
if (ctx.rootGetters['me/getMe'] === null) {
|
if (ctx.rootGetters["me/getMe"] === null) {
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,23 +80,30 @@ export default <Module<CalendarLocalsState, State>> {
|
|||||||
return Promise.resolve(ctx.getters.getRangeSource);
|
return Promise.resolve(ctx.getters.getRangeSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.commit('addLoaded', {
|
ctx.commit("addLoaded", {
|
||||||
start: start,
|
start: start,
|
||||||
end: end,
|
end: end,
|
||||||
});
|
});
|
||||||
|
|
||||||
return fetchCalendarLocalForUser(
|
return fetchCalendarLocalForUser(
|
||||||
ctx.rootGetters['me/getMe'],
|
ctx.rootGetters["me/getMe"],
|
||||||
start,
|
start,
|
||||||
end
|
end,
|
||||||
)
|
)
|
||||||
.then((remotes: CalendarLight[]) => {
|
.then((remotes: CalendarLight[]) => {
|
||||||
// to be add when reactivity problem will be solve ?
|
// to be add when reactivity problem will be solve ?
|
||||||
//ctx.commit('addRemotes', remotes);
|
//ctx.commit('addRemotes', remotes);
|
||||||
const inputs = remotes
|
const inputs = remotes
|
||||||
.map(cr => localsToFullCalendarEvent(cr))
|
.map((cr) => localsToFullCalendarEvent(cr))
|
||||||
.map(cr => ({...cr, backgroundColor: COLORS[0], textColor: 'black', editable: false}))
|
.map((cr) => ({
|
||||||
ctx.commit('calendarRanges/addExternals', inputs, {root: true});
|
...cr,
|
||||||
|
backgroundColor: COLORS[0],
|
||||||
|
textColor: "black",
|
||||||
|
editable: false,
|
||||||
|
}));
|
||||||
|
ctx.commit("calendarRanges/addExternals", inputs, {
|
||||||
|
root: true,
|
||||||
|
});
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
})
|
})
|
||||||
.catch((e: TransportExceptionInterface) => {
|
.catch((e: TransportExceptionInterface) => {
|
||||||
@ -90,6 +111,6 @@ export default <Module<CalendarLocalsState, State>> {
|
|||||||
|
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
} as Module<CalendarLocalsState, State>;
|
||||||
|
@ -1,52 +1,65 @@
|
|||||||
import {State} from './../index';
|
import { State } from "./../index";
|
||||||
import {ActionContext, Module} from 'vuex';
|
import { ActionContext, Module } from "vuex";
|
||||||
import {CalendarRange, CalendarRangeCreate, CalendarRangeEdit, isEventInputCalendarRange} from "../../../../types";
|
import {
|
||||||
|
CalendarRange,
|
||||||
|
CalendarRangeCreate,
|
||||||
|
CalendarRangeEdit,
|
||||||
|
isEventInputCalendarRange,
|
||||||
|
} from "../../../../types";
|
||||||
import { Location } from "../../../../../../../ChillMainBundle/Resources/public/types";
|
import { Location } from "../../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
import {fetchCalendarRangeForUser} from '../../../Calendar/api';
|
import { fetchCalendarRangeForUser } from "../../../Calendar/api";
|
||||||
import {calendarRangeToFullCalendarEvent} from '../../../Calendar/store/utils';
|
import { calendarRangeToFullCalendarEvent } from "../../../Calendar/store/utils";
|
||||||
import {EventInput} from '@fullcalendar/core';
|
import { EventInput } from "@fullcalendar/core";
|
||||||
import { makeFetch } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
import { makeFetch } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||||
import {
|
import {
|
||||||
datetimeToISO,
|
datetimeToISO,
|
||||||
dateToISO,
|
dateToISO,
|
||||||
ISOToDatetime
|
ISOToDatetime,
|
||||||
} from "../../../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
} from "../../../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
||||||
import type { EventInputCalendarRange } from "../../../../types";
|
import type { EventInputCalendarRange } from "../../../../types";
|
||||||
|
|
||||||
export interface CalendarRangesState {
|
export interface CalendarRangesState {
|
||||||
ranges: (EventInput | EventInputCalendarRange) [],
|
ranges: (EventInput | EventInputCalendarRange)[];
|
||||||
rangesLoaded: { start: number, end: number }[],
|
rangesLoaded: { start: number; end: number }[];
|
||||||
rangesIndex: Set<string>,
|
rangesIndex: Set<string>;
|
||||||
key: number
|
key: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Context = ActionContext<CalendarRangesState, State>;
|
type Context = ActionContext<CalendarRangesState, State>;
|
||||||
|
|
||||||
export default <Module<CalendarRangesState, State>>{
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): CalendarRangesState => ({
|
state: (): CalendarRangesState => ({
|
||||||
ranges: [],
|
ranges: [],
|
||||||
rangesLoaded: [],
|
rangesLoaded: [],
|
||||||
rangesIndex: new Set<string>(),
|
rangesIndex: new Set<string>(),
|
||||||
key: 0
|
key: 0,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
isRangeLoaded: (state: CalendarRangesState) => ({start, end}: { start: Date, end: Date }): boolean => {
|
isRangeLoaded:
|
||||||
for (let range of state.rangesLoaded) {
|
(state: CalendarRangesState) =>
|
||||||
if (start.getTime() === range.start && end.getTime() === range.end) {
|
({ start, end }: { start: Date; end: Date }): boolean => {
|
||||||
|
for (const range of state.rangesLoaded) {
|
||||||
|
if (
|
||||||
|
start.getTime() === range.start &&
|
||||||
|
end.getTime() === range.end
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
getRangesOnDate: (state: CalendarRangesState) => (date: Date): EventInputCalendarRange[] => {
|
getRangesOnDate:
|
||||||
|
(state: CalendarRangesState) =>
|
||||||
|
(date: Date): EventInputCalendarRange[] => {
|
||||||
const founds = [];
|
const founds = [];
|
||||||
const dateStr = <string>dateToISO(date);
|
const dateStr = dateToISO(date) as string;
|
||||||
|
|
||||||
for (let range of state.ranges) {
|
for (const range of state.ranges) {
|
||||||
if (isEventInputCalendarRange(range)
|
if (
|
||||||
&& range.start.startsWith(dateStr)
|
isEventInputCalendarRange(range) &&
|
||||||
|
range.start.startsWith(dateStr)
|
||||||
) {
|
) {
|
||||||
founds.push(range);
|
founds.push(range);
|
||||||
}
|
}
|
||||||
@ -54,15 +67,18 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
|
|
||||||
return founds;
|
return founds;
|
||||||
},
|
},
|
||||||
getRangesOnWeek: (state: CalendarRangesState) => (mondayDate: Date): EventInputCalendarRange[] => {
|
getRangesOnWeek:
|
||||||
|
(state: CalendarRangesState) =>
|
||||||
|
(mondayDate: Date): EventInputCalendarRange[] => {
|
||||||
const founds = [];
|
const founds = [];
|
||||||
for (let d of Array.from(Array(7).keys())) {
|
for (const d of Array.from(Array(7).keys())) {
|
||||||
const dateOfWeek = new Date(mondayDate);
|
const dateOfWeek = new Date(mondayDate);
|
||||||
dateOfWeek.setDate(mondayDate.getDate() + d);
|
dateOfWeek.setDate(mondayDate.getDate() + d);
|
||||||
const dateStr = <string>dateToISO(dateOfWeek);
|
const dateStr = dateToISO(dateOfWeek) as string;
|
||||||
for (let range of state.ranges) {
|
for (const range of state.ranges) {
|
||||||
if (isEventInputCalendarRange(range)
|
if (
|
||||||
&& range.start.startsWith(dateStr)
|
isEventInputCalendarRange(range) &&
|
||||||
|
range.start.startsWith(dateStr)
|
||||||
) {
|
) {
|
||||||
founds.push(range);
|
founds.push(range);
|
||||||
}
|
}
|
||||||
@ -75,12 +91,14 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
mutations: {
|
mutations: {
|
||||||
addRanges(state: CalendarRangesState, ranges: CalendarRange[]) {
|
addRanges(state: CalendarRangesState, ranges: CalendarRange[]) {
|
||||||
const toAdd = ranges
|
const toAdd = ranges
|
||||||
.map(cr => calendarRangeToFullCalendarEvent(cr))
|
.map((cr) => calendarRangeToFullCalendarEvent(cr))
|
||||||
.map(cr => ({
|
.map((cr) => ({
|
||||||
...cr, backgroundColor: 'white', borderColor: '#3788d8',
|
...cr,
|
||||||
textColor: 'black'
|
backgroundColor: "white",
|
||||||
|
borderColor: "#3788d8",
|
||||||
|
textColor: "black",
|
||||||
}))
|
}))
|
||||||
.filter(r => !state.rangesIndex.has(r.id));
|
.filter((r) => !state.rangesIndex.has(r.id));
|
||||||
|
|
||||||
toAdd.forEach((r) => {
|
toAdd.forEach((r) => {
|
||||||
state.rangesIndex.add(r.id);
|
state.rangesIndex.add(r.id);
|
||||||
@ -89,8 +107,9 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
state.key = state.key + toAdd.length;
|
state.key = state.key + toAdd.length;
|
||||||
},
|
},
|
||||||
addExternals(state, externalEvents: (EventInput & { id: string })[]) {
|
addExternals(state, externalEvents: (EventInput & { id: string })[]) {
|
||||||
const toAdd = externalEvents
|
const toAdd = externalEvents.filter(
|
||||||
.filter(r => !state.rangesIndex.has(r.id));
|
(r) => !state.rangesIndex.has(r.id),
|
||||||
|
);
|
||||||
|
|
||||||
toAdd.forEach((r) => {
|
toAdd.forEach((r) => {
|
||||||
state.rangesIndex.add(r.id);
|
state.rangesIndex.add(r.id);
|
||||||
@ -98,24 +117,43 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
});
|
});
|
||||||
state.key = state.key + toAdd.length;
|
state.key = state.key + toAdd.length;
|
||||||
},
|
},
|
||||||
addLoaded(state: CalendarRangesState, payload: { start: Date, end: Date }) {
|
addLoaded(
|
||||||
state.rangesLoaded.push({start: payload.start.getTime(), end: payload.end.getTime()});
|
state: CalendarRangesState,
|
||||||
|
payload: { start: Date; end: Date },
|
||||||
|
) {
|
||||||
|
state.rangesLoaded.push({
|
||||||
|
start: payload.start.getTime(),
|
||||||
|
end: payload.end.getTime(),
|
||||||
|
});
|
||||||
},
|
},
|
||||||
addRange(state: CalendarRangesState, payload: CalendarRange) {
|
addRange(state: CalendarRangesState, payload: CalendarRange) {
|
||||||
const asEvent = calendarRangeToFullCalendarEvent(payload);
|
const asEvent = calendarRangeToFullCalendarEvent(payload);
|
||||||
state.ranges.push({...asEvent, backgroundColor: 'white', borderColor: '#3788d8', textColor: 'black'});
|
state.ranges.push({
|
||||||
|
...asEvent,
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderColor: "#3788d8",
|
||||||
|
textColor: "black",
|
||||||
|
});
|
||||||
state.rangesIndex.add(asEvent.id);
|
state.rangesIndex.add(asEvent.id);
|
||||||
state.key = state.key + 1;
|
state.key = state.key + 1;
|
||||||
},
|
},
|
||||||
removeRange(state: CalendarRangesState, calendarRangeId: number) {
|
removeRange(state: CalendarRangesState, calendarRangeId: number) {
|
||||||
const found = state.ranges.find(r => r.calendarRangeId === calendarRangeId && r.is === "range");
|
const found = state.ranges.find(
|
||||||
|
(r) =>
|
||||||
|
r.calendarRangeId === calendarRangeId && r.is === "range",
|
||||||
|
);
|
||||||
|
|
||||||
if (found !== undefined) {
|
if (found !== undefined) {
|
||||||
state.ranges = state.ranges.filter(
|
state.ranges = state.ranges.filter(
|
||||||
(r) => !(r.calendarRangeId === calendarRangeId && r.is === "range")
|
(r) =>
|
||||||
|
!(
|
||||||
|
r.calendarRangeId === calendarRangeId &&
|
||||||
|
r.is === "range"
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (typeof found.id === "string") { // should always be true
|
if (typeof found.id === "string") {
|
||||||
|
// should always be true
|
||||||
state.rangesIndex.delete(found.id);
|
state.rangesIndex.delete(found.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +161,9 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateRange(state, range: CalendarRange) {
|
updateRange(state, range: CalendarRange) {
|
||||||
const found = state.ranges.find(r => r.calendarRangeId === range.id && r.is === "range");
|
const found = state.ranges.find(
|
||||||
|
(r) => r.calendarRangeId === range.id && r.is === "range",
|
||||||
|
);
|
||||||
const newEvent = calendarRangeToFullCalendarEvent(range);
|
const newEvent = calendarRangeToFullCalendarEvent(range);
|
||||||
|
|
||||||
if (found !== undefined) {
|
if (found !== undefined) {
|
||||||
@ -134,14 +174,17 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.key = state.key + 1;
|
state.key = state.key + 1;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
fetchRanges(ctx: Context, payload: { start: Date, end: Date }): Promise<null> {
|
fetchRanges(
|
||||||
|
ctx: Context,
|
||||||
|
payload: { start: Date; end: Date },
|
||||||
|
): Promise<null> {
|
||||||
const start = payload.start;
|
const start = payload.start;
|
||||||
const end = payload.end;
|
const end = payload.end;
|
||||||
|
|
||||||
if (ctx.rootGetters['me/getMe'] === null) {
|
if (ctx.rootGetters["me/getMe"] === null) {
|
||||||
return Promise.resolve(ctx.getters.getRangeSource);
|
return Promise.resolve(ctx.getters.getRangeSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,49 +192,58 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
return Promise.resolve(ctx.getters.getRangeSource);
|
return Promise.resolve(ctx.getters.getRangeSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.commit('addLoaded', {
|
ctx.commit("addLoaded", {
|
||||||
start: start,
|
start: start,
|
||||||
end: end,
|
end: end,
|
||||||
});
|
});
|
||||||
|
|
||||||
return fetchCalendarRangeForUser(
|
return fetchCalendarRangeForUser(
|
||||||
ctx.rootGetters['me/getMe'],
|
ctx.rootGetters["me/getMe"],
|
||||||
start,
|
start,
|
||||||
end
|
end,
|
||||||
)
|
).then((ranges: CalendarRange[]) => {
|
||||||
.then((ranges: CalendarRange[]) => {
|
ctx.commit("addRanges", ranges);
|
||||||
ctx.commit('addRanges', ranges);
|
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
createRange(ctx, {start, end, location}: { start: Date, end: Date, location: Location }): Promise<null> {
|
createRange(
|
||||||
|
ctx,
|
||||||
|
{
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
location,
|
||||||
|
}: { start: Date; end: Date; location: Location },
|
||||||
|
): Promise<null> {
|
||||||
const url = `/api/1.0/calendar/calendar-range.json?`;
|
const url = `/api/1.0/calendar/calendar-range.json?`;
|
||||||
|
|
||||||
if (ctx.rootState.me.me === null) {
|
if (ctx.rootState.me.me === null) {
|
||||||
throw new Error('user is currently null');
|
throw new Error("user is currently null");
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
user: {
|
user: {
|
||||||
id: ctx.rootState.me.me.id,
|
id: ctx.rootState.me.me.id,
|
||||||
type: "user"
|
type: "user",
|
||||||
},
|
},
|
||||||
startDate: {
|
startDate: {
|
||||||
datetime: datetimeToISO(start),
|
datetime: datetimeToISO(start),
|
||||||
},
|
},
|
||||||
endDate: {
|
endDate: {
|
||||||
datetime: datetimeToISO(end)
|
datetime: datetimeToISO(end),
|
||||||
},
|
},
|
||||||
location: {
|
location: {
|
||||||
id: location.id,
|
id: location.id,
|
||||||
type: "location"
|
type: "location",
|
||||||
}
|
},
|
||||||
} as CalendarRangeCreate;
|
} as CalendarRangeCreate;
|
||||||
|
|
||||||
return makeFetch<CalendarRangeCreate, CalendarRange>('POST', url, body)
|
return makeFetch<CalendarRangeCreate, CalendarRange>(
|
||||||
|
"POST",
|
||||||
|
url,
|
||||||
|
body,
|
||||||
|
)
|
||||||
.then((newRange) => {
|
.then((newRange) => {
|
||||||
|
ctx.commit("addRange", newRange);
|
||||||
ctx.commit('addRange', newRange);
|
|
||||||
|
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
})
|
})
|
||||||
@ -199,88 +251,127 @@ export default <Module<CalendarRangesState, State>>{
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
deleteRange(ctx, calendarRangeId: number) {
|
deleteRange(ctx, calendarRangeId: number) {
|
||||||
const url = `/api/1.0/calendar/calendar-range/${calendarRangeId}.json`;
|
const url = `/api/1.0/calendar/calendar-range/${calendarRangeId}.json`;
|
||||||
|
|
||||||
makeFetch<undefined, never>('DELETE', url)
|
makeFetch<undefined, never>("DELETE", url).then((_) => {
|
||||||
.then((_) => {
|
ctx.commit("removeRange", calendarRangeId);
|
||||||
ctx.commit('removeRange', calendarRangeId);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
patchRangeTime(ctx, {calendarRangeId, start, end}: {calendarRangeId: number, start: Date, end: Date}): Promise<null> {
|
patchRangeTime(
|
||||||
|
ctx,
|
||||||
|
{
|
||||||
|
calendarRangeId,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
}: { calendarRangeId: number; start: Date; end: Date },
|
||||||
|
): Promise<null> {
|
||||||
const url = `/api/1.0/calendar/calendar-range/${calendarRangeId}.json`;
|
const url = `/api/1.0/calendar/calendar-range/${calendarRangeId}.json`;
|
||||||
const body = {
|
const body = {
|
||||||
startDate: {
|
startDate: {
|
||||||
datetime: datetimeToISO(start)
|
datetime: datetimeToISO(start),
|
||||||
},
|
},
|
||||||
endDate: {
|
endDate: {
|
||||||
datetime: datetimeToISO(end)
|
datetime: datetimeToISO(end),
|
||||||
},
|
},
|
||||||
} as CalendarRangeEdit;
|
} as CalendarRangeEdit;
|
||||||
|
|
||||||
return makeFetch<CalendarRangeEdit, CalendarRange>('PATCH', url, body)
|
return makeFetch<CalendarRangeEdit, CalendarRange>(
|
||||||
|
"PATCH",
|
||||||
|
url,
|
||||||
|
body,
|
||||||
|
)
|
||||||
.then((range) => {
|
.then((range) => {
|
||||||
ctx.commit('updateRange', range);
|
ctx.commit("updateRange", range);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
patchRangeLocation(ctx, {location, calendarRangeId}: {location: Location, calendarRangeId: number}): Promise<null> {
|
patchRangeLocation(
|
||||||
|
ctx,
|
||||||
|
{
|
||||||
|
location,
|
||||||
|
calendarRangeId,
|
||||||
|
}: { location: Location; calendarRangeId: number },
|
||||||
|
): Promise<null> {
|
||||||
const url = `/api/1.0/calendar/calendar-range/${calendarRangeId}.json`;
|
const url = `/api/1.0/calendar/calendar-range/${calendarRangeId}.json`;
|
||||||
const body = {
|
const body = {
|
||||||
location: {
|
location: {
|
||||||
id: location.id,
|
id: location.id,
|
||||||
type: "location"
|
type: "location",
|
||||||
},
|
},
|
||||||
} as CalendarRangeEdit;
|
} as CalendarRangeEdit;
|
||||||
|
|
||||||
return makeFetch<CalendarRangeEdit, CalendarRange>('PATCH', url, body)
|
return makeFetch<CalendarRangeEdit, CalendarRange>(
|
||||||
|
"PATCH",
|
||||||
|
url,
|
||||||
|
body,
|
||||||
|
)
|
||||||
.then((range) => {
|
.then((range) => {
|
||||||
ctx.commit('updateRange', range);
|
ctx.commit("updateRange", range);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
copyFromDayToAnotherDay(ctx, {from, to}: {from: Date, to: Date}): Promise<null> {
|
copyFromDayToAnotherDay(
|
||||||
const rangesToCopy: EventInputCalendarRange[] = ctx.getters['getRangesOnDate'](from);
|
ctx,
|
||||||
|
{ from, to }: { from: Date; to: Date },
|
||||||
|
): Promise<null> {
|
||||||
|
const rangesToCopy: EventInputCalendarRange[] =
|
||||||
|
ctx.getters["getRangesOnDate"](from);
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
for (let r of rangesToCopy) {
|
for (const r of rangesToCopy) {
|
||||||
let start = new Date(<Date>ISOToDatetime(r.start));
|
const start = new Date(ISOToDatetime(r.start) as Date);
|
||||||
start.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
start.setFullYear(
|
||||||
let end = new Date(<Date>ISOToDatetime(r.end));
|
to.getFullYear(),
|
||||||
|
to.getMonth(),
|
||||||
|
to.getDate(),
|
||||||
|
);
|
||||||
|
const end = new Date(ISOToDatetime(r.end) as Date);
|
||||||
end.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
end.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
||||||
let location = ctx.rootGetters['locations/getLocationById'](r.locationId);
|
const location = ctx.rootGetters["locations/getLocationById"](
|
||||||
|
r.locationId,
|
||||||
|
);
|
||||||
|
|
||||||
promises.push(ctx.dispatch('createRange', {start, end, location}));
|
promises.push(
|
||||||
|
ctx.dispatch("createRange", { start, end, location }),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises).then(_ => Promise.resolve(null));
|
return Promise.all(promises).then((_) => Promise.resolve(null));
|
||||||
},
|
},
|
||||||
copyFromWeekToAnotherWeek(ctx, {fromMonday, toMonday}: {fromMonday: Date, toMonday: Date}): Promise<null> {
|
copyFromWeekToAnotherWeek(
|
||||||
|
ctx,
|
||||||
const rangesToCopy: EventInputCalendarRange[] = ctx.getters['getRangesOnWeek'](fromMonday);
|
{ fromMonday, toMonday }: { fromMonday: Date; toMonday: Date },
|
||||||
|
): Promise<null> {
|
||||||
|
const rangesToCopy: EventInputCalendarRange[] =
|
||||||
|
ctx.getters["getRangesOnWeek"](fromMonday);
|
||||||
const promises = [];
|
const promises = [];
|
||||||
const diffTime = toMonday.getTime() - fromMonday.getTime();
|
const diffTime = toMonday.getTime() - fromMonday.getTime();
|
||||||
for (let r of rangesToCopy) {
|
for (const r of rangesToCopy) {
|
||||||
let start = new Date(<Date>ISOToDatetime(r.start));
|
const start = new Date(ISOToDatetime(r.start) as Date);
|
||||||
let end = new Date(<Date>ISOToDatetime(r.end));
|
const end = new Date(ISOToDatetime(r.end) as Date);
|
||||||
start.setTime(start.getTime() + diffTime);
|
start.setTime(start.getTime() + diffTime);
|
||||||
end.setTime(end.getTime() + diffTime);
|
end.setTime(end.getTime() + diffTime);
|
||||||
let location = ctx.rootGetters['locations/getLocationById'](r.locationId);
|
const location = ctx.rootGetters["locations/getLocationById"](
|
||||||
|
r.locationId,
|
||||||
|
);
|
||||||
|
|
||||||
promises.push(ctx.dispatch('createRange', {start, end, location}));
|
promises.push(
|
||||||
|
ctx.dispatch("createRange", { start, end, location }),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises).then(_ => Promise.resolve(null));
|
return Promise.all(promises).then((_) => Promise.resolve(null));
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
} as Module<CalendarRangesState, State>;
|
||||||
|
@ -1,33 +1,38 @@
|
|||||||
import {State} from './../index';
|
import { State } from "./../index";
|
||||||
import {ActionContext, Module} from 'vuex';
|
import { ActionContext, Module } from "vuex";
|
||||||
import {CalendarRemote} from '../../../../types';
|
import { CalendarRemote } from "../../../../types";
|
||||||
import {fetchCalendarRemoteForUser} from '../../../Calendar/api';
|
import { fetchCalendarRemoteForUser } from "../../../Calendar/api";
|
||||||
import {EventInput} from '@fullcalendar/core';
|
import { EventInput } from "@fullcalendar/core";
|
||||||
import { remoteToFullCalendarEvent } from "../../../Calendar/store/utils";
|
import { remoteToFullCalendarEvent } from "../../../Calendar/store/utils";
|
||||||
import { TransportExceptionInterface } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
import { TransportExceptionInterface } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||||
import { COLORS } from "../../../Calendar/const";
|
import { COLORS } from "../../../Calendar/const";
|
||||||
|
|
||||||
export interface CalendarRemotesState {
|
export interface CalendarRemotesState {
|
||||||
remotes: EventInput[],
|
remotes: EventInput[];
|
||||||
remotesLoaded: {start: number, end: number}[],
|
remotesLoaded: { start: number; end: number }[];
|
||||||
remotesIndex: Set<string>,
|
remotesIndex: Set<string>;
|
||||||
key: number
|
key: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Context = ActionContext<CalendarRemotesState, State>;
|
type Context = ActionContext<CalendarRemotesState, State>;
|
||||||
|
|
||||||
export default <Module<CalendarRemotesState, State>> {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): CalendarRemotesState => ({
|
state: (): CalendarRemotesState => ({
|
||||||
remotes: [],
|
remotes: [],
|
||||||
remotesLoaded: [],
|
remotesLoaded: [],
|
||||||
remotesIndex: new Set<string>(),
|
remotesIndex: new Set<string>(),
|
||||||
key: 0
|
key: 0,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
isRemotesLoaded: (state: CalendarRemotesState) => ({start, end}: {start: Date, end: Date}): boolean => {
|
isRemotesLoaded:
|
||||||
for (let range of state.remotesLoaded) {
|
(state: CalendarRemotesState) =>
|
||||||
if (start.getTime() === range.start && end.getTime() === range.end) {
|
({ start, end }: { start: Date; end: Date }): boolean => {
|
||||||
|
for (const range of state.remotesLoaded) {
|
||||||
|
if (
|
||||||
|
start.getTime() === range.start &&
|
||||||
|
end.getTime() === range.end
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,11 +42,11 @@ export default <Module<CalendarRemotesState, State>> {
|
|||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
addRemotes(state: CalendarRemotesState, ranges: CalendarRemote[]) {
|
addRemotes(state: CalendarRemotesState, ranges: CalendarRemote[]) {
|
||||||
console.log('addRemotes', ranges);
|
console.log("addRemotes", ranges);
|
||||||
|
|
||||||
const toAdd = ranges
|
const toAdd = ranges
|
||||||
.map(cr => remoteToFullCalendarEvent(cr))
|
.map((cr) => remoteToFullCalendarEvent(cr))
|
||||||
.filter(r => !state.remotesIndex.has(r.id));
|
.filter((r) => !state.remotesIndex.has(r.id));
|
||||||
|
|
||||||
toAdd.forEach((r) => {
|
toAdd.forEach((r) => {
|
||||||
state.remotesIndex.add(r.id);
|
state.remotesIndex.add(r.id);
|
||||||
@ -49,16 +54,25 @@ export default <Module<CalendarRemotesState, State>> {
|
|||||||
});
|
});
|
||||||
state.key = state.key + toAdd.length;
|
state.key = state.key + toAdd.length;
|
||||||
},
|
},
|
||||||
addLoaded(state: CalendarRemotesState, payload: {start: Date, end: Date}) {
|
addLoaded(
|
||||||
state.remotesLoaded.push({start: payload.start.getTime(), end: payload.end.getTime()});
|
state: CalendarRemotesState,
|
||||||
|
payload: { start: Date; end: Date },
|
||||||
|
) {
|
||||||
|
state.remotesLoaded.push({
|
||||||
|
start: payload.start.getTime(),
|
||||||
|
end: payload.end.getTime(),
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
fetchRemotes(ctx: Context, payload: {start: Date, end: Date}): Promise<null> {
|
fetchRemotes(
|
||||||
|
ctx: Context,
|
||||||
|
payload: { start: Date; end: Date },
|
||||||
|
): Promise<null> {
|
||||||
const start = payload.start;
|
const start = payload.start;
|
||||||
const end = payload.end;
|
const end = payload.end;
|
||||||
|
|
||||||
if (ctx.rootGetters['me/getMe'] === null) {
|
if (ctx.rootGetters["me/getMe"] === null) {
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,23 +80,30 @@ export default <Module<CalendarRemotesState, State>> {
|
|||||||
return Promise.resolve(ctx.getters.getRangeSource);
|
return Promise.resolve(ctx.getters.getRangeSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.commit('addLoaded', {
|
ctx.commit("addLoaded", {
|
||||||
start: start,
|
start: start,
|
||||||
end: end,
|
end: end,
|
||||||
});
|
});
|
||||||
|
|
||||||
return fetchCalendarRemoteForUser(
|
return fetchCalendarRemoteForUser(
|
||||||
ctx.rootGetters['me/getMe'],
|
ctx.rootGetters["me/getMe"],
|
||||||
start,
|
start,
|
||||||
end
|
end,
|
||||||
)
|
)
|
||||||
.then((remotes: CalendarRemote[]) => {
|
.then((remotes: CalendarRemote[]) => {
|
||||||
// to be add when reactivity problem will be solve ?
|
// to be add when reactivity problem will be solve ?
|
||||||
//ctx.commit('addRemotes', remotes);
|
//ctx.commit('addRemotes', remotes);
|
||||||
const inputs = remotes
|
const inputs = remotes
|
||||||
.map(cr => remoteToFullCalendarEvent(cr))
|
.map((cr) => remoteToFullCalendarEvent(cr))
|
||||||
.map(cr => ({...cr, backgroundColor: COLORS[0], textColor: 'black', editable: false}))
|
.map((cr) => ({
|
||||||
ctx.commit('calendarRanges/addExternals', inputs, {root: true});
|
...cr,
|
||||||
|
backgroundColor: COLORS[0],
|
||||||
|
textColor: "black",
|
||||||
|
editable: false,
|
||||||
|
}));
|
||||||
|
ctx.commit("calendarRanges/addExternals", inputs, {
|
||||||
|
root: true,
|
||||||
|
});
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
})
|
})
|
||||||
.catch((e: TransportExceptionInterface) => {
|
.catch((e: TransportExceptionInterface) => {
|
||||||
@ -90,6 +111,6 @@ export default <Module<CalendarRemotesState, State>> {
|
|||||||
|
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
} as Module<CalendarRemotesState, State>;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import {State} from './../index';
|
import { State } from "./../index";
|
||||||
import {ActionContext} from 'vuex';
|
import { ActionContext } from "vuex";
|
||||||
|
|
||||||
export interface FullCalendarState {
|
export interface FullCalendarState {
|
||||||
currentView: {
|
currentView: {
|
||||||
start: Date|null,
|
start: Date | null;
|
||||||
end: Date|null,
|
end: Date | null;
|
||||||
},
|
};
|
||||||
key: number
|
key: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Context = ActionContext<FullCalendarState, State>;
|
type Context = ActionContext<FullCalendarState, State>;
|
||||||
@ -21,36 +21,58 @@ export default {
|
|||||||
key: 0,
|
key: 0,
|
||||||
}),
|
}),
|
||||||
mutations: {
|
mutations: {
|
||||||
setCurrentDatesView: function(state: FullCalendarState, payload: {start: Date, end: Date}): void {
|
setCurrentDatesView: function (
|
||||||
|
state: FullCalendarState,
|
||||||
|
payload: { start: Date; end: Date },
|
||||||
|
): void {
|
||||||
state.currentView.start = payload.start;
|
state.currentView.start = payload.start;
|
||||||
state.currentView.end = payload.end;
|
state.currentView.end = payload.end;
|
||||||
},
|
},
|
||||||
increaseKey: function (state: FullCalendarState): void {
|
increaseKey: function (state: FullCalendarState): void {
|
||||||
state.key = state.key + 1;
|
state.key = state.key + 1;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setCurrentDatesView(ctx: Context, {start, end}: {start: Date|null, end: Date|null}): Promise<null> {
|
setCurrentDatesView(
|
||||||
console.log('dispatch setCurrentDatesView', {start, end});
|
ctx: Context,
|
||||||
|
{ start, end }: { start: Date | null; end: Date | null },
|
||||||
|
): Promise<null> {
|
||||||
|
console.log("dispatch setCurrentDatesView", { start, end });
|
||||||
|
|
||||||
if (ctx.state.currentView.start !== start || ctx.state.currentView.end !== end) {
|
if (
|
||||||
ctx.commit('setCurrentDatesView', {start, end});
|
ctx.state.currentView.start !== start ||
|
||||||
|
ctx.state.currentView.end !== end
|
||||||
|
) {
|
||||||
|
ctx.commit("setCurrentDatesView", { start, end });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start !== null && end !== null) {
|
if (start !== null && end !== null) {
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
ctx.dispatch('calendarRanges/fetchRanges', {start, end}, {root: true}).then(_ => Promise.resolve(null)),
|
ctx
|
||||||
ctx.dispatch('calendarRemotes/fetchRemotes', {start, end}, {root: true}).then(_ => Promise.resolve(null)),
|
.dispatch(
|
||||||
ctx.dispatch('calendarLocals/fetchLocals', {start, end}, {root: true}).then(_ => Promise.resolve(null))
|
"calendarRanges/fetchRanges",
|
||||||
]
|
{ start, end },
|
||||||
).then(_ => Promise.resolve(null));
|
{ root: true },
|
||||||
|
)
|
||||||
|
.then((_) => Promise.resolve(null)),
|
||||||
|
ctx
|
||||||
|
.dispatch(
|
||||||
|
"calendarRemotes/fetchRemotes",
|
||||||
|
{ start, end },
|
||||||
|
{ root: true },
|
||||||
|
)
|
||||||
|
.then((_) => Promise.resolve(null)),
|
||||||
|
ctx
|
||||||
|
.dispatch(
|
||||||
|
"calendarLocals/fetchLocals",
|
||||||
|
{ start, end },
|
||||||
|
{ root: true },
|
||||||
|
)
|
||||||
|
.then((_) => Promise.resolve(null)),
|
||||||
|
]).then((_) => Promise.resolve(null));
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Location } from "../../../../../../../ChillMainBundle/Resources/public/types";
|
import { Location } from "../../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
import {State} from '../index';
|
import { State } from "../index";
|
||||||
import {Module} from 'vuex';
|
import { Module } from "vuex";
|
||||||
import { getLocations } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/locations";
|
import { getLocations } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/locations";
|
||||||
import { whereami } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/user";
|
import { whereami } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/user";
|
||||||
|
|
||||||
@ -10,18 +10,20 @@ export interface LocationState {
|
|||||||
currentLocation: Location | null;
|
currentLocation: Location | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default <Module<LocationState, State>>{
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: (): LocationState => {
|
state: (): LocationState => {
|
||||||
return {
|
return {
|
||||||
locations: [],
|
locations: [],
|
||||||
locationPicked: null,
|
locationPicked: null,
|
||||||
currentLocation: null,
|
currentLocation: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getLocationById: (state) => (id: number): Location|undefined => {
|
getLocationById:
|
||||||
return state.locations.find(l => l.id === id);
|
(state) =>
|
||||||
|
(id: number): Location | undefined => {
|
||||||
|
return state.locations.find((l) => l.id === id);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
@ -34,7 +36,8 @@ export default <Module<LocationState, State>>{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.locationPicked = state.locations.find(l => l.id === location.id) || null;
|
state.locationPicked =
|
||||||
|
state.locations.find((l) => l.id === location.id) || null;
|
||||||
},
|
},
|
||||||
setCurrentLocation(state, location: Location | null): void {
|
setCurrentLocation(state, location: Location | null): void {
|
||||||
if (null === location) {
|
if (null === location) {
|
||||||
@ -42,21 +45,21 @@ export default <Module<LocationState, State>>{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.currentLocation = state.locations.find(l => l.id === location.id) || null;
|
state.currentLocation =
|
||||||
}
|
state.locations.find((l) => l.id === location.id) || null;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
getLocations(ctx): Promise<void> {
|
getLocations(ctx): Promise<void> {
|
||||||
return getLocations().then(locations => {
|
return getLocations().then((locations) => {
|
||||||
ctx.commit('setLocations', locations);
|
ctx.commit("setLocations", locations);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getCurrentLocation(ctx): Promise<void> {
|
getCurrentLocation(ctx): Promise<void> {
|
||||||
return whereami().then(location => {
|
return whereami().then((location) => {
|
||||||
ctx.commit('setCurrentLocation', location);
|
ctx.commit("setCurrentLocation", location);
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
} as Module<LocationState, State>;
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import {State} from './../index';
|
import { State } from "./../index";
|
||||||
import {User} from '../../../../../../../ChillMainBundle/Resources/public/types';
|
import { User } from "../../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
import {ActionContext} from 'vuex';
|
import { ActionContext } from "vuex";
|
||||||
|
|
||||||
export interface MeState {
|
export interface MeState {
|
||||||
me: User|null,
|
me: User | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Context = ActionContext<MeState, State>;
|
type Context = ActionContext<MeState, State>;
|
||||||
@ -22,8 +22,5 @@ export default {
|
|||||||
setWhoAmi(state: MeState, me: User) {
|
setWhoAmi(state: MeState, me: User) {
|
||||||
state.me = me;
|
state.me = me;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,20 +6,22 @@
|
|||||||
const fetchCalendarRanges = () => {
|
const fetchCalendarRanges = () => {
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
const url = `/api/1.0/calendar/calendar-range-available.json`;
|
const url = `/api/1.0/calendar/calendar-range-available.json`;
|
||||||
return fetch(url)
|
return fetch(url).then((response) => {
|
||||||
.then(response => {
|
if (response.ok) {
|
||||||
if (response.ok) { return response.json(); }
|
return response.json();
|
||||||
throw Error('Error with request resource response');
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchCalendarRangesByUser = (userId) => {
|
const fetchCalendarRangesByUser = (userId) => {
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
const url = `/api/1.0/calendar/calendar-range-available.json?user=${userId}`;
|
const url = `/api/1.0/calendar/calendar-range-available.json?user=${userId}`;
|
||||||
return fetch(url)
|
return fetch(url).then((response) => {
|
||||||
.then(response => {
|
if (response.ok) {
|
||||||
if (response.ok) { return response.json(); }
|
return response.json();
|
||||||
throw Error('Error with request resource response');
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -31,14 +33,14 @@ const fetchCalendarRangesByUser = (userId) => {
|
|||||||
const fetchCalendar = (mainUserId) => {
|
const fetchCalendar = (mainUserId) => {
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
const url = `/api/1.0/calendar/calendar.json?main_user=${mainUserId}&item_per_page=1000`;
|
const url = `/api/1.0/calendar/calendar.json?main_user=${mainUserId}&item_per_page=1000`;
|
||||||
return fetch(url)
|
return fetch(url).then((response) => {
|
||||||
.then(response => {
|
if (response.ok) {
|
||||||
if (response.ok) { return response.json(); }
|
return response.json();
|
||||||
throw Error('Error with request resource response');
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Endpoint chill_api_single_calendar_range__entity_create
|
* Endpoint chill_api_single_calendar_range__entity_create
|
||||||
* method POST, post CalendarRange entity
|
* method POST, post CalendarRange entity
|
||||||
@ -46,14 +48,16 @@ const fetchCalendar = (mainUserId) => {
|
|||||||
const postCalendarRange = (body) => {
|
const postCalendarRange = (body) => {
|
||||||
const url = `/api/1.0/calendar/calendar-range.json?`;
|
const url = `/api/1.0/calendar/calendar-range.json?`;
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
"Content-Type": "application/json;charset=utf-8",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(body)
|
body: JSON.stringify(body),
|
||||||
}).then(response => {
|
}).then((response) => {
|
||||||
if (response.ok) { return response.json(); }
|
if (response.ok) {
|
||||||
throw Error('Error with request resource response');
|
return response.json();
|
||||||
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,17 +66,19 @@ const postCalendarRange = (body) => {
|
|||||||
* method PATCH, patch CalendarRange entity
|
* method PATCH, patch CalendarRange entity
|
||||||
*/
|
*/
|
||||||
const patchCalendarRange = (id, body) => {
|
const patchCalendarRange = (id, body) => {
|
||||||
console.log(body)
|
console.log(body);
|
||||||
const url = `/api/1.0/calendar/calendar-range/${id}.json`;
|
const url = `/api/1.0/calendar/calendar-range/${id}.json`;
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
method: 'PATCH',
|
method: "PATCH",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
"Content-Type": "application/json;charset=utf-8",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(body)
|
body: JSON.stringify(body),
|
||||||
}).then(response => {
|
}).then((response) => {
|
||||||
if (response.ok) { return response.json(); }
|
if (response.ok) {
|
||||||
throw Error('Error with request resource response');
|
return response.json();
|
||||||
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,13 +89,15 @@ const patchCalendarRange = (id, body) => {
|
|||||||
const deleteCalendarRange = (id) => {
|
const deleteCalendarRange = (id) => {
|
||||||
const url = `/api/1.0/calendar/calendar-range/${id}.json`;
|
const url = `/api/1.0/calendar/calendar-range/${id}.json`;
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
method: 'DELETE',
|
method: "DELETE",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
"Content-Type": "application/json;charset=utf-8",
|
||||||
},
|
},
|
||||||
}).then(response => {
|
}).then((response) => {
|
||||||
if (response.ok) { return response.json(); }
|
if (response.ok) {
|
||||||
throw Error('Error with request resource response');
|
return response.json();
|
||||||
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,5 +107,5 @@ export {
|
|||||||
fetchCalendarRangesByUser,
|
fetchCalendarRangesByUser,
|
||||||
postCalendarRange,
|
postCalendarRange,
|
||||||
patchCalendarRange,
|
patchCalendarRange,
|
||||||
deleteCalendarRange
|
deleteCalendarRange,
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="chill-red">{{ $t('choose_your_calendar_user') }}</h2>
|
<h2 class="chill-red">
|
||||||
|
{{ $t("choose_your_calendar_user") }}
|
||||||
|
</h2>
|
||||||
<VueMultiselect
|
<VueMultiselect
|
||||||
name="field"
|
name="field"
|
||||||
id="calendarUserSelector"
|
id="calendarUserSelector"
|
||||||
@ -19,50 +21,70 @@
|
|||||||
@select="selectUsers"
|
@select="selectUsers"
|
||||||
@remove="unSelectUsers"
|
@remove="unSelectUsers"
|
||||||
@close="coloriseSelectedValues"
|
@close="coloriseSelectedValues"
|
||||||
:options="options">
|
:options="options"
|
||||||
</VueMultiselect>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input type="checkbox" id="myCalendar" class="form-check-input" v-model="showMyCalendarWidget" />
|
<input
|
||||||
<label class="form-check-label" for="myCalendar">{{ $t('show_my_calendar') }}</label>
|
type="checkbox"
|
||||||
|
id="myCalendar"
|
||||||
|
class="form-check-input"
|
||||||
|
v-model="showMyCalendarWidget"
|
||||||
|
/>
|
||||||
|
<label class="form-check-label" for="myCalendar">{{
|
||||||
|
$t("show_my_calendar")
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input type="checkbox" id="weekends" class="form-check-input" @click="toggleWeekends" />
|
<input
|
||||||
<label class="form-check-label" for="weekends">{{ $t('show_weekends') }}</label>
|
type="checkbox"
|
||||||
|
id="weekends"
|
||||||
|
class="form-check-input"
|
||||||
|
@click="toggleWeekends"
|
||||||
|
/>
|
||||||
|
<label class="form-check-label" for="weekends">{{
|
||||||
|
$t("show_weekends")
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { fetchCalendarRanges, fetchCalendar } from "../../_api/api";
|
||||||
|
import VueMultiselect from "vue-multiselect";
|
||||||
|
import { whoami } from "ChillPersonAssets/vuejs/AccompanyingCourse/api";
|
||||||
|
|
||||||
import { fetchCalendarRanges, fetchCalendar } from '../../_api/api'
|
const COLORS = [
|
||||||
import VueMultiselect from 'vue-multiselect';
|
/* from https://colorbrewer2.org/#type=qualitative&scheme=Set3&n=12 */
|
||||||
import { whoami } from 'ChillPersonAssets/vuejs/AccompanyingCourse/api';
|
"#8dd3c7",
|
||||||
|
"#ffffb3",
|
||||||
const COLORS = [ /* from https://colorbrewer2.org/#type=qualitative&scheme=Set3&n=12 */
|
"#bebada",
|
||||||
'#8dd3c7',
|
"#fb8072",
|
||||||
'#ffffb3',
|
"#80b1d3",
|
||||||
'#bebada',
|
"#fdb462",
|
||||||
'#fb8072',
|
"#b3de69",
|
||||||
'#80b1d3',
|
"#fccde5",
|
||||||
'#fdb462',
|
"#d9d9d9",
|
||||||
'#b3de69',
|
"#bc80bd",
|
||||||
'#fccde5',
|
"#ccebc5",
|
||||||
'#d9d9d9',
|
"#ffed6f",
|
||||||
'#bc80bd',
|
|
||||||
'#ccebc5',
|
|
||||||
'#ffed6f'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CalendarUserSelector',
|
name: "CalendarUserSelector",
|
||||||
components: { VueMultiselect },
|
components: { VueMultiselect },
|
||||||
props: ['users', 'updateEventsSource', 'calendarEvents', 'showMyCalendar', 'toggleMyCalendar', 'toggleWeekends'],
|
props: [
|
||||||
|
"users",
|
||||||
|
"updateEventsSource",
|
||||||
|
"calendarEvents",
|
||||||
|
"showMyCalendar",
|
||||||
|
"toggleMyCalendar",
|
||||||
|
"toggleWeekends",
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
errorMsg: [],
|
errorMsg: [],
|
||||||
value: [],
|
value: [],
|
||||||
options: []
|
options: [],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
showMyCalendarWidget: {
|
showMyCalendarWidget: {
|
||||||
@ -72,86 +94,113 @@ export default {
|
|||||||
},
|
},
|
||||||
get() {
|
get() {
|
||||||
return this.showMyCalendar;
|
return this.showMyCalendar;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init() {
|
init() {
|
||||||
this.fetchData()
|
this.fetchData();
|
||||||
},
|
},
|
||||||
fetchData() {
|
fetchData() {
|
||||||
fetchCalendarRanges().then(calendarRanges => new Promise((resolve, reject) => {
|
fetchCalendarRanges()
|
||||||
|
.then(
|
||||||
|
(calendarRanges) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
let results = calendarRanges.results;
|
let results = calendarRanges.results;
|
||||||
|
|
||||||
let users = [];
|
let users = [];
|
||||||
|
|
||||||
results.forEach(i => {
|
results.forEach((i) => {
|
||||||
if (!(users.some(j => i.user.id === j.id))){
|
if (!users.some((j) => i.user.id === j.id)) {
|
||||||
let ratio = Math.floor(users.length / COLORS.length);
|
let ratio = Math.floor(
|
||||||
let colorIndex = users.length - ratio * COLORS.length;
|
users.length / COLORS.length,
|
||||||
|
);
|
||||||
|
let colorIndex =
|
||||||
|
users.length - ratio * COLORS.length;
|
||||||
users.push({
|
users.push({
|
||||||
id: i.user.id,
|
id: i.user.id,
|
||||||
username: i.user.username,
|
username: i.user.username,
|
||||||
color: COLORS[colorIndex]
|
color: COLORS[colorIndex],
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let calendarEvents = [];
|
let calendarEvents = [];
|
||||||
users.forEach(u => {
|
users.forEach((u) => {
|
||||||
let arr = results.filter(i => i.user.id === u.id).map(i =>
|
let arr = results
|
||||||
({
|
.filter((i) => i.user.id === u.id)
|
||||||
|
.map((i) => ({
|
||||||
start: i.startDate.datetime,
|
start: i.startDate.datetime,
|
||||||
end: i.endDate.datetime,
|
end: i.endDate.datetime,
|
||||||
calendarRangeId: i.id,
|
calendarRangeId: i.id,
|
||||||
sourceColor: u.color
|
sourceColor: u.color,
|
||||||
//display: 'background' // can be an option for the disponibility
|
//display: 'background' // can be an option for the disponibility
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
calendarEvents.push({
|
calendarEvents.push({
|
||||||
events: arr,
|
events: arr,
|
||||||
color: u.color,
|
color: u.color,
|
||||||
textColor: '#444444',
|
textColor: "#444444",
|
||||||
editable: false,
|
editable: false,
|
||||||
id: u.id
|
id: u.id,
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
this.users.loaded = users;
|
this.users.loaded = users;
|
||||||
this.options = users;
|
this.options = users;
|
||||||
|
|
||||||
this.calendarEvents.loaded = calendarEvents;
|
this.calendarEvents.loaded = calendarEvents;
|
||||||
whoami().then(me => new Promise((resolve, reject) => {
|
whoami().then(
|
||||||
|
(me) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
this.users.logged = me;
|
this.users.logged = me;
|
||||||
let currentUser = users.find(u => u.id === me.id);
|
let currentUser = users.find(
|
||||||
|
(u) => u.id === me.id,
|
||||||
|
);
|
||||||
this.value = currentUser;
|
this.value = currentUser;
|
||||||
|
|
||||||
fetchCalendar(currentUser.id).then(calendar => new Promise((resolve, reject) => {
|
fetchCalendar(currentUser.id).then(
|
||||||
let results = calendar.results;
|
(calendar) =>
|
||||||
let events = results.map(i =>
|
new Promise(
|
||||||
({
|
(resolve, reject) => {
|
||||||
start: i.startDate.datetime,
|
let results =
|
||||||
end: i.endDate.datetime,
|
calendar.results;
|
||||||
})
|
let events =
|
||||||
|
results.map(
|
||||||
|
(i) => ({
|
||||||
|
start: i
|
||||||
|
.startDate
|
||||||
|
.datetime,
|
||||||
|
end: i
|
||||||
|
.endDate
|
||||||
|
.datetime,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
let calendarEventsCurrentUser = {
|
let calendarEventsCurrentUser =
|
||||||
|
{
|
||||||
events: events,
|
events: events,
|
||||||
color: 'darkblue',
|
color: "darkblue",
|
||||||
id: 1000,
|
id: 1000,
|
||||||
editable: false
|
editable: false,
|
||||||
};
|
};
|
||||||
this.calendarEvents.user = calendarEventsCurrentUser;
|
this.calendarEvents.user =
|
||||||
|
calendarEventsCurrentUser;
|
||||||
|
|
||||||
this.selectUsers(currentUser);
|
this.selectUsers(
|
||||||
|
currentUser,
|
||||||
|
);
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
}));
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
}))
|
}),
|
||||||
|
)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.errorMsg.push(error.message);
|
this.errorMsg.push(error.message);
|
||||||
});
|
});
|
||||||
@ -160,29 +209,32 @@ export default {
|
|||||||
return `${value.username}`;
|
return `${value.username}`;
|
||||||
},
|
},
|
||||||
coloriseSelectedValues() {
|
coloriseSelectedValues() {
|
||||||
let tags = document.querySelectorAll('div.multiselect__tags-wrap')[0];
|
let tags = document.querySelectorAll(
|
||||||
|
"div.multiselect__tags-wrap",
|
||||||
|
)[0];
|
||||||
|
|
||||||
if (tags.hasChildNodes()) {
|
if (tags.hasChildNodes()) {
|
||||||
let children = tags.childNodes;
|
let children = tags.childNodes;
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
let child = children[i];
|
let child = children[i];
|
||||||
if (child.nodeType === Node.ELEMENT_NODE) {
|
if (child.nodeType === Node.ELEMENT_NODE) {
|
||||||
this.users.selected.forEach(u => {
|
this.users.selected.forEach((u) => {
|
||||||
if (child.hasChildNodes()) {
|
if (child.hasChildNodes()) {
|
||||||
if (child.firstChild.innerText == u.username) {
|
if (child.firstChild.innerText == u.username) {
|
||||||
child.style.background = u.color;
|
child.style.background = u.color;
|
||||||
child.firstChild.style.color = '#444444';
|
child.firstChild.style.color = "#444444";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectEvents() {
|
selectEvents() {
|
||||||
let selectedUsersId = this.users.selected.map(a => a.id);
|
let selectedUsersId = this.users.selected.map((a) => a.id);
|
||||||
this.calendarEvents.selected = this.calendarEvents.loaded.filter(a => selectedUsersId.includes(a.id));
|
this.calendarEvents.selected = this.calendarEvents.loaded.filter(
|
||||||
|
(a) => selectedUsersId.includes(a.id),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
selectUsers(value) {
|
selectUsers(value) {
|
||||||
this.users.selected.push(value);
|
this.users.selected.push(value);
|
||||||
@ -191,16 +243,17 @@ export default {
|
|||||||
this.updateEventsSource();
|
this.updateEventsSource();
|
||||||
},
|
},
|
||||||
unSelectUsers(value) {
|
unSelectUsers(value) {
|
||||||
this.users.selected = this.users.selected.filter(a => a.id != value.id);
|
this.users.selected = this.users.selected.filter(
|
||||||
|
(a) => a.id != value.id,
|
||||||
|
);
|
||||||
this.selectEvents();
|
this.selectEvents();
|
||||||
this.updateEventsSource();
|
this.updateEventsSource();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.init();
|
this.init();
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
||||||
|
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
import { multiSelectMessages } from 'ChillMainAssets/vuejs/_js/i18n'
|
import { multiSelectMessages } from "ChillMainAssets/vuejs/_js/i18n";
|
||||||
|
|
||||||
const calendarUserSelectorMessages = {
|
const calendarUserSelectorMessages = {
|
||||||
fr: {
|
fr: {
|
||||||
choose_your_calendar_user: "Afficher les plages de disponibilités",
|
choose_your_calendar_user: "Afficher les plages de disponibilités",
|
||||||
select_user: "Sélectionnez des calendriers",
|
select_user: "Sélectionnez des calendriers",
|
||||||
show_my_calendar: "Afficher mon calendrier",
|
show_my_calendar: "Afficher mon calendrier",
|
||||||
show_weekends: "Afficher les week-ends"
|
show_weekends: "Afficher les week-ends",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.assign(calendarUserSelectorMessages.fr, multiSelectMessages.fr);
|
Object.assign(calendarUserSelectorMessages.fr, multiSelectMessages.fr);
|
||||||
|
|
||||||
export {
|
export { calendarUserSelectorMessages };
|
||||||
calendarUserSelectorMessages
|
|
||||||
};
|
|
||||||
|
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
// this file loads all assets from the Chill calendar bundle
|
// this file loads all assets from the Chill calendar bundle
|
||||||
module.exports = function (encore, entries) {
|
module.exports = function (encore, entries) {
|
||||||
|
entries.push(__dirname + "/Resources/public/chill/chill.js");
|
||||||
entries.push(__dirname + '/Resources/public/chill/chill.js');
|
|
||||||
|
|
||||||
encore.addAliases({
|
encore.addAliases({
|
||||||
ChillCalendarAssets: __dirname + '/Resources/public'
|
ChillCalendarAssets: __dirname + "/Resources/public",
|
||||||
});
|
});
|
||||||
|
|
||||||
encore.addEntry('vue_calendar', __dirname + '/Resources/public/vuejs/Calendar/index.js');
|
encore.addEntry(
|
||||||
encore.addEntry('vue_mycalendarrange', __dirname + '/Resources/public/vuejs/MyCalendarRange/index2.ts');
|
"vue_calendar",
|
||||||
encore.addEntry('page_calendar', __dirname + '/Resources/public/chill/index.js');
|
__dirname + "/Resources/public/vuejs/Calendar/index.js",
|
||||||
encore.addEntry('mod_answer', __dirname + '/Resources/public/module/Invite/answer.js');
|
);
|
||||||
|
encore.addEntry(
|
||||||
|
"vue_mycalendarrange",
|
||||||
|
__dirname + "/Resources/public/vuejs/MyCalendarRange/index2.ts",
|
||||||
|
);
|
||||||
|
encore.addEntry(
|
||||||
|
"page_calendar",
|
||||||
|
__dirname + "/Resources/public/chill/index.js",
|
||||||
|
);
|
||||||
|
encore.addEntry(
|
||||||
|
"mod_answer",
|
||||||
|
__dirname + "/Resources/public/module/Invite/answer.js",
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,8 +3,6 @@ import { fetchResults } from "ChillMainAssets/lib/api/apiMethods.ts";
|
|||||||
const fetchTemplates = (entityClass) => {
|
const fetchTemplates = (entityClass) => {
|
||||||
let fqdnEntityClass = encodeURI(entityClass);
|
let fqdnEntityClass = encodeURI(entityClass);
|
||||||
return fetchResults(`/api/1.0/docgen/templates/by-entity/${fqdnEntityClass}`);
|
return fetchResults(`/api/1.0/docgen/templates/by-entity/${fqdnEntityClass}`);
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
fetchTemplates
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export { fetchTemplates };
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
|
|
||||||
const buildLink = function (templateId, entityId, entityClass) {
|
const buildLink = function (templateId, entityId, entityClass) {
|
||||||
const
|
const entityIdEncoded = encodeURI(entityId),
|
||||||
entityIdEncoded = encodeURI(entityId),
|
returnPath = encodeURIComponent(
|
||||||
returnPath = encodeURIComponent(window.location.pathname + window.location.search + window.location.hash),
|
window.location.pathname + window.location.search + window.location.hash,
|
||||||
|
),
|
||||||
entityClassEncoded = encodeURI(entityClass),
|
entityClassEncoded = encodeURI(entityClass),
|
||||||
url = `/fr/doc/gen/generate/from/${templateId}/for/${entityClassEncoded}/${entityIdEncoded}?returnPath=${returnPath}`
|
url = `/fr/doc/gen/generate/from/${templateId}/for/${entityClassEncoded}/${entityIdEncoded}?returnPath=${returnPath}`;
|
||||||
;
|
console.log("computed Url");
|
||||||
console.log('computed Url');
|
|
||||||
return url;
|
return url;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import {createApp} from 'vue';
|
import { createApp } from "vue";
|
||||||
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
import PickTemplate from "ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue";
|
||||||
import {fetchTemplates} from 'ChillDocGeneratorAssets/api/pickTemplate.js';
|
import { fetchTemplates } from "ChillDocGeneratorAssets/api/pickTemplate.js";
|
||||||
import {_createI18n} from 'ChillMainAssets/vuejs/_js/i18n';
|
import { _createI18n } from "ChillMainAssets/vuejs/_js/i18n";
|
||||||
|
|
||||||
const i18n = _createI18n({});
|
const i18n = _createI18n({});
|
||||||
|
|
||||||
document.querySelectorAll('div[data-docgen-template-picker]').forEach(el => {
|
document.querySelectorAll("div[data-docgen-template-picker]").forEach((el) => {
|
||||||
fetchTemplates(el.dataset.entityClass).then(templates => {
|
fetchTemplates(el.dataset.entityClass).then((templates) => {
|
||||||
let
|
let picker = {
|
||||||
picker = {
|
template:
|
||||||
template: '<pick-template :templates="this.templates" :entityId="this.entityId"></pick-template>',
|
'<pick-template :templates="this.templates" :entityId="this.entityId"></pick-template>',
|
||||||
components: {
|
components: {
|
||||||
PickTemplate,
|
PickTemplate,
|
||||||
},
|
},
|
||||||
@ -17,11 +17,9 @@ document.querySelectorAll('div[data-docgen-template-picker]').forEach(el => {
|
|||||||
return {
|
return {
|
||||||
templates: templates,
|
templates: templates,
|
||||||
entityId: el.dataset.entityId,
|
entityId: el.dataset.entityId,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
;
|
|
||||||
createApp(picker).use(i18n).mount(el);
|
createApp(picker).use(i18n).mount(el);
|
||||||
})
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -2,26 +2,44 @@
|
|||||||
<div>
|
<div>
|
||||||
<template v-if="templates.length > 0">
|
<template v-if="templates.length > 0">
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
<h2>{{ $t('generate_document')}}</h2>
|
<h2>{{ $t("generate_document") }}</h2>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<slot name="label">
|
<slot name="label">
|
||||||
<label>{{ $t('select_a_template') }}</label>
|
<label>{{ $t("select_a_template") }}</label>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3">
|
||||||
<select class="form-select" v-model="template">
|
<select class="form-select" v-model="template">
|
||||||
<option disabled selected value="">{{ $t('choose_a_template') }}</option>
|
<option disabled selected value="">
|
||||||
|
{{ $t("choose_a_template") }}
|
||||||
|
</option>
|
||||||
<template v-for="t in templates" :key="t.id">
|
<template v-for="t in templates" :key="t.id">
|
||||||
<option :value="t.id" >{{ t.name.fr || 'Aucun nom défini' }}</option>
|
<option :value="t.id">
|
||||||
|
{{ t.name.fr || "Aucun nom défini" }}
|
||||||
|
</option>
|
||||||
</template>
|
</template>
|
||||||
</select>
|
</select>
|
||||||
<a v-if="canGenerate" class="btn btn-update btn-sm change-icon" :href="buildUrlGenerate" @click.prevent="clickGenerate($event, buildUrlGenerate)"><i class="fa fa-fw fa-cog"></i></a>
|
<a
|
||||||
<a v-else class="btn btn-update btn-sm change-icon" href="#" disabled ><i class="fa fa-fw fa-cog"></i></a>
|
v-if="canGenerate"
|
||||||
|
class="btn btn-update btn-sm change-icon"
|
||||||
|
:href="buildUrlGenerate"
|
||||||
|
@click.prevent="
|
||||||
|
clickGenerate($event, buildUrlGenerate)
|
||||||
|
"
|
||||||
|
><i class="fa fa-fw fa-cog"
|
||||||
|
/></a>
|
||||||
|
<a
|
||||||
|
v-else
|
||||||
|
class="btn btn-update btn-sm change-icon"
|
||||||
|
href="#"
|
||||||
|
disabled
|
||||||
|
><i class="fa fa-fw fa-cog"
|
||||||
|
/></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -30,16 +48,13 @@
|
|||||||
<p>{{ getDescription }}</p>
|
<p>{{ getDescription }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { buildLink } from "ChillDocGeneratorAssets/lib/document-generator";
|
||||||
import {buildLink} from 'ChillDocGeneratorAssets/lib/document-generator';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PickTemplate",
|
name: "PickTemplate",
|
||||||
@ -57,13 +72,13 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false,
|
default: false,
|
||||||
}
|
|
||||||
},
|
},
|
||||||
emits: ['goToGenerateDocument'],
|
},
|
||||||
|
emits: ["goToGenerateDocument"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
template: null,
|
template: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
canGenerate() {
|
canGenerate() {
|
||||||
@ -78,21 +93,21 @@ export default {
|
|||||||
},
|
},
|
||||||
getDescription() {
|
getDescription() {
|
||||||
if (null === this.template) {
|
if (null === this.template) {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
let desc = this.templates.find(t => t.id === this.template);
|
let desc = this.templates.find((t) => t.id === this.template);
|
||||||
if (null === desc) {
|
if (null === desc) {
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
return desc.description || '';
|
return desc.description || "";
|
||||||
},
|
},
|
||||||
buildUrlGenerate() {
|
buildUrlGenerate() {
|
||||||
if (null === this.template) {
|
if (null === this.template) {
|
||||||
return '#';
|
return "#";
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildLink(this.template, this.entityId, this.entityClass);
|
return buildLink(this.template, this.entityId, this.entityClass);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
clickGenerate(event, link) {
|
clickGenerate(event, link) {
|
||||||
@ -100,21 +115,23 @@ export default {
|
|||||||
window.location.assign(link);
|
window.location.assign(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('goToGenerateDocument', {event, link, template: this.template});
|
this.$emit("goToGenerateDocument", {
|
||||||
|
event,
|
||||||
|
link,
|
||||||
|
template: this.template,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
i18n: {
|
i18n: {
|
||||||
messages: {
|
messages: {
|
||||||
fr: {
|
fr: {
|
||||||
generate_document: 'Générer un document',
|
generate_document: "Générer un document",
|
||||||
select_a_template: 'Choisir un modèle',
|
select_a_template: "Choisir un modèle",
|
||||||
choose_a_template: 'Choisir',
|
choose_a_template: "Choisir",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
// this file loads all assets from the Chill DocGenerator bundle
|
// this file loads all assets from the Chill DocGenerator bundle
|
||||||
module.exports = function (encore, entries) {
|
module.exports = function (encore, entries) {
|
||||||
encore.addAliases({
|
encore.addAliases({
|
||||||
ChillDocGeneratorAssets: __dirname + '/Resources/public'
|
ChillDocGeneratorAssets: __dirname + "/Resources/public",
|
||||||
});
|
});
|
||||||
|
|
||||||
encore.addEntry('mod_docgen_picktemplate', __dirname + '/Resources/public/module/PickTemplate/index.js');
|
encore.addEntry(
|
||||||
|
"mod_docgen_picktemplate",
|
||||||
|
__dirname + "/Resources/public/module/PickTemplate/index.js",
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
var mime = require('mime');
|
var mime = require("mime");
|
||||||
|
|
||||||
var algo = 'AES-CBC';
|
var algo = "AES-CBC";
|
||||||
|
|
||||||
var initializeButtons = (root) => {
|
var initializeButtons = (root) => {
|
||||||
var
|
var buttons = root.querySelectorAll("a[data-download-button]");
|
||||||
buttons = root.querySelectorAll('a[data-download-button]');
|
|
||||||
|
|
||||||
for (let i = 0; i < buttons.length; i++) {
|
for (let i = 0; i < buttons.length; i++) {
|
||||||
initialize(buttons[i]);
|
initialize(buttons[i]);
|
||||||
@ -12,18 +11,17 @@ var initializeButtons = (root) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var initialize = (button) => {
|
var initialize = (button) => {
|
||||||
button.addEventListener('click', onClick);
|
button.addEventListener("click", onClick);
|
||||||
};
|
};
|
||||||
|
|
||||||
var onClick = e => download(e.target);
|
var onClick = (e) => download(e.target);
|
||||||
|
|
||||||
var download = (button) => {
|
var download = (button) => {
|
||||||
var
|
var keyData = JSON.parse(button.dataset.key),
|
||||||
keyData = JSON.parse(button.dataset.key),
|
|
||||||
ivData = JSON.parse(button.dataset.iv),
|
ivData = JSON.parse(button.dataset.iv),
|
||||||
iv = new Uint8Array(ivData),
|
iv = new Uint8Array(ivData),
|
||||||
urlGenerator = button.dataset.tempUrlGetGenerator,
|
urlGenerator = button.dataset.tempUrlGetGenerator,
|
||||||
hasFilename = 'filename' in button.dataset,
|
hasFilename = "filename" in button.dataset,
|
||||||
filename = button.dataset.filename,
|
filename = button.dataset.filename,
|
||||||
labelPreparing = button.dataset.labelPreparing,
|
labelPreparing = button.dataset.labelPreparing,
|
||||||
labelReady = button.dataset.labelReady,
|
labelReady = button.dataset.labelReady,
|
||||||
@ -31,65 +29,70 @@ var download = (button) => {
|
|||||||
extension = mime.getExtension(mimeType),
|
extension = mime.getExtension(mimeType),
|
||||||
decryptError = "Error while decrypting file",
|
decryptError = "Error while decrypting file",
|
||||||
fetchError = "Error while fetching file",
|
fetchError = "Error while fetching file",
|
||||||
key, url
|
key,
|
||||||
;
|
url;
|
||||||
|
|
||||||
button.textContent = labelPreparing;
|
button.textContent = labelPreparing;
|
||||||
|
|
||||||
window.fetch(urlGenerator)
|
window
|
||||||
|
.fetch(urlGenerator)
|
||||||
.then((r) => {
|
.then((r) => {
|
||||||
if (r.ok) {
|
if (r.ok) {
|
||||||
return r.json();
|
return r.json();
|
||||||
} else {
|
} else {
|
||||||
throw new Error("error while downloading url " + r.status + " " + r.statusText);
|
throw new Error(
|
||||||
|
"error while downloading url " + r.status + " " + r.statusText,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then((data) => {
|
||||||
return window.fetch(data.url);
|
return window.fetch(data.url);
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
return response.arrayBuffer();
|
return response.arrayBuffer();
|
||||||
}
|
}
|
||||||
throw new Error(response.status + response.statusText);
|
throw new Error(response.status + response.statusText);
|
||||||
})
|
})
|
||||||
.then(buffer => {
|
.then((buffer) => {
|
||||||
if (keyData.alg !== undefined) {
|
if (keyData.alg !== undefined) {
|
||||||
return window.crypto.subtle
|
return window.crypto.subtle
|
||||||
.importKey('jwk', keyData, { name: algo, iv: iv}, false, ['decrypt'])
|
.importKey("jwk", keyData, { name: algo, iv: iv }, false, ["decrypt"])
|
||||||
.then(key => {
|
.then((key) => {
|
||||||
return window.crypto.subtle.decrypt({ name: algo, iv: iv }, key, buffer);
|
return window.crypto.subtle.decrypt(
|
||||||
|
{ name: algo, iv: iv },
|
||||||
|
key,
|
||||||
|
buffer,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return Promise.resolve(buffer);
|
return Promise.resolve(buffer);
|
||||||
})
|
})
|
||||||
.then(decrypted => {
|
.then((decrypted) => {
|
||||||
var
|
var blob = new Blob([decrypted], { type: mimeType }),
|
||||||
blob = new Blob([decrypted], { type: mimeType }),
|
url = window.URL.createObjectURL(blob);
|
||||||
url = window.URL.createObjectURL(blob)
|
|
||||||
;
|
|
||||||
button.href = url;
|
button.href = url;
|
||||||
button.target = '_blank';
|
button.target = "_blank";
|
||||||
button.type = mimeType;
|
button.type = mimeType;
|
||||||
button.textContent = labelReady;
|
button.textContent = labelReady;
|
||||||
if (hasFilename) {
|
if (hasFilename) {
|
||||||
|
|
||||||
button.download = filename;
|
button.download = filename;
|
||||||
if (extension !== false) {
|
if (extension !== false) {
|
||||||
button.download = button.download + '.' + extension;
|
button.download = button.download + "." + extension;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button.removeEventListener('click', onClick);
|
button.removeEventListener("click", onClick);
|
||||||
button.click();
|
button.click();
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
button.textContent = "";
|
button.textContent = "";
|
||||||
button.appendChild(document.createTextNode("error while handling decrypted file"));
|
button.appendChild(
|
||||||
})
|
document.createTextNode("error while handling decrypted file"),
|
||||||
;
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('load', function(e) {
|
window.addEventListener("load", function (e) {
|
||||||
initializeButtons(e.target);
|
initializeButtons(e.target);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
require('./uploader.js');
|
require("./uploader.js");
|
||||||
require('./downloader.js');
|
require("./downloader.js");
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
var algo = 'AES-CBC';
|
var algo = "AES-CBC";
|
||||||
import Dropzone from 'dropzone';
|
import Dropzone from "dropzone";
|
||||||
import { initializeButtons } from './downloader.js';
|
import { initializeButtons } from "./downloader.js";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -23,8 +22,8 @@ import { initializeButtons } from './downloader.js';
|
|||||||
|
|
||||||
// load css
|
// load css
|
||||||
//require('dropzone/dist/basic.css');
|
//require('dropzone/dist/basic.css');
|
||||||
require('dropzone/dist/dropzone.css');
|
require("dropzone/dist/dropzone.css");
|
||||||
require('./index.scss');
|
require("./index.scss");
|
||||||
//
|
//
|
||||||
|
|
||||||
// disable dropzone autodiscover
|
// disable dropzone autodiscover
|
||||||
@ -32,22 +31,21 @@ Dropzone.autoDiscover = false;
|
|||||||
|
|
||||||
var keyDefinition = {
|
var keyDefinition = {
|
||||||
name: algo,
|
name: algo,
|
||||||
length: 256
|
length: 256,
|
||||||
};
|
};
|
||||||
|
|
||||||
var searchForZones = function (root) {
|
var searchForZones = function (root) {
|
||||||
var zones = root.querySelectorAll('div[data-stored-object]');
|
var zones = root.querySelectorAll("div[data-stored-object]");
|
||||||
for (let i = 0; i < zones.length; i++) {
|
for (let i = 0; i < zones.length; i++) {
|
||||||
initialize(zones[i]);
|
initialize(zones[i]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var getUploadUrl = function (zoneData, files) {
|
var getUploadUrl = function (zoneData, files) {
|
||||||
var
|
var generateTempUrlPost = zoneData.zone.querySelector(
|
||||||
generateTempUrlPost = zoneData.zone.querySelector('input[data-async-file-upload]').dataset.generateTempUrlPost,
|
"input[data-async-file-upload]",
|
||||||
oReq = new XMLHttpRequest()
|
).dataset.generateTempUrlPost,
|
||||||
;
|
oReq = new XMLHttpRequest();
|
||||||
|
|
||||||
// arg, dropzone, you cannot handle async upload...
|
// arg, dropzone, you cannot handle async upload...
|
||||||
oReq.open("GET", generateTempUrlPost, false);
|
oReq.open("GET", generateTempUrlPost, false);
|
||||||
oReq.send();
|
oReq.send();
|
||||||
@ -62,32 +60,37 @@ var getUploadUrl = function(zoneData, files) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var encryptFile = function (originalFile, zoneData, done) {
|
var encryptFile = function (originalFile, zoneData, done) {
|
||||||
var
|
var iv = crypto.getRandomValues(new Uint8Array(16)),
|
||||||
iv = crypto.getRandomValues(new Uint8Array(16)),
|
|
||||||
reader = new FileReader(),
|
reader = new FileReader(),
|
||||||
jsKey, rawKey
|
jsKey,
|
||||||
;
|
rawKey;
|
||||||
|
|
||||||
zoneData.originalType = originalFile.type;
|
zoneData.originalType = originalFile.type;
|
||||||
|
|
||||||
reader.onload = e => {
|
reader.onload = (e) => {
|
||||||
window.crypto.subtle.generateKey(keyDefinition, true, [ "encrypt", "decrypt" ])
|
window.crypto.subtle
|
||||||
.then(key => {
|
.generateKey(keyDefinition, true, ["encrypt", "decrypt"])
|
||||||
|
.then((key) => {
|
||||||
jsKey = key;
|
jsKey = key;
|
||||||
|
|
||||||
// we register the key somwhere
|
// we register the key somwhere
|
||||||
return window.crypto.subtle.exportKey('jwk', key);
|
return window.crypto.subtle.exportKey("jwk", key);
|
||||||
}).then(exportedKey => {
|
})
|
||||||
|
.then((exportedKey) => {
|
||||||
rawKey = exportedKey;
|
rawKey = exportedKey;
|
||||||
|
|
||||||
// we start encryption
|
// we start encryption
|
||||||
return window.crypto.subtle.encrypt({ name: algo, iv: iv}, jsKey, e.target.result);
|
return window.crypto.subtle.encrypt(
|
||||||
|
{ name: algo, iv: iv },
|
||||||
|
jsKey,
|
||||||
|
e.target.result,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.then(encrypted => {
|
.then((encrypted) => {
|
||||||
zoneData.crypto = {
|
zoneData.crypto = {
|
||||||
jsKey: jsKey,
|
jsKey: jsKey,
|
||||||
rawKey: rawKey,
|
rawKey: rawKey,
|
||||||
iv: iv
|
iv: iv,
|
||||||
};
|
};
|
||||||
|
|
||||||
done(new File([encrypted], zoneData.suffix));
|
done(new File([encrypted], zoneData.suffix));
|
||||||
@ -98,12 +101,11 @@ var encryptFile = function(originalFile, zoneData, done) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var addBelowButton = (btn, zone, zoneData) => {
|
var addBelowButton = (btn, zone, zoneData) => {
|
||||||
let
|
let belowZone = zone.querySelector(".chill-dropzone__below-zone");
|
||||||
belowZone = zone.querySelector('.chill-dropzone__below-zone');
|
|
||||||
|
|
||||||
if (belowZone === null) {
|
if (belowZone === null) {
|
||||||
belowZone = document.createElement('div');
|
belowZone = document.createElement("div");
|
||||||
belowZone.classList.add('chill-dropzone__below-zone');
|
belowZone.classList.add("chill-dropzone__below-zone");
|
||||||
zone.appendChild(belowZone);
|
zone.appendChild(belowZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,14 +113,13 @@ var addBelowButton = (btn, zone, zoneData) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var createZone = (zone, zoneData) => {
|
var createZone = (zone, zoneData) => {
|
||||||
var
|
var created = document.createElement("div"),
|
||||||
created = document.createElement('div'),
|
initMessage = document.createElement("div"),
|
||||||
initMessage = document.createElement('div'),
|
|
||||||
initContent = zone.dataset.labelInitMessage,
|
initContent = zone.dataset.labelInitMessage,
|
||||||
dropzoneI;
|
dropzoneI;
|
||||||
|
|
||||||
created.classList.add('dropzone');
|
created.classList.add("dropzone");
|
||||||
initMessage.classList.add('dz-message');
|
initMessage.classList.add("dz-message");
|
||||||
initMessage.appendChild(document.createTextNode(initContent));
|
initMessage.appendChild(document.createTextNode(initContent));
|
||||||
console.log(Dropzone);
|
console.log(Dropzone);
|
||||||
dropzoneI = new Dropzone(created, {
|
dropzoneI = new Dropzone(created, {
|
||||||
@ -139,7 +140,7 @@ var createZone = (zone, zoneData) => {
|
|||||||
},
|
},
|
||||||
renameFile: function (file) {
|
renameFile: function (file) {
|
||||||
return zoneData.suffix;
|
return zoneData.suffix;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
dropzoneI.on("sending", function (file, xhr, formData) {
|
dropzoneI.on("sending", function (file, xhr, formData) {
|
||||||
@ -156,7 +157,7 @@ var createZone = (zone, zoneData) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
dropzoneI.on("addedfile", function (file) {
|
dropzoneI.on("addedfile", function (file) {
|
||||||
if (zoneData.hasOwnProperty('currentFile')) {
|
if (zoneData.hasOwnProperty("currentFile")) {
|
||||||
dropzoneI.removeFile(zoneData.currentFile);
|
dropzoneI.removeFile(zoneData.currentFile);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -170,19 +171,20 @@ var createZone = (zone, zoneData) => {
|
|||||||
let event = new CustomEvent("chill_dropzone_initialized", {
|
let event = new CustomEvent("chill_dropzone_initialized", {
|
||||||
detail: {
|
detail: {
|
||||||
dropzone: dropzoneI,
|
dropzone: dropzoneI,
|
||||||
zoneData: zoneData
|
zoneData: zoneData,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
window.dispatchEvent(event);
|
window.dispatchEvent(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var initialize = function (zone) {
|
var initialize = function (zone) {
|
||||||
var
|
var allowRemove = zone.dataset.allowRemove,
|
||||||
allowRemove = zone.dataset.allowRemove,
|
zoneData = {
|
||||||
zoneData = { zone: zone, suffix: createFilename(), allowRemove: allowRemove, old: null }
|
zone: zone,
|
||||||
;
|
suffix: createFilename(),
|
||||||
|
allowRemove: allowRemove,
|
||||||
|
old: null,
|
||||||
|
};
|
||||||
if (hasDataInForm(zone, zoneData)) {
|
if (hasDataInForm(zone, zoneData)) {
|
||||||
insertRemoveButton(zone, zoneData);
|
insertRemoveButton(zone, zoneData);
|
||||||
insertDownloadButton(zone, zoneData);
|
insertDownloadButton(zone, zoneData);
|
||||||
@ -193,7 +195,8 @@ var initialize = function(zone) {
|
|||||||
|
|
||||||
var createFilename = () => {
|
var createFilename = () => {
|
||||||
var text = "";
|
var text = "";
|
||||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
var possible =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
for (let i = 0; i < 7; i++) {
|
for (let i = 0; i < 7; i++) {
|
||||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||||
@ -203,13 +206,10 @@ var createFilename = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var storeDataInForm = (zone, zoneData) => {
|
var storeDataInForm = (zone, zoneData) => {
|
||||||
var
|
var inputKey = zone.querySelector("input[data-stored-object-key]"),
|
||||||
inputKey = zone.querySelector('input[data-stored-object-key]'),
|
inputIv = zone.querySelector("input[data-stored-object-iv]"),
|
||||||
inputIv = zone.querySelector('input[data-stored-object-iv]'),
|
inputObject = zone.querySelector("input[data-async-file-upload]"),
|
||||||
inputObject = zone.querySelector('input[data-async-file-upload]'),
|
inputType = zone.querySelector("input[data-async-file-type]");
|
||||||
inputType = zone.querySelector('input[data-async-file-type]')
|
|
||||||
;
|
|
||||||
|
|
||||||
inputKey.value = JSON.stringify(zoneData.crypto.rawKey);
|
inputKey.value = JSON.stringify(zoneData.crypto.rawKey);
|
||||||
inputIv.value = JSON.stringify(Array.from(zoneData.crypto.iv));
|
inputIv.value = JSON.stringify(Array.from(zoneData.crypto.iv));
|
||||||
inputType.value = zoneData.originalType;
|
inputType.value = zoneData.originalType;
|
||||||
@ -219,15 +219,12 @@ var storeDataInForm = (zone, zoneData) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const restoreDataInForm = (zone, zoneData) => {
|
const restoreDataInForm = (zone, zoneData) => {
|
||||||
var
|
var inputKey = zone.querySelector("input[data-stored-object-key]"),
|
||||||
inputKey = zone.querySelector('input[data-stored-object-key]'),
|
inputIv = zone.querySelector("input[data-stored-object-iv]"),
|
||||||
inputIv = zone.querySelector('input[data-stored-object-iv]'),
|
inputObject = zone.querySelector("input[data-async-file-upload]"),
|
||||||
inputObject = zone.querySelector('input[data-async-file-upload]'),
|
inputType = zone.querySelector("input[data-async-file-type]");
|
||||||
inputType = zone.querySelector('input[data-async-file-type]')
|
|
||||||
;
|
|
||||||
|
|
||||||
if (zoneData.old === null) {
|
if (zoneData.old === null) {
|
||||||
console.log('should not have restored data');
|
console.log("should not have restored data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,27 +237,21 @@ const restoreDataInForm = (zone, zoneData) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const hasDataInForm = (zone, zoneData) => {
|
const hasDataInForm = (zone, zoneData) => {
|
||||||
var
|
var inputObject = zone.querySelector("input[data-async-file-upload]");
|
||||||
inputObject = zone.querySelector('input[data-async-file-upload]')
|
|
||||||
;
|
|
||||||
|
|
||||||
return inputObject.value.length > 0;
|
return inputObject.value.length > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
var removeDataInForm = (zone, zoneData) => {
|
var removeDataInForm = (zone, zoneData) => {
|
||||||
var
|
var inputKey = zone.querySelector("input[data-stored-object-key]"),
|
||||||
inputKey = zone.querySelector('input[data-stored-object-key]'),
|
inputIv = zone.querySelector("input[data-stored-object-iv]"),
|
||||||
inputIv = zone.querySelector('input[data-stored-object-iv]'),
|
inputObject = zone.querySelector("input[data-async-file-upload]"),
|
||||||
inputObject = zone.querySelector('input[data-async-file-upload]'),
|
inputType = zone.querySelector("input[data-async-file-type]");
|
||||||
inputType = zone.querySelector('input[data-async-file-type]')
|
|
||||||
;
|
|
||||||
|
|
||||||
// store data for future usage
|
// store data for future usage
|
||||||
zoneData.old = {
|
zoneData.old = {
|
||||||
key: inputKey.value,
|
key: inputKey.value,
|
||||||
iv: inputIv.value,
|
iv: inputIv.value,
|
||||||
obj: inputObject.value,
|
obj: inputObject.value,
|
||||||
type: inputType.value
|
type: inputType.value,
|
||||||
};
|
};
|
||||||
// set blank values
|
// set blank values
|
||||||
inputKey.value = "";
|
inputKey.value = "";
|
||||||
@ -272,30 +263,27 @@ var removeDataInForm = (zone, zoneData) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var insertRemoveButton = (zone, zoneData) => {
|
var insertRemoveButton = (zone, zoneData) => {
|
||||||
var
|
var removeButton = document.createElement("a"),
|
||||||
removeButton = document.createElement('a'),
|
cancelButton = document.createElement("a"),
|
||||||
cancelButton = document.createElement('a'),
|
|
||||||
labelRemove = zone.dataset.dictRemove,
|
labelRemove = zone.dataset.dictRemove,
|
||||||
labelCancel = 'Restaurer'
|
labelCancel = "Restaurer";
|
||||||
;
|
removeButton.classList.add("btn", "btn-delete");
|
||||||
|
|
||||||
removeButton.classList.add('btn', 'btn-delete');
|
|
||||||
removeButton.textContent = labelRemove;
|
removeButton.textContent = labelRemove;
|
||||||
|
|
||||||
cancelButton.classList.add('btn', 'btn-cancel');
|
cancelButton.classList.add("btn", "btn-cancel");
|
||||||
cancelButton.textContent = labelCancel;
|
cancelButton.textContent = labelCancel;
|
||||||
|
|
||||||
removeButton.addEventListener('click', (e) => {
|
removeButton.addEventListener("click", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (zoneData.allowRemove === 'true') {
|
if (zoneData.allowRemove === "true") {
|
||||||
removeDataInForm(zone, zoneData);
|
removeDataInForm(zone, zoneData);
|
||||||
cancelButton.addEventListener('click', (e) => {
|
cancelButton.addEventListener("click", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
restoreDataInForm(zone, zoneData);
|
restoreDataInForm(zone, zoneData);
|
||||||
|
|
||||||
cancelButton.remove();
|
cancelButton.remove();
|
||||||
zone.querySelector('.dropzone').remove();
|
zone.querySelector(".dropzone").remove();
|
||||||
|
|
||||||
initialize(zone);
|
initialize(zone);
|
||||||
});
|
});
|
||||||
@ -311,10 +299,7 @@ var insertRemoveButton = (zone, zoneData) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const removeDownloadButton = (zone, zoneData) => {
|
const removeDownloadButton = (zone, zoneData) => {
|
||||||
var
|
var existingButtons = zone.querySelectorAll("a[data-download-button]");
|
||||||
existingButtons = zone.querySelectorAll('a[data-download-button]')
|
|
||||||
;
|
|
||||||
|
|
||||||
// remove existing
|
// remove existing
|
||||||
existingButtons.forEach(function (b) {
|
existingButtons.forEach(function (b) {
|
||||||
b.remove();
|
b.remove();
|
||||||
@ -322,30 +307,27 @@ const removeDownloadButton = (zone, zoneData) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var insertDownloadButton = (zone, zoneData) => {
|
var insertDownloadButton = (zone, zoneData) => {
|
||||||
var
|
var existingButtons = zone.querySelectorAll("a[data-download-button]"),
|
||||||
existingButtons = zone.querySelectorAll('a[data-download-button]'),
|
newButton = document.createElement("a"),
|
||||||
newButton = document.createElement('a'),
|
inputKey = zone.querySelector("input[data-stored-object-key]"),
|
||||||
inputKey = zone.querySelector('input[data-stored-object-key]'),
|
inputIv = zone.querySelector("input[data-stored-object-iv]"),
|
||||||
inputIv = zone.querySelector('input[data-stored-object-iv]'),
|
inputObject = zone.querySelector("input[data-async-file-upload]"),
|
||||||
inputObject = zone.querySelector('input[data-async-file-upload]'),
|
inputType = zone.querySelector("input[data-async-file-type]"),
|
||||||
inputType = zone.querySelector('input[data-async-file-type]'),
|
|
||||||
labelPreparing = zone.dataset.labelPreparing,
|
labelPreparing = zone.dataset.labelPreparing,
|
||||||
labelQuietButton = zone.dataset.labelQuietButton,
|
labelQuietButton = zone.dataset.labelQuietButton,
|
||||||
labelReady = zone.dataset.labelReady,
|
labelReady = zone.dataset.labelReady,
|
||||||
tempUrlGenerator = zone.dataset.tempUrlGenerator,
|
tempUrlGenerator = zone.dataset.tempUrlGenerator,
|
||||||
tempUrlGeneratorParams = new URLSearchParams()
|
tempUrlGeneratorParams = new URLSearchParams();
|
||||||
;
|
|
||||||
|
|
||||||
// remove existing
|
// remove existing
|
||||||
existingButtons.forEach(function (b) {
|
existingButtons.forEach(function (b) {
|
||||||
b.remove();
|
b.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (inputObject.value === '') {
|
if (inputObject.value === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tempUrlGeneratorParams.append('object_name', inputObject.value);
|
tempUrlGeneratorParams.append("object_name", inputObject.value);
|
||||||
|
|
||||||
newButton.dataset.downloadButton = true;
|
newButton.dataset.downloadButton = true;
|
||||||
newButton.dataset.key = inputKey.value;
|
newButton.dataset.key = inputKey.value;
|
||||||
@ -353,8 +335,9 @@ var insertDownloadButton = (zone, zoneData) => {
|
|||||||
newButton.dataset.mimeType = inputType.value;
|
newButton.dataset.mimeType = inputType.value;
|
||||||
newButton.dataset.labelPreparing = labelPreparing;
|
newButton.dataset.labelPreparing = labelPreparing;
|
||||||
newButton.dataset.labelReady = labelReady;
|
newButton.dataset.labelReady = labelReady;
|
||||||
newButton.dataset.tempUrlGetGenerator = tempUrlGenerator + '?' + tempUrlGeneratorParams.toString();
|
newButton.dataset.tempUrlGetGenerator =
|
||||||
newButton.classList.add('btn', 'btn-download', 'dz-bt-below-dropzone');
|
tempUrlGenerator + "?" + tempUrlGeneratorParams.toString();
|
||||||
|
newButton.classList.add("btn", "btn-download", "dz-bt-below-dropzone");
|
||||||
newButton.textContent = labelQuietButton;
|
newButton.textContent = labelQuietButton;
|
||||||
|
|
||||||
addBelowButton(newButton, zone, zoneData);
|
addBelowButton(newButton, zone, zoneData);
|
||||||
@ -362,11 +345,11 @@ var insertDownloadButton = (zone, zoneData) => {
|
|||||||
initializeButtons(zone);
|
initializeButtons(zone);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('load', function(e) {
|
window.addEventListener("load", function (e) {
|
||||||
searchForZones(document);
|
searchForZones(document);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('collection-add-entry', function(e) {
|
window.addEventListener("collection-add-entry", function (e) {
|
||||||
searchForZones(e.detail.entry);
|
searchForZones(e.detail.entry);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,23 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="isButtonGroupDisplayable" class="btn-group">
|
<div v-if="isButtonGroupDisplayable" class="btn-group">
|
||||||
<button :class="Object.assign({'btn': true, 'btn-outline-primary': true, 'dropdown-toggle': true, 'btn-sm': props.small})" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
<button
|
||||||
|
:class="
|
||||||
|
Object.assign({
|
||||||
|
btn: true,
|
||||||
|
'btn-outline-primary': true,
|
||||||
|
'dropdown-toggle': true,
|
||||||
|
'btn-sm': props.small,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
Actions
|
Actions
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li v-if="isEditableOnline">
|
<li v-if="isEditableOnline">
|
||||||
<wopi-edit-button :stored-object="props.storedObject" :classes="{'dropdown-item': true}" :execute-before-leave="props.executeBeforeLeave"></wopi-edit-button>
|
<wopi-edit-button
|
||||||
|
:stored-object="props.storedObject"
|
||||||
|
:classes="{ 'dropdown-item': true }"
|
||||||
|
:execute-before-leave="props.executeBeforeLeave"
|
||||||
|
></wopi-edit-button>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="isEditableOnDesktop">
|
<li v-if="isEditableOnDesktop">
|
||||||
<desktop-edit-button :classes="{'dropdown-item': true}" :edit-link="props.davLink" :expiration-link="props.davLinkExpiration"></desktop-edit-button>
|
<desktop-edit-button
|
||||||
|
:classes="{ 'dropdown-item': true }"
|
||||||
|
:edit-link="props.davLink"
|
||||||
|
:expiration-link="props.davLinkExpiration"
|
||||||
|
></desktop-edit-button>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="isConvertibleToPdf">
|
<li v-if="isConvertibleToPdf">
|
||||||
<convert-button :stored-object="props.storedObject" :filename="filename" :classes="{'dropdown-item': true}"></convert-button>
|
<convert-button
|
||||||
|
:stored-object="props.storedObject"
|
||||||
|
:filename="filename"
|
||||||
|
:classes="{ 'dropdown-item': true }"
|
||||||
|
></convert-button>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="isDownloadable">
|
<li v-if="isDownloadable">
|
||||||
<download-button :stored-object="props.storedObject" :at-version="props.storedObject.currentVersion" :filename="filename" :classes="{'dropdown-item': true}" :display-action-string-in-button="true"></download-button>
|
<download-button
|
||||||
|
:stored-object="props.storedObject"
|
||||||
|
:at-version="props.storedObject.currentVersion"
|
||||||
|
:filename="filename"
|
||||||
|
:classes="{ 'dropdown-item': true }"
|
||||||
|
:display-action-string-in-button="true"
|
||||||
|
></download-button>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="isHistoryViewable">
|
<li v-if="isHistoryViewable">
|
||||||
<history-button :stored-object="props.storedObject" :can-edit="canEdit && props.storedObject._permissions.canEdit"></history-button>
|
<history-button
|
||||||
|
:stored-object="props.storedObject"
|
||||||
|
:can-edit="
|
||||||
|
canEdit && props.storedObject._permissions.canEdit
|
||||||
|
"
|
||||||
|
></history-button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -27,31 +62,34 @@
|
|||||||
<div v-else-if="'failure' === props.storedObject.status">
|
<div v-else-if="'failure' === props.storedObject.status">
|
||||||
<div class="btn btn-outline-danger">La génération a échoué</div>
|
<div class="btn btn-outline-danger">La génération a échoué</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
||||||
import { computed, onMounted } from "vue";
|
import { computed, onMounted } from "vue";
|
||||||
import ConvertButton from "./StoredObjectButton/ConvertButton.vue";
|
import ConvertButton from "./StoredObjectButton/ConvertButton.vue";
|
||||||
import DownloadButton from "./StoredObjectButton/DownloadButton.vue";
|
import DownloadButton from "./StoredObjectButton/DownloadButton.vue";
|
||||||
import WopiEditButton from "./StoredObjectButton/WopiEditButton.vue";
|
import WopiEditButton from "./StoredObjectButton/WopiEditButton.vue";
|
||||||
import {is_extension_editable, is_extension_viewable, is_object_ready} from "./StoredObjectButton/helpers";
|
import {
|
||||||
|
is_extension_editable,
|
||||||
|
is_extension_viewable,
|
||||||
|
is_object_ready,
|
||||||
|
} from "./StoredObjectButton/helpers";
|
||||||
import {
|
import {
|
||||||
StoredObject,
|
StoredObject,
|
||||||
StoredObjectStatusChange, StoredObjectVersion,
|
StoredObjectStatusChange,
|
||||||
WopiEditButtonExecutableBeforeLeaveFunction
|
StoredObjectVersion,
|
||||||
|
WopiEditButtonExecutableBeforeLeaveFunction,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import DesktopEditButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/DesktopEditButton.vue";
|
import DesktopEditButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/DesktopEditButton.vue";
|
||||||
import HistoryButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton.vue";
|
import HistoryButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton.vue";
|
||||||
|
|
||||||
interface DocumentActionButtonsGroupConfig {
|
interface DocumentActionButtonsGroupConfig {
|
||||||
storedObject: StoredObject,
|
storedObject: StoredObject;
|
||||||
small?: boolean,
|
small?: boolean;
|
||||||
canEdit?: boolean,
|
canEdit?: boolean;
|
||||||
canDownload?: boolean,
|
canDownload?: boolean;
|
||||||
canConvertPdf?: boolean,
|
canConvertPdf?: boolean;
|
||||||
returnPath?: string,
|
returnPath?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will be the filename displayed to the user when he·she download the document
|
* Will be the filename displayed to the user when he·she download the document
|
||||||
@ -59,34 +97,41 @@ interface DocumentActionButtonsGroupConfig {
|
|||||||
*
|
*
|
||||||
* If not set, 'document' will be used.
|
* If not set, 'document' will be used.
|
||||||
*/
|
*/
|
||||||
filename?: string,
|
filename?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set, will execute this function before leaving to the editor
|
* If set, will execute this function before leaving to the editor
|
||||||
*/
|
*/
|
||||||
executeBeforeLeave?: WopiEditButtonExecutableBeforeLeaveFunction,
|
executeBeforeLeave?: WopiEditButtonExecutableBeforeLeaveFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a link to download and edit file using webdav
|
* a link to download and edit file using webdav
|
||||||
*/
|
*/
|
||||||
davLink?: string,
|
davLink?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the expiration date of the download, as a unix timestamp
|
* the expiration date of the download, as a unix timestamp
|
||||||
*/
|
*/
|
||||||
davLinkExpiration?: number,
|
davLinkExpiration?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit =
|
||||||
(e: 'onStoredObjectStatusChange', newStatus: StoredObjectStatusChange): void
|
defineEmits<
|
||||||
}>();
|
(
|
||||||
|
e: "onStoredObjectStatusChange",
|
||||||
|
newStatus: StoredObjectStatusChange,
|
||||||
|
) => void
|
||||||
|
>();
|
||||||
|
|
||||||
const props = withDefaults(defineProps<DocumentActionButtonsGroupConfig>(), {
|
const props = withDefaults(defineProps<DocumentActionButtonsGroupConfig>(), {
|
||||||
small: false,
|
small: false,
|
||||||
canEdit: true,
|
canEdit: true,
|
||||||
canDownload: true,
|
canDownload: true,
|
||||||
canConvertPdf: true,
|
canConvertPdf: true,
|
||||||
returnPath: window.location.pathname + window.location.search + window.location.hash
|
returnPath:
|
||||||
|
window.location.pathname +
|
||||||
|
window.location.search +
|
||||||
|
window.location.hash,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,22 +145,32 @@ let tryiesForReady = 0;
|
|||||||
const maxTryiesForReady = 120;
|
const maxTryiesForReady = 120;
|
||||||
|
|
||||||
const isButtonGroupDisplayable = computed<boolean>(() => {
|
const isButtonGroupDisplayable = computed<boolean>(() => {
|
||||||
return isDownloadable.value || isEditableOnline.value || isEditableOnDesktop.value || isConvertibleToPdf.value;
|
return (
|
||||||
|
isDownloadable.value ||
|
||||||
|
isEditableOnline.value ||
|
||||||
|
isEditableOnDesktop.value ||
|
||||||
|
isConvertibleToPdf.value
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const isDownloadable = computed<boolean>(() => {
|
const isDownloadable = computed<boolean>(() => {
|
||||||
return props.storedObject.status === 'ready'
|
return (
|
||||||
|
props.storedObject.status === "ready" ||
|
||||||
// happens when the stored object version is just added, but not persisted
|
// happens when the stored object version is just added, but not persisted
|
||||||
|| (props.storedObject.currentVersion !== null && props.storedObject.status === 'empty')
|
(props.storedObject.currentVersion !== null &&
|
||||||
|
props.storedObject.status === "empty")
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const isEditableOnline = computed<boolean>(() => {
|
const isEditableOnline = computed<boolean>(() => {
|
||||||
return props.storedObject.status === 'ready'
|
return (
|
||||||
&& props.storedObject._permissions.canEdit
|
props.storedObject.status === "ready" &&
|
||||||
&& props.canEdit
|
props.storedObject._permissions.canEdit &&
|
||||||
&& props.storedObject.currentVersion !== null
|
props.canEdit &&
|
||||||
&& is_extension_editable(props.storedObject.currentVersion.type)
|
props.storedObject.currentVersion !== null &&
|
||||||
&& props.storedObject.currentVersion.persisted !== false;
|
is_extension_editable(props.storedObject.currentVersion.type) &&
|
||||||
|
props.storedObject.currentVersion.persisted !== false
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const isEditableOnDesktop = computed<boolean>(() => {
|
const isEditableOnDesktop = computed<boolean>(() => {
|
||||||
@ -123,26 +178,28 @@ const isEditableOnDesktop = computed<boolean>(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const isConvertibleToPdf = computed<boolean>(() => {
|
const isConvertibleToPdf = computed<boolean>(() => {
|
||||||
return props.storedObject.status === 'ready'
|
return (
|
||||||
&& props.storedObject._permissions.canSee
|
props.storedObject.status === "ready" &&
|
||||||
&& props.canConvertPdf
|
props.storedObject._permissions.canSee &&
|
||||||
&& props.storedObject.currentVersion !== null
|
props.canConvertPdf &&
|
||||||
&& is_extension_viewable(props.storedObject.currentVersion.type)
|
props.storedObject.currentVersion !== null &&
|
||||||
&& props.storedObject.currentVersion.type !== 'application/pdf'
|
is_extension_viewable(props.storedObject.currentVersion.type) &&
|
||||||
&& props.storedObject.currentVersion.persisted !== false;
|
props.storedObject.currentVersion.type !== "application/pdf" &&
|
||||||
|
props.storedObject.currentVersion.persisted !== false
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const isHistoryViewable = computed<boolean>(() => {
|
const isHistoryViewable = computed<boolean>(() => {
|
||||||
return props.storedObject.status === 'ready';
|
return props.storedObject.status === "ready";
|
||||||
});
|
});
|
||||||
|
|
||||||
const checkForReady = function (): void {
|
const checkForReady = function (): void {
|
||||||
if (
|
if (
|
||||||
'ready' === props.storedObject.status
|
"ready" === props.storedObject.status ||
|
||||||
|| 'empty' === props.storedObject.status
|
"empty" === props.storedObject.status ||
|
||||||
|| 'failure' === props.storedObject.status
|
"failure" === props.storedObject.status ||
|
||||||
// stop reloading if the page stays opened for a long time
|
// stop reloading if the page stays opened for a long time
|
||||||
|| tryiesForReady > maxTryiesForReady
|
tryiesForReady > maxTryiesForReady
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -153,20 +210,19 @@ const checkForReady = function(): void {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onObjectNewStatusCallback = async function (): Promise<void> {
|
const onObjectNewStatusCallback = async function (): Promise<void> {
|
||||||
|
if (props.storedObject.status === "stored_object_created") {
|
||||||
if (props.storedObject.status === 'stored_object_created') {
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
const new_status = await is_object_ready(props.storedObject);
|
const new_status = await is_object_ready(props.storedObject);
|
||||||
if (props.storedObject.status !== new_status.status) {
|
if (props.storedObject.status !== new_status.status) {
|
||||||
emit('onStoredObjectStatusChange', new_status);
|
emit("onStoredObjectStatusChange", new_status);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} else if ('failure' === new_status.status) {
|
} else if ("failure" === new_status.status) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('ready' !== new_status.status) {
|
if ("ready" !== new_status.status) {
|
||||||
// we check for new status, unless it is ready
|
// we check for new status, unless it is ready
|
||||||
checkForReady();
|
checkForReady();
|
||||||
}
|
}
|
||||||
@ -176,9 +232,7 @@ const onObjectNewStatusCallback = async function(): Promise<void> {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
checkForReady();
|
checkForReady();
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -27,7 +27,9 @@
|
|||||||
</modal>
|
</modal>
|
||||||
</teleport>
|
</teleport>
|
||||||
<div class="col-12 m-auto sticky-top">
|
<div class="col-12 m-auto sticky-top">
|
||||||
<div class="row justify-content-center border-bottom pdf-tools d-md-none">
|
<div
|
||||||
|
class="row justify-content-center border-bottom pdf-tools d-md-none"
|
||||||
|
>
|
||||||
<div class="col-5 text-center turn-page">
|
<div class="col-5 text-center turn-page">
|
||||||
<select
|
<select
|
||||||
class="form-select form-select-sm"
|
class="form-select form-select-sm"
|
||||||
@ -89,7 +91,10 @@
|
|||||||
class="col-5 p-0 text-center turnSignature"
|
class="col-5 p-0 text-center turnSignature"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
:disabled="userSignatureZone === null || userSignatureZone?.index < 1"
|
:disabled="
|
||||||
|
userSignatureZone === null ||
|
||||||
|
userSignatureZone?.index < 1
|
||||||
|
"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(-1)"
|
@click="turnSignature(-1)"
|
||||||
>
|
>
|
||||||
@ -97,7 +102,9 @@
|
|||||||
</button>
|
</button>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<button
|
<button
|
||||||
:disabled="userSignatureZone?.index >= signature.zones.length - 1"
|
:disabled="
|
||||||
|
userSignatureZone?.index >= signature.zones.length - 1
|
||||||
|
"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(1)"
|
@click="turnSignature(1)"
|
||||||
>
|
>
|
||||||
@ -135,7 +142,10 @@
|
|||||||
:title="$t('add_sign_zone')"
|
:title="$t('add_sign_zone')"
|
||||||
>
|
>
|
||||||
<template v-if="canvasEvent === 'add'">
|
<template v-if="canvasEvent === 'add'">
|
||||||
<div class="spinner-border spinner-border-sm" role="status">
|
<div
|
||||||
|
class="spinner-border spinner-border-sm"
|
||||||
|
role="status"
|
||||||
|
>
|
||||||
<span class="visually-hidden">Loading...</span>
|
<span class="visually-hidden">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -190,7 +200,10 @@
|
|||||||
class="col-4 d-xl-none text-center turnSignature p-0"
|
class="col-4 d-xl-none text-center turnSignature p-0"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
:disabled="userSignatureZone === null || userSignatureZone?.index < 1"
|
:disabled="
|
||||||
|
userSignatureZone === null ||
|
||||||
|
userSignatureZone?.index < 1
|
||||||
|
"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(-1)"
|
@click="turnSignature(-1)"
|
||||||
>
|
>
|
||||||
@ -198,7 +211,9 @@
|
|||||||
</button>
|
</button>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<button
|
<button
|
||||||
:disabled="userSignatureZone?.index >= signature.zones.length - 1"
|
:disabled="
|
||||||
|
userSignatureZone?.index >= signature.zones.length - 1
|
||||||
|
"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(1)"
|
@click="turnSignature(1)"
|
||||||
>
|
>
|
||||||
@ -210,7 +225,10 @@
|
|||||||
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
:disabled="userSignatureZone === null || userSignatureZone?.index < 1"
|
:disabled="
|
||||||
|
userSignatureZone === null ||
|
||||||
|
userSignatureZone?.index < 1
|
||||||
|
"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(-1)"
|
@click="turnSignature(-1)"
|
||||||
>
|
>
|
||||||
@ -218,7 +236,9 @@
|
|||||||
</button>
|
</button>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<button
|
<button
|
||||||
:disabled="userSignatureZone?.index >= signature.zones.length - 1"
|
:disabled="
|
||||||
|
userSignatureZone?.index >= signature.zones.length - 1
|
||||||
|
"
|
||||||
class="btn btn-light btn-sm"
|
class="btn btn-light btn-sm"
|
||||||
@click="turnSignature(1)"
|
@click="turnSignature(1)"
|
||||||
>
|
>
|
||||||
@ -259,7 +279,10 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ $t("click_on_document") }}
|
{{ $t("click_on_document") }}
|
||||||
<div class="spinner-border spinner-border-sm" role="status">
|
<div
|
||||||
|
class="spinner-border spinner-border-sm"
|
||||||
|
role="status"
|
||||||
|
>
|
||||||
<span class="visually-hidden">Loading...</span>
|
<span class="visually-hidden">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -336,7 +359,10 @@ console.log(PdfWorker); // incredible but this is needed
|
|||||||
// pdfjsLib.GlobalWorkerOptions.workerSrc = PdfWorker;
|
// pdfjsLib.GlobalWorkerOptions.workerSrc = PdfWorker;
|
||||||
|
|
||||||
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
||||||
import {download_and_decrypt_doc, download_doc_as_pdf} from "../StoredObjectButton/helpers";
|
import {
|
||||||
|
download_and_decrypt_doc,
|
||||||
|
download_doc_as_pdf,
|
||||||
|
} from "../StoredObjectButton/helpers";
|
||||||
|
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.mjs";
|
pdfjsLib.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.mjs";
|
||||||
|
|
||||||
@ -479,12 +505,18 @@ const addCanvasEvents = () => {
|
|||||||
canvas.addEventListener(
|
canvas.addEventListener(
|
||||||
"pointerup",
|
"pointerup",
|
||||||
(e) => canvasClick(e, canvas),
|
(e) => canvasClick(e, canvas),
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const canvas = document.querySelectorAll("canvas")[0] as HTMLCanvasElement;
|
const canvas = document.querySelectorAll(
|
||||||
canvas.addEventListener("pointerup", (e) => canvasClick(e, canvas), false);
|
"canvas",
|
||||||
|
)[0] as HTMLCanvasElement;
|
||||||
|
canvas.addEventListener(
|
||||||
|
"pointerup",
|
||||||
|
(e) => canvasClick(e, canvas),
|
||||||
|
false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -511,7 +543,7 @@ const scaleYToCanvas = (h: number, canvasHeight: number, PDFHeight: number) =>
|
|||||||
const hitSignature = (
|
const hitSignature = (
|
||||||
zone: SignatureZone,
|
zone: SignatureZone,
|
||||||
xy: number[],
|
xy: number[],
|
||||||
canvas: HTMLCanvasElement
|
canvas: HTMLCanvasElement,
|
||||||
) =>
|
) =>
|
||||||
scaleXToCanvas(zone.x, canvas.width, zone.PDFPage.width) < xy[0] &&
|
scaleXToCanvas(zone.x, canvas.width, zone.PDFPage.width) < xy[0] &&
|
||||||
xy[0] <
|
xy[0] <
|
||||||
@ -520,7 +552,11 @@ const hitSignature = (
|
|||||||
scaleYToCanvas(zone.y, canvas.height, zone.PDFPage.height) <
|
scaleYToCanvas(zone.y, canvas.height, zone.PDFPage.height) <
|
||||||
xy[1] &&
|
xy[1] &&
|
||||||
xy[1] <
|
xy[1] <
|
||||||
scaleYToCanvas(zone.height - zone.y, canvas.height, zone.PDFPage.height) +
|
scaleYToCanvas(
|
||||||
|
zone.height - zone.y,
|
||||||
|
canvas.height,
|
||||||
|
zone.PDFPage.height,
|
||||||
|
) +
|
||||||
zone.PDFPage.height * zoom.value;
|
zone.PDFPage.height * zoom.value;
|
||||||
|
|
||||||
const selectZone = async (z: SignatureZone, canvas: HTMLCanvasElement) => {
|
const selectZone = async (z: SignatureZone, canvas: HTMLCanvasElement) => {
|
||||||
@ -536,8 +572,9 @@ const selectZoneEvent = (e: PointerEvent, canvas: HTMLCanvasElement) =>
|
|||||||
signature.zones
|
signature.zones
|
||||||
.filter(
|
.filter(
|
||||||
(z) =>
|
(z) =>
|
||||||
(z.PDFPage.index + 1 === getCanvasId(canvas) && multiPage.value) ||
|
(z.PDFPage.index + 1 === getCanvasId(canvas) &&
|
||||||
(z.PDFPage.index + 1 === page.value && !multiPage.value)
|
multiPage.value) ||
|
||||||
|
(z.PDFPage.index + 1 === page.value && !multiPage.value),
|
||||||
)
|
)
|
||||||
.map((z) => {
|
.map((z) => {
|
||||||
if (hitSignature(z, [e.offsetX, e.offsetY], canvas)) {
|
if (hitSignature(z, [e.offsetX, e.offsetY], canvas)) {
|
||||||
@ -590,7 +627,7 @@ const drawZone = (
|
|||||||
zone: SignatureZone,
|
zone: SignatureZone,
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
canvasWidth: number,
|
canvasWidth: number,
|
||||||
canvasHeight: number
|
canvasHeight: number,
|
||||||
) => {
|
) => {
|
||||||
const unselectedBlue = "#007bff";
|
const unselectedBlue = "#007bff";
|
||||||
const selectedBlue = "#034286";
|
const selectedBlue = "#034286";
|
||||||
@ -605,7 +642,7 @@ const drawZone = (
|
|||||||
zone.PDFPage.height * zoom.value -
|
zone.PDFPage.height * zoom.value -
|
||||||
scaleYToCanvas(zone.y, canvasHeight, zone.PDFPage.height),
|
scaleYToCanvas(zone.y, canvasHeight, zone.PDFPage.height),
|
||||||
scaleXToCanvas(zone.width, canvasWidth, zone.PDFPage.width),
|
scaleXToCanvas(zone.width, canvasWidth, zone.PDFPage.width),
|
||||||
scaleYToCanvas(zone.height, canvasHeight, zone.PDFPage.height)
|
scaleYToCanvas(zone.height, canvasHeight, zone.PDFPage.height),
|
||||||
);
|
);
|
||||||
ctx.font = `bold ${16 * zoom.value}px serif`;
|
ctx.font = `bold ${16 * zoom.value}px serif`;
|
||||||
ctx.textAlign = "center";
|
ctx.textAlign = "center";
|
||||||
@ -633,7 +670,7 @@ const drawAllZones = () => {
|
|||||||
.filter(
|
.filter(
|
||||||
(z) =>
|
(z) =>
|
||||||
multiPage.value ||
|
multiPage.value ||
|
||||||
(z.PDFPage.index + 1 === page.value && !multiPage.value)
|
(z.PDFPage.index + 1 === page.value && !multiPage.value),
|
||||||
)
|
)
|
||||||
.map((z) => {
|
.map((z) => {
|
||||||
const canvas = getCanvas(z.PDFPage.index + 1);
|
const canvas = getCanvas(z.PDFPage.index + 1);
|
||||||
@ -663,7 +700,7 @@ const checkSignature = () => {
|
|||||||
signedState.value = "error";
|
signedState.value = "error";
|
||||||
console.log("Error while checking the signature", error);
|
console.log("Error while checking the signature", error);
|
||||||
$toast.error(
|
$toast.error(
|
||||||
`Erreur lors de la vérification de la signature: ${error.txt}`
|
`Erreur lors de la vérification de la signature: ${error.txt}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -682,7 +719,7 @@ const checkForReady = () => {
|
|||||||
tryForReady = 0;
|
tryForReady = 0;
|
||||||
console.log("Reached the maximum number of tentative to try signing");
|
console.log("Reached the maximum number of tentative to try signing");
|
||||||
$toast.error(
|
$toast.error(
|
||||||
"Le nombre maximum de tentatives pour essayer de signer est atteint"
|
"Le nombre maximum de tentatives pour essayer de signer est atteint",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (signedState.value === "rejected") {
|
if (signedState.value === "rejected") {
|
||||||
@ -724,7 +761,7 @@ const confirmSign = () => {
|
|||||||
console.log("Error while posting the signature", error);
|
console.log("Error while posting the signature", error);
|
||||||
stopTrySigning();
|
stopTrySigning();
|
||||||
$toast.error(
|
$toast.error(
|
||||||
`Erreur lors de la soumission de la signature: ${error.txt}`
|
`Erreur lors de la soumission de la signature: ${error.txt}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -780,8 +817,8 @@ const addZoneEvent = async (e: PointerEvent, canvas: HTMLCanvasElement) => {
|
|||||||
|
|
||||||
const getReturnPath = () =>
|
const getReturnPath = () =>
|
||||||
window.location.search
|
window.location.search
|
||||||
? window.location.search.split("?returnPath=")[1] ??
|
? (window.location.search.split("?returnPath=")[1] ??
|
||||||
window.location.pathname
|
window.location.pathname)
|
||||||
: window.location.pathname;
|
: window.location.pathname;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
@ -842,4 +879,3 @@ div.signature-modal-body {
|
|||||||
height: 8rem;
|
height: 8rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -1,19 +1,31 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import { StoredObject, StoredObjectVersionCreated } from "../../types";
|
import { StoredObject, StoredObjectVersionCreated } from "../../types";
|
||||||
import {encryptFile, fetchNewStoredObject, uploadVersion} from "../../js/async-upload/uploader";
|
import {
|
||||||
|
encryptFile,
|
||||||
|
fetchNewStoredObject,
|
||||||
|
uploadVersion,
|
||||||
|
} from "../../js/async-upload/uploader";
|
||||||
import { computed, ref, Ref } from "vue";
|
import { computed, ref, Ref } from "vue";
|
||||||
import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue";
|
import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue";
|
||||||
|
|
||||||
interface DropFileConfig {
|
interface DropFileConfig {
|
||||||
existingDoc?: StoredObject,
|
existingDoc?: StoredObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<DropFileConfig>(), {existingDoc: null});
|
const props = withDefaults(defineProps<DropFileConfig>(), {
|
||||||
|
existingDoc: null,
|
||||||
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit =
|
||||||
(e: 'addDocument', {stored_object_version: StoredObjectVersionCreated, stored_object: StoredObject}): void,
|
defineEmits<
|
||||||
}>();
|
(
|
||||||
|
e: "addDocument",
|
||||||
|
{
|
||||||
|
stored_object_version: StoredObjectVersionCreated,
|
||||||
|
stored_object: StoredObject,
|
||||||
|
},
|
||||||
|
) => void
|
||||||
|
>();
|
||||||
|
|
||||||
const is_dragging: Ref<boolean> = ref(false);
|
const is_dragging: Ref<boolean> = ref(false);
|
||||||
const uploading: Ref<boolean> = ref(false);
|
const uploading: Ref<boolean> = ref(false);
|
||||||
@ -27,13 +39,13 @@ const onDragOver = (e: Event) => {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
is_dragging.value = true;
|
is_dragging.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
const onDragLeave = (e: Event) => {
|
const onDragLeave = (e: Event) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
is_dragging.value = false;
|
is_dragging.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
const onDrop = (e: DragEvent) => {
|
const onDrop = (e: DragEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -49,8 +61,8 @@ const onDrop = (e: DragEvent) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFile(files[0])
|
handleFile(files[0]);
|
||||||
}
|
};
|
||||||
|
|
||||||
const onZoneClick = (e: Event) => {
|
const onZoneClick = (e: Event) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -61,21 +73,21 @@ const onZoneClick = (e: Event) => {
|
|||||||
input.addEventListener("change", onFileChange);
|
input.addEventListener("change", onFileChange);
|
||||||
|
|
||||||
input.click();
|
input.click();
|
||||||
}
|
};
|
||||||
|
|
||||||
const onFileChange = async (event: Event): Promise<void> => {
|
const onFileChange = async (event: Event): Promise<void> => {
|
||||||
const input = event.target as HTMLInputElement;
|
const input = event.target as HTMLInputElement;
|
||||||
|
|
||||||
if (input.files && input.files[0]) {
|
if (input.files && input.files[0]) {
|
||||||
console.log('file added', input.files[0]);
|
console.log("file added", input.files[0]);
|
||||||
const file = input.files[0];
|
const file = input.files[0];
|
||||||
await handleFile(file);
|
await handleFile(file);
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw 'No file given';
|
throw "No file given";
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleFile = async (file: File): Promise<void> => {
|
const handleFile = async (file: File): Promise<void> => {
|
||||||
uploading.value = true;
|
uploading.value = true;
|
||||||
@ -100,25 +112,39 @@ const handleFile = async (file: File): Promise<void> => {
|
|||||||
keyInfos: jsonWebKey,
|
keyInfos: jsonWebKey,
|
||||||
type: type,
|
type: type,
|
||||||
persisted: false,
|
persisted: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
emit('addDocument', {stored_object, stored_object_version});
|
emit("addDocument", { stored_object, stored_object_version });
|
||||||
uploading.value = false;
|
uploading.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="drop-file">
|
<div class="drop-file">
|
||||||
<div v-if="!uploading" :class="{ area: true, dragging: is_dragging}" @click="onZoneClick" @dragover="onDragOver" @dragleave="onDragLeave" @drop="onDrop">
|
<div
|
||||||
|
v-if="!uploading"
|
||||||
|
:class="{ area: true, dragging: is_dragging }"
|
||||||
|
@click="onZoneClick"
|
||||||
|
@dragover="onDragOver"
|
||||||
|
@dragleave="onDragLeave"
|
||||||
|
@drop="onDrop"
|
||||||
|
>
|
||||||
<p v-if="has_existing_doc" class="file-icon">
|
<p v-if="has_existing_doc" class="file-icon">
|
||||||
<file-icon :type="props.existingDoc?.type"></file-icon>
|
<file-icon :type="props.existingDoc?.type"></file-icon>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p v-if="display_filename !== null" class="display-filename">{{ display_filename }}</p>
|
<p v-if="display_filename !== null" class="display-filename">
|
||||||
|
{{ display_filename }}
|
||||||
|
</p>
|
||||||
<!-- todo i18n -->
|
<!-- todo i18n -->
|
||||||
<p v-if="has_existing_doc">Déposez un document ou cliquez ici pour remplacer le document existant</p>
|
<p v-if="has_existing_doc">
|
||||||
<p v-else>Déposez un document ou cliquez ici pour ouvrir le navigateur de fichier</p>
|
Déposez un document ou cliquez ici pour remplacer le document
|
||||||
|
existant
|
||||||
|
</p>
|
||||||
|
<p v-else>
|
||||||
|
Déposez un document ou cliquez ici pour ouvrir le navigateur de
|
||||||
|
fichier
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="waiting">
|
<div v-else class="waiting">
|
||||||
<i class="fa fa-cog fa-spin fa-3x fa-fw"></i>
|
<i class="fa fa-cog fa-spin fa-3x fa-fw"></i>
|
||||||
@ -140,7 +166,8 @@ const handleFile = async (file: File): Promise<void> => {
|
|||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .area, & > .waiting {
|
& > .area,
|
||||||
|
& > .waiting {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 10rem;
|
height: 10rem;
|
||||||
|
|
||||||
@ -163,5 +190,4 @@ const handleFile = async (file: File): Promise<void> => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
||||||
import { StoredObject, StoredObjectVersion } from "../../types";
|
import { StoredObject, StoredObjectVersion } from "../../types";
|
||||||
import DropFileWidget from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileWidget.vue";
|
import DropFileWidget from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileWidget.vue";
|
||||||
import { computed, reactive } from "vue";
|
import { computed, reactive } from "vue";
|
||||||
import {useToast} from 'vue-toast-notification';
|
import { useToast } from "vue-toast-notification";
|
||||||
|
|
||||||
interface DropFileConfig {
|
interface DropFileConfig {
|
||||||
allowRemove: boolean,
|
allowRemove: boolean;
|
||||||
existingDoc?: StoredObject,
|
existingDoc?: StoredObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<DropFileConfig>(), {
|
const props = withDefaults(defineProps<DropFileConfig>(), {
|
||||||
@ -16,8 +15,14 @@ const props = withDefaults(defineProps<DropFileConfig>(), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'addDocument', {stored_object: StoredObject, stored_object_version: StoredObjectVersion}): void,
|
(
|
||||||
(e: 'removeDocument'): void
|
e: "addDocument",
|
||||||
|
{
|
||||||
|
stored_object: StoredObject,
|
||||||
|
stored_object_version: StoredObjectVersion,
|
||||||
|
},
|
||||||
|
): void;
|
||||||
|
(e: "removeDocument"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const $toast = useToast();
|
const $toast = useToast();
|
||||||
@ -26,23 +31,30 @@ const state = reactive({showModal: false});
|
|||||||
|
|
||||||
const modalClasses = { "modal-dialog-centered": true, "modal-md": true };
|
const modalClasses = { "modal-dialog-centered": true, "modal-md": true };
|
||||||
|
|
||||||
const buttonState = computed<'add'|'replace'>(() => {
|
const buttonState = computed<"add" | "replace">(() => {
|
||||||
if (props.existingDoc === undefined || props.existingDoc === null) {
|
if (props.existingDoc === undefined || props.existingDoc === null) {
|
||||||
return 'add';
|
return "add";
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'replace';
|
return "replace";
|
||||||
})
|
});
|
||||||
|
|
||||||
function onAddDocument({stored_object, stored_object_version}: {stored_object: StoredObject, stored_object_version: StoredObjectVersion}): void {
|
function onAddDocument({
|
||||||
const message = buttonState.value === 'add' ? "Document ajouté" : "Document remplacé";
|
stored_object,
|
||||||
|
stored_object_version,
|
||||||
|
}: {
|
||||||
|
stored_object: StoredObject;
|
||||||
|
stored_object_version: StoredObjectVersion;
|
||||||
|
}): void {
|
||||||
|
const message =
|
||||||
|
buttonState.value === "add" ? "Document ajouté" : "Document remplacé";
|
||||||
$toast.success(message);
|
$toast.success(message);
|
||||||
emit('addDocument', {stored_object_version, stored_object});
|
emit("addDocument", { stored_object_version, stored_object });
|
||||||
state.showModal = false;
|
state.showModal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRemoveDocument(): void {
|
function onRemoveDocument(): void {
|
||||||
emit('removeDocument');
|
emit("removeDocument");
|
||||||
}
|
}
|
||||||
|
|
||||||
function openModal(): void {
|
function openModal(): void {
|
||||||
@ -55,15 +67,30 @@ function closeModal(): void {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<button v-if="buttonState === 'add'" @click="openModal" class="btn btn-create">Ajouter un document</button>
|
<button
|
||||||
<button v-else @click="openModal" class="btn btn-edit">Remplacer le document</button>
|
v-if="buttonState === 'add'"
|
||||||
<modal v-if="state.showModal" :modal-dialog-class="modalClasses" @close="closeModal">
|
@click="openModal"
|
||||||
|
class="btn btn-create"
|
||||||
|
>
|
||||||
|
Ajouter un document
|
||||||
|
</button>
|
||||||
|
<button v-else @click="openModal" class="btn btn-edit">
|
||||||
|
Remplacer le document
|
||||||
|
</button>
|
||||||
|
<modal
|
||||||
|
v-if="state.showModal"
|
||||||
|
:modal-dialog-class="modalClasses"
|
||||||
|
@close="closeModal"
|
||||||
|
>
|
||||||
<template v-slot:body>
|
<template v-slot:body>
|
||||||
<drop-file-widget :existing-doc="existingDoc" :allow-remove="allowRemove" @add-document="onAddDocument" @remove-document="onRemoveDocument" ></drop-file-widget>
|
<drop-file-widget
|
||||||
|
:existing-doc="existingDoc"
|
||||||
|
:allow-remove="allowRemove"
|
||||||
|
@add-document="onAddDocument"
|
||||||
|
@remove-document="onRemoveDocument"
|
||||||
|
></drop-file-widget>
|
||||||
</template>
|
</template>
|
||||||
</modal>
|
</modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import { StoredObject, StoredObjectVersion } from "../../types";
|
import { StoredObject, StoredObjectVersion } from "../../types";
|
||||||
import { computed, ref, Ref } from "vue";
|
import { computed, ref, Ref } from "vue";
|
||||||
import DropFile from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFile.vue";
|
import DropFile from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFile.vue";
|
||||||
import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue";
|
import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue";
|
||||||
|
|
||||||
interface DropFileConfig {
|
interface DropFileConfig {
|
||||||
allowRemove: boolean,
|
allowRemove: boolean;
|
||||||
existingDoc?: StoredObject,
|
existingDoc?: StoredObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<DropFileConfig>(), {
|
const props = withDefaults(defineProps<DropFileConfig>(), {
|
||||||
@ -15,8 +14,14 @@ const props = withDefaults(defineProps<DropFileConfig>(), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'addDocument', {stored_object: StoredObject, stored_object_version: StoredObjectVersion}): void,
|
(
|
||||||
(e: 'removeDocument'): void
|
e: "addDocument",
|
||||||
|
{
|
||||||
|
stored_object: StoredObject,
|
||||||
|
stored_object_version: StoredObjectVersion,
|
||||||
|
},
|
||||||
|
): void;
|
||||||
|
(e: "removeDocument"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const has_existing_doc = computed<boolean>(() => {
|
const has_existing_doc = computed<boolean>(() => {
|
||||||
@ -27,7 +32,7 @@ const dav_link_expiration = computed<number|undefined>(() => {
|
|||||||
if (props.existingDoc === undefined || props.existingDoc === null) {
|
if (props.existingDoc === undefined || props.existingDoc === null) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (props.existingDoc.status !== 'ready') {
|
if (props.existingDoc.status !== "ready") {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,28 +43,36 @@ const dav_link_href = computed<string|undefined>(() => {
|
|||||||
if (props.existingDoc === undefined || props.existingDoc === null) {
|
if (props.existingDoc === undefined || props.existingDoc === null) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (props.existingDoc.status !== 'ready') {
|
if (props.existingDoc.status !== "ready") {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return props.existingDoc._links?.dav_link?.href;
|
return props.existingDoc._links?.dav_link?.href;
|
||||||
})
|
});
|
||||||
|
|
||||||
const onAddDocument = ({stored_object, stored_object_version}: {stored_object: StoredObject, stored_object_version: StoredObjectVersion}): void => {
|
const onAddDocument = ({
|
||||||
emit('addDocument', {stored_object, stored_object_version});
|
stored_object,
|
||||||
}
|
stored_object_version,
|
||||||
|
}: {
|
||||||
|
stored_object: StoredObject;
|
||||||
|
stored_object_version: StoredObjectVersion;
|
||||||
|
}): void => {
|
||||||
|
emit("addDocument", { stored_object, stored_object_version });
|
||||||
|
};
|
||||||
|
|
||||||
const onRemoveDocument = (e: Event): void => {
|
const onRemoveDocument = (e: Event): void => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
emit('removeDocument');
|
emit("removeDocument");
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<drop-file :existingDoc="props.existingDoc" @addDocument="onAddDocument"></drop-file>
|
<drop-file
|
||||||
|
:existingDoc="props.existingDoc"
|
||||||
|
@addDocument="onAddDocument"
|
||||||
|
></drop-file>
|
||||||
|
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li v-if="has_existing_doc">
|
<li v-if="has_existing_doc">
|
||||||
@ -72,12 +85,14 @@ const onRemoveDocument = (e: Event): void => {
|
|||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button v-if="allowRemove" class="btn btn-delete" @click="onRemoveDocument($event)" ></button>
|
<button
|
||||||
|
v-if="allowRemove"
|
||||||
|
class="btn btn-delete"
|
||||||
|
@click="onRemoveDocument($event)"
|
||||||
|
></button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -4,22 +4,43 @@ interface FileIconConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<FileIconConfig>();
|
const props = defineProps<FileIconConfig>();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<i class="fa fa-file-pdf-o" v-if="props.type === 'application/pdf'"></i>
|
<i class="fa fa-file-pdf-o" v-if="props.type === 'application/pdf'"></i>
|
||||||
<i class="fa fa-file-word-o" v-else-if="props.type === 'application/vnd.oasis.opendocument.text'"></i>
|
<i
|
||||||
<i class="fa fa-file-word-o" v-else-if="props.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'"></i>
|
class="fa fa-file-word-o"
|
||||||
<i class="fa fa-file-word-o" v-else-if="props.type === 'application/msword'"></i>
|
v-else-if="props.type === 'application/vnd.oasis.opendocument.text'"
|
||||||
<i class="fa fa-file-excel-o" v-else-if="props.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'"></i>
|
></i>
|
||||||
<i class="fa fa-file-excel-o" v-else-if="props.type === 'application/vnd.ms-excel'"></i>
|
<i
|
||||||
|
class="fa fa-file-word-o"
|
||||||
|
v-else-if="
|
||||||
|
props.type ===
|
||||||
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
||||||
|
"
|
||||||
|
></i>
|
||||||
|
<i
|
||||||
|
class="fa fa-file-word-o"
|
||||||
|
v-else-if="props.type === 'application/msword'"
|
||||||
|
></i>
|
||||||
|
<i
|
||||||
|
class="fa fa-file-excel-o"
|
||||||
|
v-else-if="
|
||||||
|
props.type ===
|
||||||
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||||
|
"
|
||||||
|
></i>
|
||||||
|
<i
|
||||||
|
class="fa fa-file-excel-o"
|
||||||
|
v-else-if="props.type === 'application/vnd.ms-excel'"
|
||||||
|
></i>
|
||||||
<i class="fa fa-file-image-o" v-else-if="props.type === 'image/jpeg'"></i>
|
<i class="fa fa-file-image-o" v-else-if="props.type === 'image/jpeg'"></i>
|
||||||
<i class="fa fa-file-image-o" v-else-if="props.type === 'image/png'"></i>
|
<i class="fa fa-file-image-o" v-else-if="props.type === 'image/png'"></i>
|
||||||
<i class="fa fa-file-archive-o" v-else-if="props.type === 'application/x-zip-compressed'"></i>
|
<i
|
||||||
|
class="fa fa-file-archive-o"
|
||||||
|
v-else-if="props.type === 'application/x-zip-compressed'"
|
||||||
|
></i>
|
||||||
<i class="fa fa-file-code-o" v-else></i>
|
<i class="fa fa-file-code-o" v-else></i>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -6,20 +6,23 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import {
|
||||||
import {build_convert_link, download_and_decrypt_doc, download_doc} from "./helpers";
|
build_convert_link,
|
||||||
|
download_and_decrypt_doc,
|
||||||
|
download_doc,
|
||||||
|
} from "./helpers";
|
||||||
import mime from "mime";
|
import mime from "mime";
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
import { StoredObject } from "../../types";
|
import { StoredObject } from "../../types";
|
||||||
|
|
||||||
interface ConvertButtonConfig {
|
interface ConvertButtonConfig {
|
||||||
storedObject: StoredObject,
|
storedObject: StoredObject;
|
||||||
classes: { [key: string]: boolean},
|
classes: Record<string, boolean>;
|
||||||
filename?: string,
|
filename?: string;
|
||||||
};
|
}
|
||||||
|
|
||||||
interface DownloadButtonState {
|
interface DownloadButtonState {
|
||||||
content: null|string
|
content: null | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<ConvertButtonConfig>();
|
const props = defineProps<ConvertButtonConfig>();
|
||||||
@ -32,13 +35,15 @@ async function download_and_open(event: Event): Promise<void> {
|
|||||||
if (null === state.content) {
|
if (null === state.content) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const raw = await download_doc(build_convert_link(props.storedObject.uuid));
|
const raw = await download_doc(
|
||||||
|
build_convert_link(props.storedObject.uuid),
|
||||||
|
);
|
||||||
state.content = window.URL.createObjectURL(raw);
|
state.content = window.URL.createObjectURL(raw);
|
||||||
|
|
||||||
button.href = window.URL.createObjectURL(raw);
|
button.href = window.URL.createObjectURL(raw);
|
||||||
button.type = 'application/pdf';
|
button.type = "application/pdf";
|
||||||
|
|
||||||
button.download = (props.filename + '.pdf') || 'document.pdf';
|
button.download = props.filename + ".pdf" || "document.pdf";
|
||||||
}
|
}
|
||||||
|
|
||||||
button.click();
|
button.click();
|
||||||
@ -47,11 +52,10 @@ async function download_and_open(event: Event): Promise<void> {
|
|||||||
|
|
||||||
function reset_state(): void {
|
function reset_state(): void {
|
||||||
state.content = null;
|
state.content = null;
|
||||||
btn.value?.removeAttribute('download');
|
btn.value?.removeAttribute("download");
|
||||||
btn.value?.removeAttribute('href');
|
btn.value?.removeAttribute("href");
|
||||||
btn.value?.removeAttribute('type');
|
btn.value?.removeAttribute("type");
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
||||||
import { computed, reactive } from "vue";
|
import { computed, reactive } from "vue";
|
||||||
|
|
||||||
export interface DesktopEditButtonConfig {
|
export interface DesktopEditButtonConfig {
|
||||||
editLink: null,
|
editLink: null;
|
||||||
classes: { [k: string]: boolean },
|
classes: Record<string, boolean>;
|
||||||
expirationLink: number|Date,
|
expirationLink: number | Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DesktopEditButtonState {
|
interface DesktopEditButtonState {
|
||||||
modalOpened: boolean
|
modalOpened: boolean;
|
||||||
};
|
}
|
||||||
|
|
||||||
const state: DesktopEditButtonState = reactive({ modalOpened: false });
|
const state: DesktopEditButtonState = reactive({ modalOpened: false });
|
||||||
|
|
||||||
const props = defineProps<DesktopEditButtonConfig>();
|
const props = defineProps<DesktopEditButtonConfig>();
|
||||||
|
|
||||||
const buildCommand = computed<string>(() => 'vnd.libreoffice.command:ofe|u|' + props.editLink);
|
const buildCommand = computed<string>(
|
||||||
|
() => "vnd.libreoffice.command:ofe|u|" + props.editLink,
|
||||||
|
);
|
||||||
|
|
||||||
const editionUntilFormatted = computed<string>(() => {
|
const editionUntilFormatted = computed<string>(() => {
|
||||||
let d;
|
let d;
|
||||||
@ -29,9 +30,11 @@ const editionUntilFormatted = computed<string>(() => {
|
|||||||
}
|
}
|
||||||
console.log(props.expirationLink);
|
console.log(props.expirationLink);
|
||||||
|
|
||||||
return (new Intl.DateTimeFormat(undefined, {'dateStyle': 'long', 'timeStyle': 'medium'})).format(d);
|
return new Intl.DateTimeFormat(undefined, {
|
||||||
|
dateStyle: "long",
|
||||||
|
timeStyle: "medium",
|
||||||
|
}).format(d);
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -39,16 +42,40 @@ const editionUntilFormatted = computed<string>(() => {
|
|||||||
<modal v-if="state.modalOpened" @close="state.modalOpened = false">
|
<modal v-if="state.modalOpened" @close="state.modalOpened = false">
|
||||||
<template v-slot:body>
|
<template v-slot:body>
|
||||||
<div class="desktop-edit">
|
<div class="desktop-edit">
|
||||||
<p class="center">Veuillez enregistrer vos modifications avant le</p>
|
<p class="center">
|
||||||
<p><strong>{{ editionUntilFormatted }}</strong></p>
|
Veuillez enregistrer vos modifications avant le
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>{{ editionUntilFormatted }}</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><a class="btn btn-primary" :href="buildCommand">Ouvrir le document pour édition</a></p>
|
<p>
|
||||||
|
<a class="btn btn-primary" :href="buildCommand"
|
||||||
|
>Ouvrir le document pour édition</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><small>Le document peut être édité uniquement en utilisant Libre Office.</small></p>
|
<p>
|
||||||
|
<small
|
||||||
|
>Le document peut être édité uniquement en utilisant
|
||||||
|
Libre Office.</small
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><small>En cas d'échec lors de l'enregistrement, sauver le document sur le poste de travail avant de le déposer à nouveau ici.</small></p>
|
<p>
|
||||||
|
<small
|
||||||
|
>En cas d'échec lors de l'enregistrement, sauver le
|
||||||
|
document sur le poste de travail avant de le déposer
|
||||||
|
à nouveau ici.</small
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><small>Vous pouvez naviguez sur d'autres pages pendant l'édition.</small></p>
|
<p>
|
||||||
|
<small
|
||||||
|
>Vous pouvez naviguez sur d'autres pages pendant
|
||||||
|
l'édition.</small
|
||||||
|
>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</modal>
|
</modal>
|
||||||
|
@ -1,9 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<a v-if="!state.is_ready" :class="props.classes" @click="download_and_open()" title="Télécharger">
|
<a
|
||||||
|
v-if="!state.is_ready"
|
||||||
|
:class="props.classes"
|
||||||
|
@click="download_and_open()"
|
||||||
|
title="Télécharger"
|
||||||
|
>
|
||||||
<i class="fa fa-download"></i>
|
<i class="fa fa-download"></i>
|
||||||
<template v-if="displayActionStringInButton">Télécharger</template>
|
<template v-if="displayActionStringInButton">Télécharger</template>
|
||||||
</a>
|
</a>
|
||||||
<a v-else :class="props.classes" target="_blank" :type="props.atVersion.type" :download="buildDocumentName()" :href="state.href_url" ref="open_button" title="Ouvrir">
|
<a
|
||||||
|
v-else
|
||||||
|
:class="props.classes"
|
||||||
|
target="_blank"
|
||||||
|
:type="props.atVersion.type"
|
||||||
|
:download="buildDocumentName()"
|
||||||
|
:href="state.href_url"
|
||||||
|
ref="open_button"
|
||||||
|
title="Ouvrir"
|
||||||
|
>
|
||||||
<i class="fa fa-external-link"></i>
|
<i class="fa fa-external-link"></i>
|
||||||
<template v-if="displayActionStringInButton">Ouvrir</template>
|
<template v-if="displayActionStringInButton">Ouvrir</template>
|
||||||
</a>
|
</a>
|
||||||
@ -16,43 +30,50 @@ import mime from "mime";
|
|||||||
import { StoredObject, StoredObjectVersion } from "../../types";
|
import { StoredObject, StoredObjectVersion } from "../../types";
|
||||||
|
|
||||||
interface DownloadButtonConfig {
|
interface DownloadButtonConfig {
|
||||||
storedObject: StoredObject,
|
storedObject: StoredObject;
|
||||||
atVersion: StoredObjectVersion,
|
atVersion: StoredObjectVersion;
|
||||||
classes: { [k: string]: boolean },
|
classes: Record<string, boolean>;
|
||||||
filename?: string,
|
filename?: string;
|
||||||
/**
|
/**
|
||||||
* if true, display the action string into the button. If false, displays only
|
* if true, display the action string into the button. If false, displays only
|
||||||
* the icon
|
* the icon
|
||||||
*/
|
*/
|
||||||
displayActionStringInButton?: boolean,
|
displayActionStringInButton?: boolean;
|
||||||
/**
|
/**
|
||||||
* if true, will download directly the file on load
|
* if true, will download directly the file on load
|
||||||
*/
|
*/
|
||||||
directDownload?: boolean,
|
directDownload?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DownloadButtonState {
|
interface DownloadButtonState {
|
||||||
is_ready: boolean,
|
is_ready: boolean;
|
||||||
is_running: boolean,
|
is_running: boolean;
|
||||||
href_url: string,
|
href_url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<DownloadButtonConfig>(), {displayActionStringInButton: true, directDownload: false});
|
const props = withDefaults(defineProps<DownloadButtonConfig>(), {
|
||||||
const state: DownloadButtonState = reactive({is_ready: false, is_running: false, href_url: "#"});
|
displayActionStringInButton: true,
|
||||||
|
directDownload: false,
|
||||||
|
});
|
||||||
|
const state: DownloadButtonState = reactive({
|
||||||
|
is_ready: false,
|
||||||
|
is_running: false,
|
||||||
|
href_url: "#",
|
||||||
|
});
|
||||||
|
|
||||||
const open_button = ref<HTMLAnchorElement | null>(null);
|
const open_button = ref<HTMLAnchorElement | null>(null);
|
||||||
|
|
||||||
function buildDocumentName(): string {
|
function buildDocumentName(): string {
|
||||||
let document_name = props.filename ?? props.storedObject.title;
|
let document_name = props.filename ?? props.storedObject.title;
|
||||||
|
|
||||||
if ('' === document_name) {
|
if ("" === document_name) {
|
||||||
document_name = 'document';
|
document_name = "document";
|
||||||
}
|
}
|
||||||
|
|
||||||
const ext = mime.getExtension(props.atVersion.type);
|
const ext = mime.getExtension(props.atVersion.type);
|
||||||
|
|
||||||
if (null !== ext) {
|
if (null !== ext) {
|
||||||
return document_name + '.' + ext;
|
return document_name + "." + ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
return document_name;
|
return document_name;
|
||||||
@ -60,21 +81,24 @@ function buildDocumentName(): string {
|
|||||||
|
|
||||||
async function download_and_open(): Promise<void> {
|
async function download_and_open(): Promise<void> {
|
||||||
if (state.is_running) {
|
if (state.is_running) {
|
||||||
console.log('state is running, aborting');
|
console.log("state is running, aborting");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.is_running = true;
|
state.is_running = true;
|
||||||
|
|
||||||
if (state.is_ready) {
|
if (state.is_ready) {
|
||||||
console.log('state is ready. This should not happens');
|
console.log("state is ready. This should not happens");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let raw;
|
let raw;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
raw = await download_and_decrypt_doc(props.storedObject, props.atVersion);
|
raw = await download_and_decrypt_doc(
|
||||||
|
props.storedObject,
|
||||||
|
props.atVersion,
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("error while downloading and decrypting document");
|
console.error("error while downloading and decrypting document");
|
||||||
console.error(e);
|
console.error(e);
|
||||||
@ -89,13 +113,13 @@ async function download_and_open(): Promise<void> {
|
|||||||
await nextTick();
|
await nextTick();
|
||||||
open_button.value?.click();
|
open_button.value?.click();
|
||||||
|
|
||||||
console.log('open button should have been clicked');
|
console.log("open button should have been clicked");
|
||||||
setTimeout(reset_state, 45000);
|
setTimeout(reset_state, 45000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset_state(): void {
|
function reset_state(): void {
|
||||||
state.href_url = '#';
|
state.href_url = "#";
|
||||||
state.is_ready = false;
|
state.is_ready = false;
|
||||||
state.is_running = false;
|
state.is_running = false;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import HistoryButtonModal from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonModal.vue";
|
import HistoryButtonModal from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonModal.vue";
|
||||||
import {StoredObject, StoredObjectVersionWithPointInTime} from "./../../types";
|
import {
|
||||||
|
StoredObject,
|
||||||
|
StoredObjectVersionWithPointInTime,
|
||||||
|
} from "./../../types";
|
||||||
import { computed, reactive, ref, useTemplateRef } from "vue";
|
import { computed, reactive, ref, useTemplateRef } from "vue";
|
||||||
import { get_versions } from "./HistoryButton/api";
|
import { get_versions } from "./HistoryButton/api";
|
||||||
|
|
||||||
@ -17,7 +19,7 @@ interface HistoryButtonState {
|
|||||||
|
|
||||||
const props = defineProps<HistoryButtonConfig>();
|
const props = defineProps<HistoryButtonConfig>();
|
||||||
const state = reactive<HistoryButtonState>({ versions: [], loaded: false });
|
const state = reactive<HistoryButtonState>({ versions: [], loaded: false });
|
||||||
const modal = useTemplateRef<typeof HistoryButtonModal>('modal');
|
const modal = useTemplateRef<typeof HistoryButtonModal>("modal");
|
||||||
|
|
||||||
const download_version_and_open_modal = async function (): Promise<void> {
|
const download_version_and_open_modal = async function (): Promise<void> {
|
||||||
if (null !== modal.value) {
|
if (null !== modal.value) {
|
||||||
@ -34,17 +36,26 @@ const download_version_and_open_modal = async function (): Promise<void> {
|
|||||||
}
|
}
|
||||||
state.loaded = true;
|
state.loaded = true;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const onRestoreVersion = ({newVersion}: {newVersion: StoredObjectVersionWithPointInTime}) => {
|
const onRestoreVersion = ({
|
||||||
|
newVersion,
|
||||||
|
}: {
|
||||||
|
newVersion: StoredObjectVersionWithPointInTime;
|
||||||
|
}) => {
|
||||||
state.versions.unshift(newVersion);
|
state.versions.unshift(newVersion);
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a @click="download_version_and_open_modal" class="dropdown-item">
|
<a @click="download_version_and_open_modal" class="dropdown-item">
|
||||||
<history-button-modal ref="modal" :versions="state.versions" :stored-object="storedObject" :can-edit="canEdit" @restore-version="onRestoreVersion"></history-button-modal>
|
<history-button-modal
|
||||||
|
ref="modal"
|
||||||
|
:versions="state.versions"
|
||||||
|
:stored-object="storedObject"
|
||||||
|
:can-edit="canEdit"
|
||||||
|
@restore-version="onRestoreVersion"
|
||||||
|
></history-button-modal>
|
||||||
<i class="fa fa-history"></i>
|
<i class="fa fa-history"></i>
|
||||||
Historique
|
Historique
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {StoredObject, StoredObjectVersionWithPointInTime} from "./../../../types";
|
import {
|
||||||
|
StoredObject,
|
||||||
|
StoredObjectVersionWithPointInTime,
|
||||||
|
} from "./../../../types";
|
||||||
import HistoryButtonListItem from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonListItem.vue";
|
import HistoryButtonListItem from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonListItem.vue";
|
||||||
import { computed, reactive } from "vue";
|
import { computed, reactive } from "vue";
|
||||||
|
|
||||||
@ -10,8 +13,8 @@ interface HistoryButtonListConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime]
|
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime];
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
interface HistoryButtonListState {
|
interface HistoryButtonListState {
|
||||||
/**
|
/**
|
||||||
@ -22,12 +25,14 @@ interface HistoryButtonListState {
|
|||||||
|
|
||||||
const props = defineProps<HistoryButtonListConfig>();
|
const props = defineProps<HistoryButtonListConfig>();
|
||||||
|
|
||||||
const state = reactive<HistoryButtonListState>({restored: -1})
|
const state = reactive<HistoryButtonListState>({ restored: -1 });
|
||||||
|
|
||||||
const higher_version = computed<number>(() => props.versions.reduce(
|
const higher_version = computed<number>(() =>
|
||||||
(accumulator: number, version: StoredObjectVersionWithPointInTime) => Math.max(accumulator, version.version),
|
props.versions.reduce(
|
||||||
-1
|
(accumulator: number, version: StoredObjectVersionWithPointInTime) =>
|
||||||
)
|
Math.max(accumulator, version.version),
|
||||||
|
-1,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,11 +40,14 @@ const higher_version = computed<number>(() => props.versions.reduce(
|
|||||||
*
|
*
|
||||||
* internally, keep track of the newly restored version
|
* internally, keep track of the newly restored version
|
||||||
*/
|
*/
|
||||||
const onRestored = ({newVersion}: {newVersion: StoredObjectVersionWithPointInTime}) => {
|
const onRestored = ({
|
||||||
|
newVersion,
|
||||||
|
}: {
|
||||||
|
newVersion: StoredObjectVersionWithPointInTime;
|
||||||
|
}) => {
|
||||||
state.restored = newVersion.version;
|
state.restored = newVersion.version;
|
||||||
emit('restoreVersion', {newVersion});
|
emit("restoreVersion", { newVersion });
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -59,9 +67,6 @@ const onRestored = ({newVersion}: {newVersion: StoredObjectVersionWithPointInTim
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<p>Chargement des versions</p>
|
<p>Chargement des versions</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {StoredObject, StoredObjectPointInTime, StoredObjectVersionWithPointInTime} from "./../../../types";
|
import {
|
||||||
|
StoredObject,
|
||||||
|
StoredObjectPointInTime,
|
||||||
|
StoredObjectVersionWithPointInTime,
|
||||||
|
} from "./../../../types";
|
||||||
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
||||||
import { ISOToDatetime } from "./../../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
import { ISOToDatetime } from "./../../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
||||||
import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue";
|
import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue";
|
||||||
@ -15,47 +19,120 @@ interface HistoryButtonListItemConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime]
|
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime];
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
const props = defineProps<HistoryButtonListItemConfig>();
|
const props = defineProps<HistoryButtonListItemConfig>();
|
||||||
|
|
||||||
const onRestore = ({newVersion}: {newVersion: StoredObjectVersionWithPointInTime}) => {
|
const onRestore = ({
|
||||||
emit('restoreVersion', {newVersion});
|
newVersion,
|
||||||
}
|
}: {
|
||||||
|
newVersion: StoredObjectVersionWithPointInTime;
|
||||||
|
}) => {
|
||||||
|
emit("restoreVersion", { newVersion });
|
||||||
|
};
|
||||||
|
|
||||||
const isKeptBeforeConversion = computed<boolean>(() => props.version["point-in-times"].reduce(
|
const isKeptBeforeConversion = computed<boolean>(() =>
|
||||||
(accumulator: boolean, pit: StoredObjectPointInTime) => accumulator || "keep-before-conversion" === pit.reason,
|
props.version["point-in-times"].reduce(
|
||||||
false
|
(accumulator: boolean, pit: StoredObjectPointInTime) =>
|
||||||
|
accumulator || "keep-before-conversion" === pit.reason,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const isRestored = computed<boolean>(() => props.version.version > 0 && null !== props.version["from-restored"]);
|
const isRestored = computed<boolean>(
|
||||||
|
() => props.version.version > 0 && null !== props.version["from-restored"],
|
||||||
|
);
|
||||||
|
|
||||||
const isDuplicated = computed<boolean>(() => props.version.version === 0 && null !== props.version["from-restored"]);
|
const isDuplicated = computed<boolean>(
|
||||||
|
() =>
|
||||||
const classes = computed<{row: true, 'row-hover': true, 'blinking-1': boolean, 'blinking-2': boolean}>(() => ({row: true, 'row-hover': true, 'blinking-1': props.isRestored && 0 === props.version.version % 2, 'blinking-2': props.isRestored && 1 === props.version.version % 2}));
|
props.version.version === 0 && null !== props.version["from-restored"],
|
||||||
|
);
|
||||||
|
|
||||||
|
const classes = computed<{
|
||||||
|
row: true;
|
||||||
|
"row-hover": true;
|
||||||
|
"blinking-1": boolean;
|
||||||
|
"blinking-2": boolean;
|
||||||
|
}>(() => ({
|
||||||
|
row: true,
|
||||||
|
"row-hover": true,
|
||||||
|
"blinking-1": props.isRestored && 0 === props.version.version % 2,
|
||||||
|
"blinking-2": props.isRestored && 1 === props.version.version % 2,
|
||||||
|
}));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="classes">
|
<div :class="classes">
|
||||||
<div class="col-12 tags" v-if="isCurrent || isKeptBeforeConversion || isRestored || isDuplicated">
|
<div
|
||||||
<span class="badge bg-success" v-if="isCurrent">Version actuelle</span>
|
class="col-12 tags"
|
||||||
<span class="badge bg-info" v-if="isKeptBeforeConversion">Conservée avant conversion dans un autre format</span>
|
v-if="
|
||||||
<span class="badge bg-info" v-if="isRestored">Restaurée depuis la version {{ version["from-restored"]?.version + 1 }}</span>
|
isCurrent ||
|
||||||
<span class="badge bg-info" v-if="isDuplicated">Dupliqué depuis un autre document</span>
|
isKeptBeforeConversion ||
|
||||||
|
isRestored ||
|
||||||
|
isDuplicated
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<span class="badge bg-success" v-if="isCurrent"
|
||||||
|
>Version actuelle</span
|
||||||
|
>
|
||||||
|
<span class="badge bg-info" v-if="isKeptBeforeConversion"
|
||||||
|
>Conservée avant conversion dans un autre format</span
|
||||||
|
>
|
||||||
|
<span class="badge bg-info" v-if="isRestored"
|
||||||
|
>Restaurée depuis la version
|
||||||
|
{{ version["from-restored"]?.version + 1 }}</span
|
||||||
|
>
|
||||||
|
<span class="badge bg-info" v-if="isDuplicated"
|
||||||
|
>Dupliqué depuis un autre document</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<file-icon :type="version.type"></file-icon> <span><strong>#{{ version.version + 1 }}</strong></span> <template v-if="version.createdBy !== null && version.createdAt !== null"><strong v-if="version.version == 0">Créé par</strong><strong v-else>modifié par</strong> <span class="badge-user"><UserRenderBoxBadge :user="version.createdBy"></UserRenderBoxBadge></span> <strong>à</strong> {{ $d(ISOToDatetime(version.createdAt.datetime8601), 'long') }}</template><template v-if="version.createdBy === null && version.createdAt !== null"><strong v-if="version.version == 0">Créé le</strong><strong v-else>modifié le</strong> {{ $d(ISOToDatetime(version.createdAt.datetime8601), 'long') }}</template>
|
<file-icon :type="version.type"></file-icon>
|
||||||
|
<span
|
||||||
|
><strong>#{{ version.version + 1 }}</strong></span
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-if="version.createdBy !== null && version.createdAt !== null"
|
||||||
|
><strong v-if="version.version == 0">Créé par</strong
|
||||||
|
><strong v-else>modifié par</strong>
|
||||||
|
<span class="badge-user"
|
||||||
|
><UserRenderBoxBadge
|
||||||
|
:user="version.createdBy"
|
||||||
|
></UserRenderBoxBadge
|
||||||
|
></span>
|
||||||
|
<strong>à</strong>
|
||||||
|
{{
|
||||||
|
$d(ISOToDatetime(version.createdAt.datetime8601), "long")
|
||||||
|
}}</template
|
||||||
|
><template
|
||||||
|
v-if="version.createdBy === null && version.createdAt !== null"
|
||||||
|
><strong v-if="version.version == 0">Créé le</strong
|
||||||
|
><strong v-else>modifié le</strong>
|
||||||
|
{{
|
||||||
|
$d(ISOToDatetime(version.createdAt.datetime8601), "long")
|
||||||
|
}}</template
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<ul class="record_actions small slim on-version-actions">
|
<ul class="record_actions small slim on-version-actions">
|
||||||
<li v-if="canEdit && !isCurrent">
|
<li v-if="canEdit && !isCurrent">
|
||||||
<restore-version-button :stored-object-version="props.version" @restore-version="onRestore"></restore-version-button>
|
<restore-version-button
|
||||||
|
:stored-object-version="props.version"
|
||||||
|
@restore-version="onRestore"
|
||||||
|
></restore-version-button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<download-button :stored-object="storedObject" :at-version="version" :classes="{btn: true, 'btn-outline-primary': true, 'btn-sm': true}" :display-action-string-in-button="false"></download-button>
|
<download-button
|
||||||
|
:stored-object="storedObject"
|
||||||
|
:at-version="version"
|
||||||
|
:classes="{
|
||||||
|
btn: true,
|
||||||
|
'btn-outline-primary': true,
|
||||||
|
'btn-sm': true,
|
||||||
|
}"
|
||||||
|
:display-action-string-in-button="false"
|
||||||
|
></download-button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
||||||
import { reactive } from "vue";
|
import { reactive } from "vue";
|
||||||
import HistoryButtonList from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonList.vue";
|
import HistoryButtonList from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonList.vue";
|
||||||
import {StoredObject, StoredObjectVersionWithPointInTime} from "./../../../types";
|
import {
|
||||||
|
StoredObject,
|
||||||
|
StoredObjectVersionWithPointInTime,
|
||||||
|
} from "./../../../types";
|
||||||
|
|
||||||
interface HistoryButtonListConfig {
|
interface HistoryButtonListConfig {
|
||||||
versions: StoredObjectVersionWithPointInTime[];
|
versions: StoredObjectVersionWithPointInTime[];
|
||||||
@ -11,8 +14,8 @@ interface HistoryButtonListConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime]
|
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime];
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
interface HistoryButtonModalState {
|
interface HistoryButtonModalState {
|
||||||
opened: boolean;
|
opened: boolean;
|
||||||
@ -23,10 +26,9 @@ const state = reactive<HistoryButtonModalState>({opened: false});
|
|||||||
|
|
||||||
const open = () => {
|
const open = () => {
|
||||||
state.opened = true;
|
state.opened = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
defineExpose({ open });
|
defineExpose({ open });
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Teleport to="body">
|
<Teleport to="body">
|
||||||
@ -36,12 +38,17 @@ defineExpose({open});
|
|||||||
</template>
|
</template>
|
||||||
<template v-slot:body>
|
<template v-slot:body>
|
||||||
<p>Les versions sont conservées pendant 90 jours.</p>
|
<p>Les versions sont conservées pendant 90 jours.</p>
|
||||||
<history-button-list :versions="props.versions" :can-edit="canEdit" :stored-object="storedObject" @restore-version="(payload) => emit('restoreVersion', payload)"></history-button-list>
|
<history-button-list
|
||||||
|
:versions="props.versions"
|
||||||
|
:can-edit="canEdit"
|
||||||
|
:stored-object="storedObject"
|
||||||
|
@restore-version="
|
||||||
|
(payload) => emit('restoreVersion', payload)
|
||||||
|
"
|
||||||
|
></history-button-list>
|
||||||
</template>
|
</template>
|
||||||
</modal>
|
</modal>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {StoredObjectVersionPersisted, StoredObjectVersionWithPointInTime} from "../../../types";
|
import {
|
||||||
|
StoredObjectVersionPersisted,
|
||||||
|
StoredObjectVersionWithPointInTime,
|
||||||
|
} from "../../../types";
|
||||||
import { useToast } from "vue-toast-notification";
|
import { useToast } from "vue-toast-notification";
|
||||||
import { restore_version } from "./api";
|
import { restore_version } from "./api";
|
||||||
|
|
||||||
interface RestoreVersionButtonProps {
|
interface RestoreVersionButtonProps {
|
||||||
storedObjectVersion: StoredObjectVersionPersisted,
|
storedObjectVersion: StoredObjectVersionPersisted;
|
||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime]
|
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime];
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
const props = defineProps<RestoreVersionButtonProps>()
|
const props = defineProps<RestoreVersionButtonProps>();
|
||||||
|
|
||||||
const $toast = useToast();
|
const $toast = useToast();
|
||||||
|
|
||||||
@ -19,14 +22,18 @@ const restore_version_fn = async () => {
|
|||||||
const newVersion = await restore_version(props.storedObjectVersion);
|
const newVersion = await restore_version(props.storedObjectVersion);
|
||||||
|
|
||||||
$toast.success("Version restaurée");
|
$toast.success("Version restaurée");
|
||||||
emit('restoreVersion', {newVersion});
|
emit("restoreVersion", { newVersion });
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<button class="btn btn-outline-action" @click="restore_version_fn" title="Restaurer"><i class="fa fa-rotate-left"></i> Restaurer</button>
|
<button
|
||||||
|
class="btn btn-outline-action"
|
||||||
|
@click="restore_version_fn"
|
||||||
|
title="Restaurer"
|
||||||
|
>
|
||||||
|
<i class="fa fa-rotate-left"></i> Restaurer
|
||||||
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<a :class="Object.assign(props.classes, {'btn': true})" @click="beforeLeave($event)" :href="build_wopi_editor_link(props.storedObject.uuid, props.returnPath)">
|
<a
|
||||||
|
:class="Object.assign(props.classes, { btn: true })"
|
||||||
|
@click="beforeLeave($event)"
|
||||||
|
:href="
|
||||||
|
build_wopi_editor_link(props.storedObject.uuid, props.returnPath)
|
||||||
|
"
|
||||||
|
>
|
||||||
<i class="fa fa-paragraph"></i>
|
<i class="fa fa-paragraph"></i>
|
||||||
Editer en ligne
|
Editer en ligne
|
||||||
</a>
|
</a>
|
||||||
@ -8,13 +14,16 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import WopiEditButton from "./WopiEditButton.vue";
|
import WopiEditButton from "./WopiEditButton.vue";
|
||||||
import { build_wopi_editor_link } from "./helpers";
|
import { build_wopi_editor_link } from "./helpers";
|
||||||
import {StoredObject, WopiEditButtonExecutableBeforeLeaveFunction} from "../../types";
|
import {
|
||||||
|
StoredObject,
|
||||||
|
WopiEditButtonExecutableBeforeLeaveFunction,
|
||||||
|
} from "../../types";
|
||||||
|
|
||||||
interface WopiEditButtonConfig {
|
interface WopiEditButtonConfig {
|
||||||
storedObject: StoredObject,
|
storedObject: StoredObject;
|
||||||
returnPath?: string,
|
returnPath?: string;
|
||||||
classes: {[k: string] : boolean},
|
classes: Record<string, boolean>;
|
||||||
executeBeforeLeave?: WopiEditButtonExecutableBeforeLeaveFunction,
|
executeBeforeLeave?: WopiEditButtonExecutableBeforeLeaveFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<WopiEditButtonConfig>();
|
const props = defineProps<WopiEditButtonConfig>();
|
||||||
@ -43,4 +52,3 @@ i.fa::before {
|
|||||||
color: var(--bs-dropdown-link-hover-color);
|
color: var(--bs-dropdown-link-hover-color);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
require('./chillevent.scss');
|
require("./chillevent.scss");
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
module.exports = function(encore, entries)
|
module.exports = function (encore, entries) {
|
||||||
{
|
entries.push(__dirname + "/Resources/public/chill/index.js");
|
||||||
entries.push(__dirname + '/Resources/public/chill/index.js');
|
|
||||||
};
|
};
|
||||||
|
@ -1 +1 @@
|
|||||||
require('./footer_bandeau.jpg');
|
require("./footer_bandeau.jpg");
|
||||||
|
@ -1,43 +1,37 @@
|
|||||||
import { ShowHide } from 'ShowHide/show_hide.js';
|
import { ShowHide } from "ShowHide/show_hide.js";
|
||||||
// listen to adding of formation and register a show hide
|
// listen to adding of formation and register a show hide
|
||||||
|
|
||||||
var make_show_hide = function (entry) {
|
var make_show_hide = function (entry) {
|
||||||
let
|
let obtained = entry.querySelector("[data-diploma-obtained]"),
|
||||||
obtained = entry.querySelector('[data-diploma-obtained]'),
|
reconnue = entry.querySelector("[data-diploma-reconnue]");
|
||||||
reconnue = entry.querySelector('[data-diploma-reconnue]')
|
|
||||||
;
|
|
||||||
var a = new ShowHide({
|
var a = new ShowHide({
|
||||||
load_event: null,
|
load_event: null,
|
||||||
froms: [obtained],
|
froms: [obtained],
|
||||||
container: [reconnue],
|
container: [reconnue],
|
||||||
test: function (froms, event) {
|
test: function (froms, event) {
|
||||||
for (let f of froms.values()) {
|
for (let f of froms.values()) {
|
||||||
for (let input of f.querySelectorAll('input').values()) {
|
for (let input of f.querySelectorAll("input").values()) {
|
||||||
if (input.value === 'non-fr') {
|
if (input.value === "non-fr") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('collection-add-entry', function(e) {
|
window.addEventListener("collection-add-entry", function (e) {
|
||||||
if (e.detail.collection.dataset.collectionName === 'formations') {
|
if (e.detail.collection.dataset.collectionName === "formations") {
|
||||||
make_show_hide(e.detail.entry);
|
make_show_hide(e.detail.entry);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// starting the formation on load
|
// starting the formation on load
|
||||||
window.addEventListener('load', function(_e) {
|
window.addEventListener("load", function (_e) {
|
||||||
let
|
let formations = document.querySelectorAll("[data-formation-entry]");
|
||||||
formations = document.querySelectorAll('[data-formation-entry]')
|
|
||||||
;
|
|
||||||
|
|
||||||
for (let f of formations.values()) {
|
for (let f of formations.values()) {
|
||||||
make_show_hide(f);
|
make_show_hide(f);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,37 +1,36 @@
|
|||||||
import { ShowHide } from 'ShowHide/show_hide.js';
|
import { ShowHide } from "ShowHide/show_hide.js";
|
||||||
|
|
||||||
var
|
var div_accompagnement = document.getElementById("form_accompagnement"),
|
||||||
div_accompagnement = document.getElementById("form_accompagnement"),
|
|
||||||
div_accompagnement_rqth = document.getElementById("form_accompagnement_rqth"),
|
div_accompagnement_rqth = document.getElementById("form_accompagnement_rqth"),
|
||||||
div_accompagnement_comment = document.getElementById("form_accompagnement_comment"),
|
div_accompagnement_comment = document.getElementById(
|
||||||
|
"form_accompagnement_comment",
|
||||||
|
),
|
||||||
div_caf_id = document.getElementById("cafId"),
|
div_caf_id = document.getElementById("cafId"),
|
||||||
div_caf_inscription_date = document.getElementById("cafInscriptionDate"),
|
div_caf_inscription_date = document.getElementById("cafInscriptionDate"),
|
||||||
div_neet_eligibilite = document.getElementById("neetEligibilite"),
|
div_neet_eligibilite = document.getElementById("neetEligibilite"),
|
||||||
div_neet_commission_date = document.getElementById("neetCommissionDate")
|
div_neet_commission_date = document.getElementById("neetCommissionDate");
|
||||||
;
|
|
||||||
|
|
||||||
// faire apparaitre / disparaitre RQTH si RQTH coché
|
// faire apparaitre / disparaitre RQTH si RQTH coché
|
||||||
new ShowHide({
|
new ShowHide({
|
||||||
"froms": [div_accompagnement],
|
froms: [div_accompagnement],
|
||||||
"test": function(froms, event) {
|
test: function (froms, event) {
|
||||||
for (let el of froms.values()) {
|
for (let el of froms.values()) {
|
||||||
for (let input of el.querySelectorAll('input').values()) {
|
for (let input of el.querySelectorAll("input").values()) {
|
||||||
if (input.value === 'rqth') {
|
if (input.value === "rqth") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"container": [div_accompagnement_rqth]
|
container: [div_accompagnement_rqth],
|
||||||
});
|
});
|
||||||
|
|
||||||
// faire apparaitre / disparaitre commetnaire si coché
|
// faire apparaitre / disparaitre commetnaire si coché
|
||||||
new ShowHide({
|
new ShowHide({
|
||||||
"froms": [div_accompagnement],
|
froms: [div_accompagnement],
|
||||||
"test": function(froms, event) {
|
test: function (froms, event) {
|
||||||
for (let el of froms.values()) {
|
for (let el of froms.values()) {
|
||||||
for (let input of el.querySelectorAll('input').values()) {
|
for (let input of el.querySelectorAll("input").values()) {
|
||||||
if (input.value === 'autre') {
|
if (input.value === "autre") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,7 +38,7 @@ new ShowHide({
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
"container": [div_accompagnement_comment]
|
container: [div_accompagnement_comment],
|
||||||
});
|
});
|
||||||
|
|
||||||
// faire apparaitre cafInscriptionDate seulement si cafID est rempli
|
// faire apparaitre cafInscriptionDate seulement si cafID est rempli
|
||||||
@ -51,7 +50,7 @@ new ShowHide({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
container: [div_caf_inscription_date],
|
container: [div_caf_inscription_date],
|
||||||
event_name: 'input'
|
event_name: "input",
|
||||||
});
|
});
|
||||||
|
|
||||||
// faire apparaitre date de commission neet seulement si eligible
|
// faire apparaitre date de commission neet seulement si eligible
|
||||||
@ -59,7 +58,7 @@ new ShowHide({
|
|||||||
froms: [div_neet_eligibilite],
|
froms: [div_neet_eligibilite],
|
||||||
test: function (froms, event) {
|
test: function (froms, event) {
|
||||||
for (let el of froms.values()) {
|
for (let el of froms.values()) {
|
||||||
for (let input of el.querySelectorAll('input').values()) {
|
for (let input of el.querySelectorAll("input").values()) {
|
||||||
if (input.value === "oui") {
|
if (input.value === "oui") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
@ -68,5 +67,5 @@ new ShowHide({
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
container: [ div_neet_commission_date ]
|
container: [div_neet_commission_date],
|
||||||
});
|
});
|
@ -1,20 +1,17 @@
|
|||||||
import { ShowHide } from 'ShowHide/show_hide.js';
|
import { ShowHide } from "ShowHide/show_hide.js";
|
||||||
|
|
||||||
var
|
|
||||||
div_objectifs = document.getElementById("objectifs"),
|
|
||||||
div_objectifs_autre = document.getElementById("objectifsAutre")
|
|
||||||
;
|
|
||||||
|
|
||||||
|
var div_objectifs = document.getElementById("objectifs"),
|
||||||
|
div_objectifs_autre = document.getElementById("objectifsAutre");
|
||||||
new ShowHide({
|
new ShowHide({
|
||||||
froms: [div_objectifs],
|
froms: [div_objectifs],
|
||||||
container: [div_objectifs_autre],
|
container: [div_objectifs_autre],
|
||||||
test: function (froms, event) {
|
test: function (froms, event) {
|
||||||
for (let el of froms.values()) {
|
for (let el of froms.values()) {
|
||||||
for (let input of el.querySelectorAll('input').values()) {
|
for (let input of el.querySelectorAll("input").values()) {
|
||||||
if (input.value === 'autre') {
|
if (input.value === "autre") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
@ -1,28 +1,27 @@
|
|||||||
import { ShowHide } from 'ShowHide/show_hide.js';
|
import { ShowHide } from "ShowHide/show_hide.js";
|
||||||
var
|
var ressources = document.getElementById("ressources"),
|
||||||
ressources = document.getElementById("ressources"),
|
|
||||||
ressources_comment = document.getElementById("ressourcesComment"),
|
ressources_comment = document.getElementById("ressourcesComment"),
|
||||||
handicap_is = document.getElementById('handicap_is'),
|
handicap_is = document.getElementById("handicap_is"),
|
||||||
handicap_if = document.getElementById('handicap_if'),
|
handicap_if = document.getElementById("handicap_if"),
|
||||||
situation_prof = document.getElementById('situation_prof'),
|
situation_prof = document.getElementById("situation_prof"),
|
||||||
type_contrat = document.getElementById('type_contrat'),
|
type_contrat = document.getElementById("type_contrat"),
|
||||||
type_contrat_aide = document.getElementById('type_contrat_aide'),
|
type_contrat_aide = document.getElementById("type_contrat_aide"),
|
||||||
situation_logement = document.getElementById('situation_logement'),
|
situation_logement = document.getElementById("situation_logement"),
|
||||||
situation_logement_precision = document.getElementById('situation_logement_precision')
|
situation_logement_precision = document.getElementById(
|
||||||
;
|
"situation_logement_precision",
|
||||||
|
);
|
||||||
new ShowHide({
|
new ShowHide({
|
||||||
froms: [ressources],
|
froms: [ressources],
|
||||||
container: [ressources_comment],
|
container: [ressources_comment],
|
||||||
test: function (froms) {
|
test: function (froms) {
|
||||||
for (let f of froms.values()) {
|
for (let f of froms.values()) {
|
||||||
for (let input of f.querySelectorAll('input').values()) {
|
for (let input of f.querySelectorAll("input").values()) {
|
||||||
if (input.value === 'autre') {
|
if (input.value === "autre") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
new ShowHide({
|
new ShowHide({
|
||||||
@ -30,15 +29,15 @@ new ShowHide({
|
|||||||
container: [handicap_if],
|
container: [handicap_if],
|
||||||
test: function (froms) {
|
test: function (froms) {
|
||||||
for (let f of froms.values()) {
|
for (let f of froms.values()) {
|
||||||
for (let input of f.querySelectorAll('input').values()) {
|
for (let input of f.querySelectorAll("input").values()) {
|
||||||
if (input.value === '1') {
|
if (input.value === "1") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var show_hide_contrat_aide = new ShowHide({
|
var show_hide_contrat_aide = new ShowHide({
|
||||||
@ -46,42 +45,42 @@ var show_hide_contrat_aide = new ShowHide({
|
|||||||
container: [type_contrat_aide],
|
container: [type_contrat_aide],
|
||||||
test: function (froms) {
|
test: function (froms) {
|
||||||
for (let f of froms.values()) {
|
for (let f of froms.values()) {
|
||||||
for (let input of f.querySelectorAll('input').values()) {
|
for (let input of f.querySelectorAll("input").values()) {
|
||||||
if (input.value === 'contrat_aide') {
|
if (input.value === "contrat_aide") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
new ShowHide({
|
new ShowHide({
|
||||||
id: 'situation_prof_type_contrat',
|
id: "situation_prof_type_contrat",
|
||||||
froms: [situation_prof],
|
froms: [situation_prof],
|
||||||
container: [type_contrat],
|
container: [type_contrat],
|
||||||
test: function (froms) {
|
test: function (froms) {
|
||||||
for (let f of froms.values()) {
|
for (let f of froms.values()) {
|
||||||
for (let input of f.querySelectorAll('input').values()) {
|
for (let input of f.querySelectorAll("input").values()) {
|
||||||
if (input.value === 'en_activite') {
|
if (input.value === "en_activite") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('show-hide-hide', function (e) {
|
window.addEventListener("show-hide-hide", function (e) {
|
||||||
if (e.detail.id = 'situation_prof_type_contrat') {
|
if ((e.detail.id = "situation_prof_type_contrat")) {
|
||||||
show_hide_contrat_aide.forceHide();
|
show_hide_contrat_aide.forceHide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('show-hide-show', function (e) {
|
window.addEventListener("show-hide-show", function (e) {
|
||||||
if (e.detail.id = 'situation_prof_type_contrat') {
|
if ((e.detail.id = "situation_prof_type_contrat")) {
|
||||||
show_hide_contrat_aide.forceCompute();
|
show_hide_contrat_aide.forceCompute();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -91,13 +90,13 @@ new ShowHide({
|
|||||||
container: [situation_logement_precision],
|
container: [situation_logement_precision],
|
||||||
test: function (froms) {
|
test: function (froms) {
|
||||||
for (let f of froms.values()) {
|
for (let f of froms.values()) {
|
||||||
for (let input of f.querySelectorAll('input')) {
|
for (let input of f.querySelectorAll("input")) {
|
||||||
if (input.value === 'heberge_chez_tiers') {
|
if (input.value === "heberge_chez_tiers") {
|
||||||
return input.checked;
|
return input.checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
});
|
});
|
@ -4,47 +4,44 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// import jQuery
|
/// import jQuery
|
||||||
const $ = require('jquery');
|
const $ = require("jquery");
|
||||||
global.$ = global.jQuery = $;
|
global.$ = global.jQuery = $;
|
||||||
|
|
||||||
/// import select2
|
/// import select2
|
||||||
const select2 = require('select2');
|
const select2 = require("select2");
|
||||||
global.select2 = select2;
|
global.select2 = select2;
|
||||||
|
|
||||||
require('select2/dist/css/select2.css');
|
require("select2/dist/css/select2.css");
|
||||||
require('select2-bootstrap-theme/dist/select2-bootstrap.css');
|
require("select2-bootstrap-theme/dist/select2-bootstrap.css");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load Chill themes assets
|
* Load Chill themes assets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require('./chillmain.scss');
|
require("./chillmain.scss");
|
||||||
|
|
||||||
import { chill } from './js/chill.js';
|
import { chill } from "./js/chill.js";
|
||||||
global.chill = chill;
|
global.chill = chill;
|
||||||
|
|
||||||
require('./js/date');
|
require("./js/date");
|
||||||
require('./js/counter.js');
|
require("./js/counter.js");
|
||||||
|
|
||||||
/// Load fonts
|
/// Load fonts
|
||||||
require('./fonts/OpenSans/OpenSans.scss')
|
require("./fonts/OpenSans/OpenSans.scss");
|
||||||
|
|
||||||
/// Load images
|
/// Load images
|
||||||
require('./img/favicon.ico');
|
require("./img/favicon.ico");
|
||||||
require('./img/logo-chill-sans-slogan_white.png');
|
require("./img/logo-chill-sans-slogan_white.png");
|
||||||
require('./img/logo-chill-outil-accompagnement_white.png');
|
require("./img/logo-chill-outil-accompagnement_white.png");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load local libs
|
* Load local libs
|
||||||
* Some libs are only used in a few pages, they are loaded on a case by case basis
|
* Some libs are only used in a few pages, they are loaded on a case by case basis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require('../lib/breadcrumb/index.js');
|
require("../lib/breadcrumb/index.js");
|
||||||
require('../lib/download-report/index.js');
|
require("../lib/download-report/index.js");
|
||||||
require('../lib/select_interactive_loading/index.js');
|
require("../lib/select_interactive_loading/index.js");
|
||||||
|
|
||||||
//require('../lib/show_hide/index.js');
|
//require('../lib/show_hide/index.js');
|
||||||
//require('../lib/tabs/index.js');
|
//require('../lib/tabs/index.js');
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
/* jslint vars: true */
|
/* jslint vars: true */
|
||||||
/*jslint indent: 4 */
|
/*jslint indent: 4 */
|
||||||
/* global moment, $, window */
|
/* global moment, $, window */
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
var chill = function() {
|
|
||||||
|
|
||||||
|
var chill = (function () {
|
||||||
/**
|
/**
|
||||||
* Display an alert message when the user wants to leave a page containing a given form
|
* Display an alert message when the user wants to leave a page containing a given form
|
||||||
* in a given state.
|
* in a given state.
|
||||||
@ -19,7 +18,11 @@ var chill = function() {
|
|||||||
* contains some modified fields otherwise always display the alert when leaving
|
* contains some modified fields otherwise always display the alert when leaving
|
||||||
* @return nothing
|
* @return nothing
|
||||||
*/
|
*/
|
||||||
function _generalDisplayAlertWhenLeavingForm(form_id, alert_message, check_unsaved_data) {
|
function _generalDisplayAlertWhenLeavingForm(
|
||||||
|
form_id,
|
||||||
|
alert_message,
|
||||||
|
check_unsaved_data,
|
||||||
|
) {
|
||||||
var form_submitted = false;
|
var form_submitted = false;
|
||||||
var unsaved_data = false;
|
var unsaved_data = false;
|
||||||
|
|
||||||
@ -27,19 +30,18 @@ var chill = function() {
|
|||||||
.submit(function () {
|
.submit(function () {
|
||||||
form_submitted = true;
|
form_submitted = true;
|
||||||
})
|
})
|
||||||
.on('reset', function() {
|
.on("reset", function () {
|
||||||
unsaved_data = false;
|
unsaved_data = false;
|
||||||
})
|
});
|
||||||
;
|
|
||||||
|
|
||||||
$.each($(form_id).find(':input'), function(i,e) {
|
$.each($(form_id).find(":input"), function (i, e) {
|
||||||
$(e).change(function () {
|
$(e).change(function () {
|
||||||
unsaved_data = true;
|
unsaved_data = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(window).bind('beforeunload', function(){
|
$(window).bind("beforeunload", function () {
|
||||||
if((!form_submitted) && (unsaved_data || !check_unsaved_data)) {
|
if (!form_submitted && (unsaved_data || !check_unsaved_data)) {
|
||||||
return alert_message;
|
return alert_message;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -93,10 +95,12 @@ var chill = function() {
|
|||||||
of an other field, its checkbox is checked.
|
of an other field, its checkbox is checked.
|
||||||
*/
|
*/
|
||||||
function checkOtherValueOnChange() {
|
function checkOtherValueOnChange() {
|
||||||
$('.input-text-other-value').each(function() {
|
$(".input-text-other-value").each(function () {
|
||||||
$(this).change(function () {
|
$(this).change(function () {
|
||||||
var checkbox = $(this).parent().find('input[type=checkbox][value=_other]')[0];
|
var checkbox = $(this)
|
||||||
$(checkbox).prop('checked', ($(this).val() !== ''));
|
.parent()
|
||||||
|
.find("input[type=checkbox][value=_other]")[0];
|
||||||
|
$(checkbox).prop("checked", $(this).val() !== "");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -139,38 +143,45 @@ var chill = function() {
|
|||||||
- quand choix
|
- quand choix
|
||||||
*/
|
*/
|
||||||
function categoryLinkParentChildSelect() {
|
function categoryLinkParentChildSelect() {
|
||||||
var forms_to_link = $('form:has(select.chill-category-link-parent)');
|
var forms_to_link = $("form:has(select.chill-category-link-parent)");
|
||||||
|
|
||||||
forms_to_link.each(function (i, form_selector) {
|
forms_to_link.each(function (i, form_selector) {
|
||||||
var form = $(form_selector), parent_multiple;
|
var form = $(form_selector),
|
||||||
|
parent_multiple;
|
||||||
form.old_category = null;
|
form.old_category = null;
|
||||||
form.link_parent = $(form).find('.chill-category-link-parent');
|
form.link_parent = $(form).find(".chill-category-link-parent");
|
||||||
form.link_child = $(form).find('.chill-category-link-child');
|
form.link_child = $(form).find(".chill-category-link-child");
|
||||||
|
|
||||||
// check if the parent allow multiple or single results
|
// check if the parent allow multiple or single results
|
||||||
parent_multiple = $(form).find('.chill-category-link-parent').get(0).multiple;
|
parent_multiple = $(form)
|
||||||
|
.find(".chill-category-link-parent")
|
||||||
|
.get(0).multiple;
|
||||||
// if we use select2, parent_multiple will be `undefined`
|
// if we use select2, parent_multiple will be `undefined`
|
||||||
if (typeof parent_multiple == 'undefined') {
|
if (typeof parent_multiple == "undefined") {
|
||||||
// currently, I do not know how to check if multiple using select2.
|
// currently, I do not know how to check if multiple using select2.
|
||||||
// we suppose that multiple is false (old behaviour)
|
// we suppose that multiple is false (old behaviour)
|
||||||
parent_multiple = false
|
parent_multiple = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$(form.link_parent).addClass('select2');
|
$(form.link_parent).addClass("select2");
|
||||||
$(form.link_parant).select2({ allowClear: true }); // it is weird: when I fix the typo here, the whole stuff does not work anymore...
|
$(form.link_parant).select2({ allowClear: true }); // it is weird: when I fix the typo here, the whole stuff does not work anymore...
|
||||||
|
|
||||||
if (parent_multiple == false) {
|
if (parent_multiple == false) {
|
||||||
|
|
||||||
form.old_category = null;
|
form.old_category = null;
|
||||||
if($(form.link_parent).select2('data') !== null) {
|
if ($(form.link_parent).select2("data") !== null) {
|
||||||
form.old_category = ($(form.link_parent).select2('data').element[0].dataset.linkCategory);
|
form.old_category = $(form.link_parent).select2(
|
||||||
|
"data",
|
||||||
|
).element[0].dataset.linkCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
$(form.link_child).find('option')
|
$(form.link_child)
|
||||||
|
.find("option")
|
||||||
.each(function (i, e) {
|
.each(function (i, e) {
|
||||||
if (
|
if (
|
||||||
((!$(e).data('link-category')) || $(e).data('link-category') == form.old_category) &&
|
(!$(e).data("link-category") ||
|
||||||
((!$(e).data('link-categories')) || form.old_category in $(e).data('link-categories').split(','))
|
$(e).data("link-category") == form.old_category) &&
|
||||||
|
(!$(e).data("link-categories") ||
|
||||||
|
form.old_category in $(e).data("link-categories").split(","))
|
||||||
) {
|
) {
|
||||||
$(e).show();
|
$(e).show();
|
||||||
// here, we should handle the optgroup
|
// here, we should handle the optgroup
|
||||||
@ -181,13 +192,17 @@ var chill = function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
form.link_parent.change(function () {
|
form.link_parent.change(function () {
|
||||||
var new_category = ($(form.link_parent).select2('data').element[0].dataset.linkCategory);
|
var new_category = $(form.link_parent).select2("data").element[0]
|
||||||
|
.dataset.linkCategory;
|
||||||
if (new_category != form.old_category) {
|
if (new_category != form.old_category) {
|
||||||
$(form.link_child).find('option')
|
$(form.link_child)
|
||||||
|
.find("option")
|
||||||
.each(function (i, e) {
|
.each(function (i, e) {
|
||||||
if (
|
if (
|
||||||
((!$(e).data('link-category')) || $(e).data('link-category') == new_category) &&
|
(!$(e).data("link-category") ||
|
||||||
((!$(e).data('link-categories')) || new_category in $(e).data('link-categories').split(','))
|
$(e).data("link-category") == new_category) &&
|
||||||
|
(!$(e).data("link-categories") ||
|
||||||
|
new_category in $(e).data("link-categories").split(","))
|
||||||
) {
|
) {
|
||||||
$(e).show();
|
$(e).show();
|
||||||
// here, we should handle the optgroup
|
// here, we should handle the optgroup
|
||||||
@ -196,20 +211,21 @@ var chill = function() {
|
|||||||
// here, we should handle the opgroup
|
// here, we should handle the opgroup
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$(form.link_child).find('option')[0].selected = true;
|
$(form.link_child).find("option")[0].selected = true;
|
||||||
form.old_category = new_category;
|
form.old_category = new_category;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var i = 0,
|
var i = 0,
|
||||||
selected_items = $(form.link_parent).find(':selected');
|
selected_items = $(form.link_parent).find(":selected");
|
||||||
|
|
||||||
form.old_categories = [];
|
form.old_categories = [];
|
||||||
for (i = 0; i < selected_items.length; i++) {
|
for (i = 0; i < selected_items.length; i++) {
|
||||||
form.old_categories.push(selected_items[i].value);
|
form.old_categories.push(selected_items[i].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
$(form.link_child).find('option')
|
$(form.link_child)
|
||||||
|
.find("option")
|
||||||
.each(function (i, e) {
|
.each(function (i, e) {
|
||||||
var visible;
|
var visible;
|
||||||
if (form.old_categories.indexOf(e.dataset.linkCategory) != -1) {
|
if (form.old_categories.indexOf(e.dataset.linkCategory) != -1) {
|
||||||
@ -221,9 +237,13 @@ var chill = function() {
|
|||||||
$(e).hide();
|
$(e).hide();
|
||||||
if (e.parentNode instanceof HTMLOptGroupElement) {
|
if (e.parentNode instanceof HTMLOptGroupElement) {
|
||||||
// we check if the other options are visible.
|
// we check if the other options are visible.
|
||||||
visible = false
|
visible = false;
|
||||||
for (var l = 0; l < e.parentNode.children.length; l++) {
|
for (var l = 0; l < e.parentNode.children.length; l++) {
|
||||||
if (window.getComputedStyle(e.parentNode.children[l]).getPropertyValue('display') != 'none') {
|
if (
|
||||||
|
window
|
||||||
|
.getComputedStyle(e.parentNode.children[l])
|
||||||
|
.getPropertyValue("display") != "none"
|
||||||
|
) {
|
||||||
visible = true;
|
visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,14 +257,15 @@ var chill = function() {
|
|||||||
|
|
||||||
form.link_parent.change(function () {
|
form.link_parent.change(function () {
|
||||||
var new_categories = [],
|
var new_categories = [],
|
||||||
selected_items = $(form.link_parent).find(':selected'),
|
selected_items = $(form.link_parent).find(":selected"),
|
||||||
visible;
|
visible;
|
||||||
for (i = 0; i < selected_items.length; i++) {
|
for (i = 0; i < selected_items.length; i++) {
|
||||||
new_categories.push(selected_items[i].value);
|
new_categories.push(selected_items[i].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_categories != form.old_categories) {
|
if (new_categories != form.old_categories) {
|
||||||
$(form.link_child).find('option')
|
$(form.link_child)
|
||||||
|
.find("option")
|
||||||
.each(function (i, e) {
|
.each(function (i, e) {
|
||||||
if (new_categories.indexOf(e.dataset.linkCategory) != -1) {
|
if (new_categories.indexOf(e.dataset.linkCategory) != -1) {
|
||||||
$(e).show();
|
$(e).show();
|
||||||
@ -257,9 +278,13 @@ var chill = function() {
|
|||||||
// we check if the parent is an optgroup
|
// we check if the parent is an optgroup
|
||||||
if (e.parentNode instanceof HTMLOptGroupElement) {
|
if (e.parentNode instanceof HTMLOptGroupElement) {
|
||||||
// we check if other options are visible
|
// we check if other options are visible
|
||||||
visible = false
|
visible = false;
|
||||||
for (var l = 0; l < e.parentNode.children.length; l++) {
|
for (var l = 0; l < e.parentNode.children.length; l++) {
|
||||||
if (window.getComputedStyle(e.parentNode.children[l]).getPropertyValue('display') != 'none') {
|
if (
|
||||||
|
window
|
||||||
|
.getComputedStyle(e.parentNode.children[l])
|
||||||
|
.getPropertyValue("display") != "none"
|
||||||
|
) {
|
||||||
visible = true;
|
visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,7 +307,9 @@ var chill = function() {
|
|||||||
var target = checkbox.dataset.displayTarget,
|
var target = checkbox.dataset.displayTarget,
|
||||||
hideableElements;
|
hideableElements;
|
||||||
|
|
||||||
hideableElements = document.querySelectorAll('[data-display-show-hide="' + target + '"]');
|
hideableElements = document.querySelectorAll(
|
||||||
|
'[data-display-show-hide="' + target + '"]',
|
||||||
|
);
|
||||||
|
|
||||||
if (checkbox.checked) {
|
if (checkbox.checked) {
|
||||||
for (let i = 0; i < hideableElements.length; i = i + 1) {
|
for (let i = 0; i < hideableElements.length; i = i + 1) {
|
||||||
@ -293,7 +320,6 @@ var chill = function() {
|
|||||||
hideableElements[i].style.display = "none";
|
hideableElements[i].style.display = "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -335,11 +361,12 @@ var chill = function() {
|
|||||||
return {
|
return {
|
||||||
checkOtherValueOnChange: checkOtherValueOnChange,
|
checkOtherValueOnChange: checkOtherValueOnChange,
|
||||||
displayAlertWhenLeavingModifiedForm: displayAlertWhenLeavingModifiedForm,
|
displayAlertWhenLeavingModifiedForm: displayAlertWhenLeavingModifiedForm,
|
||||||
displayAlertWhenLeavingUnsubmittedForm: displayAlertWhenLeavingUnsubmittedForm,
|
displayAlertWhenLeavingUnsubmittedForm:
|
||||||
|
displayAlertWhenLeavingUnsubmittedForm,
|
||||||
checkNullValuesInChoices: checkNullValuesInChoices,
|
checkNullValuesInChoices: checkNullValuesInChoices,
|
||||||
categoryLinkParentChildSelect: categoryLinkParentChildSelect,
|
categoryLinkParentChildSelect: categoryLinkParentChildSelect,
|
||||||
listenerDisplayCheckbox: listenerDisplayCheckbox,
|
listenerDisplayCheckbox: listenerDisplayCheckbox,
|
||||||
};
|
};
|
||||||
} ();
|
})();
|
||||||
|
|
||||||
export { chill };
|
export { chill };
|
||||||
|
@ -9,26 +9,23 @@
|
|||||||
const isNum = (v) => !isNaN(v);
|
const isNum = (v) => !isNaN(v);
|
||||||
|
|
||||||
const parseCounter = () => {
|
const parseCounter = () => {
|
||||||
document.querySelectorAll('span.counter')
|
document.querySelectorAll("span.counter").forEach((el) => {
|
||||||
.forEach(el => {
|
|
||||||
let r = [];
|
let r = [];
|
||||||
el.innerText
|
el.innerText
|
||||||
.trim()
|
.trim()
|
||||||
.split(' ')
|
.split(" ")
|
||||||
.forEach(w => {
|
.forEach((w) => {
|
||||||
if (isNum(w)) {
|
if (isNum(w)) {
|
||||||
r.push(`<span>${w}</span>`);
|
r.push(`<span>${w}</span>`);
|
||||||
} else {
|
} else {
|
||||||
r.push(w);
|
r.push(w);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
;
|
el.innerHTML = r.join(" ");
|
||||||
el.innerHTML = r.join(' ');
|
});
|
||||||
})
|
|
||||||
;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', function (e) {
|
window.addEventListener("DOMContentLoaded", function (e) {
|
||||||
parseCounter();
|
parseCounter();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -19,9 +19,9 @@ export const dateToISO = (date: Date|null): string|null => {
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
date.getFullYear(),
|
date.getFullYear(),
|
||||||
(date.getMonth() + 1).toString().padStart(2, '0'),
|
(date.getMonth() + 1).toString().padStart(2, "0"),
|
||||||
date.getDate().toString().padStart(2, '0')
|
date.getDate().toString().padStart(2, "0"),
|
||||||
].join('-');
|
].join("-");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,11 +37,10 @@ export const ISOToDate = (str: string|null): Date|null => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let
|
const [year, month, day] = str.split("-").map((p) => parseInt(p));
|
||||||
[year, month, day] = str.split('-').map(p => parseInt(p));
|
|
||||||
|
|
||||||
return new Date(year, month - 1, day, 0, 0, 0, 0);
|
return new Date(year, month - 1, day, 0, 0, 0, 0);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a date object from iso string formatted as YYYY-mm-dd:HH:MM:ss+01:00
|
* Return a date object from iso string formatted as YYYY-mm-dd:HH:MM:ss+01:00
|
||||||
@ -52,19 +51,18 @@ export const ISOToDatetime = (str: string|null): Date|null => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let
|
const [cal, times] = str.split("T"),
|
||||||
[cal, times] = str.split('T'),
|
[year, month, date] = cal.split("-").map((s) => parseInt(s)),
|
||||||
[year, month, date] = cal.split('-').map(s => parseInt(s)),
|
|
||||||
[time, timezone] = times.split(times.charAt(8)),
|
[time, timezone] = times.split(times.charAt(8)),
|
||||||
[hours, minutes, seconds] = time.split(':').map(s => parseInt(s));
|
[hours, minutes, seconds] = time.split(":").map((s) => parseInt(s));
|
||||||
;
|
if ("0000" === timezone) {
|
||||||
|
return new Date(
|
||||||
if ('0000' === timezone) {
|
Date.UTC(year, month - 1, date, hours, minutes, seconds),
|
||||||
return new Date(Date.UTC(year, month-1, date, hours, minutes, seconds));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Date(year, month - 1, date, hours, minutes, seconds);
|
return new Date(year, month - 1, date, hours, minutes, seconds);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a date to ISO8601, valid for usage in api
|
* Convert a date to ISO8601, valid for usage in api
|
||||||
@ -74,39 +72,43 @@ export const datetimeToISO = (date: Date): string => {
|
|||||||
let cal, time, offset;
|
let cal, time, offset;
|
||||||
cal = [
|
cal = [
|
||||||
date.getFullYear(),
|
date.getFullYear(),
|
||||||
(date.getMonth() + 1).toString().padStart(2, '0'),
|
(date.getMonth() + 1).toString().padStart(2, "0"),
|
||||||
date.getDate().toString().padStart(2, '0')
|
date.getDate().toString().padStart(2, "0"),
|
||||||
].join('-');
|
].join("-");
|
||||||
|
|
||||||
time = [
|
time = [
|
||||||
date.getHours().toString().padStart(2, '0'),
|
date.getHours().toString().padStart(2, "0"),
|
||||||
date.getMinutes().toString().padStart(2, '0'),
|
date.getMinutes().toString().padStart(2, "0"),
|
||||||
date.getSeconds().toString().padStart(2, '0')
|
date.getSeconds().toString().padStart(2, "0"),
|
||||||
].join(':');
|
].join(":");
|
||||||
|
|
||||||
offset = [
|
offset = [
|
||||||
date.getTimezoneOffset() <= 0 ? '+' : '-',
|
date.getTimezoneOffset() <= 0 ? "+" : "-",
|
||||||
Math.abs(Math.floor(date.getTimezoneOffset() / 60)).toString().padStart(2, '0'),
|
Math.abs(Math.floor(date.getTimezoneOffset() / 60))
|
||||||
':',
|
.toString()
|
||||||
Math.abs(date.getTimezoneOffset() % 60).toString().padStart(2, '0'),
|
.padStart(2, "0"),
|
||||||
].join('');
|
":",
|
||||||
|
Math.abs(date.getTimezoneOffset() % 60)
|
||||||
|
.toString()
|
||||||
|
.padStart(2, "0"),
|
||||||
|
].join("");
|
||||||
|
|
||||||
let x = cal + 'T' + time + offset;
|
const x = cal + "T" + time + offset;
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const intervalDaysToISO = (days: number | string | null): string => {
|
export const intervalDaysToISO = (days: number | string | null): string => {
|
||||||
if (null === days) {
|
if (null === days) {
|
||||||
return 'P0D';
|
return "P0D";
|
||||||
}
|
}
|
||||||
|
|
||||||
return `P${days}D`;
|
return `P${days}D`;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const intervalISOToDays = (str: string | null): number | null => {
|
export const intervalISOToDays = (str: string | null): number | null => {
|
||||||
if (null === str) {
|
if (null === str) {
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("" === str.trim()) {
|
if ("" === str.trim()) {
|
||||||
@ -121,40 +123,42 @@ export const intervalISOToDays = (str: string|null): number|null => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (str.charAt(i)) {
|
switch (str.charAt(i)) {
|
||||||
case 'P':
|
case "P":
|
||||||
isDate = true;
|
isDate = true;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case "T":
|
||||||
isDate = false;
|
isDate = false;
|
||||||
break;
|
break;
|
||||||
case '0':
|
case "0":
|
||||||
case '1':
|
case "1":
|
||||||
case '2':
|
case "2":
|
||||||
case '3':
|
case "3":
|
||||||
case '4':
|
case "4":
|
||||||
case '5':
|
case "5":
|
||||||
case '6':
|
case "6":
|
||||||
case '7':
|
case "7":
|
||||||
case '8':
|
case "8":
|
||||||
case '9':
|
case "9":
|
||||||
vstring = vstring + str.charAt(i);
|
vstring = vstring + str.charAt(i);
|
||||||
break;
|
break;
|
||||||
case 'Y':
|
case "Y":
|
||||||
days = days + Number.parseInt(vstring) * 365;
|
days = days + Number.parseInt(vstring) * 365;
|
||||||
vstring = "";
|
vstring = "";
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case "M":
|
||||||
days = days + Number.parseInt(vstring) * 30;
|
days = days + Number.parseInt(vstring) * 30;
|
||||||
vstring = "";
|
vstring = "";
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case "D":
|
||||||
days = days + Number.parseInt(vstring);
|
days = days + Number.parseInt(vstring);
|
||||||
vstring = "";
|
vstring = "";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw Error("this character should not appears: " + str.charAt(i));
|
throw Error(
|
||||||
|
"this character should not appears: " + str.charAt(i),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return days;
|
return days;
|
||||||
}
|
};
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import {Address, GeographicalUnitLayer, SimpleGeographicalUnit} from "../../types";
|
import {
|
||||||
|
Address,
|
||||||
|
GeographicalUnitLayer,
|
||||||
|
SimpleGeographicalUnit,
|
||||||
|
} from "../../types";
|
||||||
import { fetchResults, makeFetch } from "./apiMethods";
|
import { fetchResults, makeFetch } from "./apiMethods";
|
||||||
|
|
||||||
export const getAddressById = async (address_id: number): Promise<Address> =>
|
export const getAddressById = async (address_id: number): Promise<Address> => {
|
||||||
{
|
|
||||||
const url = `/api/1.0/main/address/${address_id}.json`;
|
const url = `/api/1.0/main/address/${address_id}.json`;
|
||||||
|
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
@ -11,25 +14,48 @@ export const getAddressById = async (address_id: number): Promise<Address> =>
|
|||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Error('Error with request resource response');
|
throw Error("Error with request resource response");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getGeographicalUnitsByAddress = async (address: Address): Promise<SimpleGeographicalUnit[]> => {
|
export const getGeographicalUnitsByAddress = async (
|
||||||
return fetchResults<SimpleGeographicalUnit>(`/api/1.0/main/geographical-unit/by-address/${address.address_id}.json`);
|
address: Address,
|
||||||
}
|
): Promise<SimpleGeographicalUnit[]> => {
|
||||||
|
return fetchResults<SimpleGeographicalUnit>(
|
||||||
|
`/api/1.0/main/geographical-unit/by-address/${address.address_id}.json`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const getAllGeographicalUnitLayers = async (): Promise<GeographicalUnitLayer[]> => {
|
export const getAllGeographicalUnitLayers = async (): Promise<
|
||||||
return fetchResults<GeographicalUnitLayer>(`/api/1.0/main/geographical-unit-layer.json`);
|
GeographicalUnitLayer[]
|
||||||
}
|
> => {
|
||||||
|
return fetchResults<GeographicalUnitLayer>(
|
||||||
|
`/api/1.0/main/geographical-unit-layer.json`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const syncAddressWithReference = async (address: Address): Promise<Address> => {
|
export const syncAddressWithReference = async (
|
||||||
return makeFetch<null, Address>("POST", `/api/1.0/main/address/reference-match/${address.address_id}/sync-with-reference`);
|
address: Address,
|
||||||
}
|
): Promise<Address> => {
|
||||||
|
return makeFetch<null, Address>(
|
||||||
|
"POST",
|
||||||
|
`/api/1.0/main/address/reference-match/${address.address_id}/sync-with-reference`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const markAddressReviewed = async (address: Address): Promise<Address> => {
|
export const markAddressReviewed = async (
|
||||||
return makeFetch<null, Address>("POST", `/api/1.0/main/address/reference-match/${address.address_id}/set/reviewed`);
|
address: Address,
|
||||||
}
|
): Promise<Address> => {
|
||||||
|
return makeFetch<null, Address>(
|
||||||
|
"POST",
|
||||||
|
`/api/1.0/main/address/reference-match/${address.address_id}/set/reviewed`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const markAddressToReview = async (address: Address): Promise<Address> => {
|
export const markAddressToReview = async (
|
||||||
return makeFetch<null, Address>("POST", `/api/1.0/main/address/reference-match/${address.address_id}/set/to_review`);
|
address: Address,
|
||||||
}
|
): Promise<Address> => {
|
||||||
|
return makeFetch<null, Address>(
|
||||||
|
"POST",
|
||||||
|
`/api/1.0/main/address/reference-match/${address.address_id}/set/to_review`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import {Scope} from '../../types';
|
import { Scope } from "../../types";
|
||||||
|
|
||||||
export type body = {[key: string]: boolean|string|number|null};
|
export type body = Record<string, boolean | string | number | null>;
|
||||||
export type fetchOption = {[key: string]: boolean|string|number|null};
|
export type fetchOption = Record<string, boolean | string | number | null>;
|
||||||
|
|
||||||
export interface Params {
|
export type Params = Record<string, number | string>;
|
||||||
[key: string]: number|string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PaginationResponse<T> {
|
export interface PaginationResponse<T> {
|
||||||
pagination: {
|
pagination: {
|
||||||
@ -16,16 +14,15 @@ export interface PaginationResponse<T> {
|
|||||||
count: number;
|
count: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FetchParams {
|
export type FetchParams = Record<string, string | number | null>;
|
||||||
[K: string]: string|number|null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface TransportExceptionInterface {
|
export interface TransportExceptionInterface {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ValidationExceptionInterface extends TransportExceptionInterface {
|
export interface ValidationExceptionInterface
|
||||||
name: 'ValidationException';
|
extends TransportExceptionInterface {
|
||||||
|
name: "ValidationException";
|
||||||
error: object;
|
error: object;
|
||||||
violations: string[];
|
violations: string[];
|
||||||
titles: string[];
|
titles: string[];
|
||||||
@ -40,23 +37,25 @@ export interface ValidationErrorResponse extends TransportExceptionInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AccessExceptionInterface extends TransportExceptionInterface {
|
export interface AccessExceptionInterface extends TransportExceptionInterface {
|
||||||
name: 'AccessException';
|
name: "AccessException";
|
||||||
violations: string[];
|
violations: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NotFoundExceptionInterface extends TransportExceptionInterface {
|
export interface NotFoundExceptionInterface
|
||||||
name: 'NotFoundException';
|
extends TransportExceptionInterface {
|
||||||
|
name: "NotFoundException";
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ServerExceptionInterface extends TransportExceptionInterface {
|
export interface ServerExceptionInterface extends TransportExceptionInterface {
|
||||||
name: 'ServerException';
|
name: "ServerException";
|
||||||
message: string;
|
message: string;
|
||||||
code: number;
|
code: number;
|
||||||
body: string;
|
body: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConflictHttpExceptionInterface extends TransportExceptionInterface {
|
export interface ConflictHttpExceptionInterface
|
||||||
name: 'ConflictHttpException';
|
extends TransportExceptionInterface {
|
||||||
|
name: "ConflictHttpException";
|
||||||
violations: string[];
|
violations: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,35 +63,33 @@ export interface ConflictHttpExceptionInterface extends TransportExceptionInterf
|
|||||||
* Generic api method that can be adapted to any fetch request
|
* Generic api method that can be adapted to any fetch request
|
||||||
*/
|
*/
|
||||||
export const makeFetch = <Input, Output>(
|
export const makeFetch = <Input, Output>(
|
||||||
method: 'POST'|'GET'|'PUT'|'PATCH'|'DELETE',
|
method: "POST" | "GET" | "PUT" | "PATCH" | "DELETE",
|
||||||
url: string, body?: body | Input | null,
|
url: string,
|
||||||
options?: FetchParams
|
body?: body | Input | null,
|
||||||
|
options?: FetchParams,
|
||||||
): Promise<Output> => {
|
): Promise<Output> => {
|
||||||
|
|
||||||
let opts = {
|
let opts = {
|
||||||
method: method,
|
method: method,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
"Content-Type": "application/json;charset=utf-8",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (body !== null && typeof body !== "undefined") {
|
||||||
if (body !== null && typeof body !== 'undefined') {
|
Object.assign(opts, { body: JSON.stringify(body) });
|
||||||
Object.assign(opts, {body: JSON.stringify(body)})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof options !== 'undefined') {
|
if (typeof options !== "undefined") {
|
||||||
opts = Object.assign(opts, options);
|
opts = Object.assign(opts, options);
|
||||||
}
|
}
|
||||||
return fetch(url, opts)
|
return fetch(url, opts).then((response) => {
|
||||||
.then(response => {
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.status === 422) {
|
if (response.status === 422) {
|
||||||
return response.json().then(response => {
|
return response.json().then((response) => {
|
||||||
throw ValidationException(response)
|
throw ValidationException(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,55 +102,62 @@ export const makeFetch = <Input, Output>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw {
|
throw {
|
||||||
name: 'Exception',
|
name: "Exception",
|
||||||
sta: response.status,
|
sta: response.status,
|
||||||
txt: response.statusText,
|
txt: response.statusText,
|
||||||
err: new Error(),
|
err: new Error(),
|
||||||
violations: response.body
|
violations: response.body,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch results with certain parameters
|
* Fetch results with certain parameters
|
||||||
*/
|
*/
|
||||||
function _fetchAction<T>(page: number, uri: string, params?: FetchParams): Promise<PaginationResponse<T>> {
|
function _fetchAction<T>(
|
||||||
const item_per_page: number = 50;
|
page: number,
|
||||||
|
uri: string,
|
||||||
|
params?: FetchParams,
|
||||||
|
): Promise<PaginationResponse<T>> {
|
||||||
|
const item_per_page = 50;
|
||||||
|
|
||||||
let searchParams = new URLSearchParams();
|
const searchParams = new URLSearchParams();
|
||||||
searchParams.append('item_per_page', item_per_page.toString());
|
searchParams.append("item_per_page", item_per_page.toString());
|
||||||
searchParams.append('page', page.toString());
|
searchParams.append("page", page.toString());
|
||||||
|
|
||||||
if (params !== undefined) {
|
if (params !== undefined) {
|
||||||
Object.keys(params).forEach(key => {
|
Object.keys(params).forEach((key) => {
|
||||||
let v = params[key];
|
const v = params[key];
|
||||||
if (typeof v === 'string') {
|
if (typeof v === "string") {
|
||||||
searchParams.append(key, v);
|
searchParams.append(key, v);
|
||||||
} else if (typeof v === 'number') {
|
} else if (typeof v === "number") {
|
||||||
searchParams.append(key, v.toString());
|
searchParams.append(key, v.toString());
|
||||||
} else if (v === null) {
|
} else if (v === null) {
|
||||||
searchParams.append(key, '');
|
searchParams.append(key, "");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = uri + '?' + searchParams.toString();
|
const url = uri + "?" + searchParams.toString();
|
||||||
|
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
method: 'GET',
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
"Content-Type": "application/json;charset=utf-8",
|
||||||
},
|
},
|
||||||
}).then((response) => {
|
})
|
||||||
if (response.ok) { return response.json(); }
|
.then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
if (response.status === 404) {
|
if (response.status === 404) {
|
||||||
throw NotFoundException(response);
|
throw NotFoundException(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.status === 422) {
|
if (response.status === 422) {
|
||||||
return response.json().then(response => {
|
return response.json().then((response) => {
|
||||||
throw ValidationException(response)
|
throw ValidationException(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,22 +166,30 @@ function _fetchAction<T>(page: number, uri: string, params?: FetchParams): Promi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (response.status >= 500) {
|
if (response.status >= 500) {
|
||||||
return response.text().then(body => {
|
return response.text().then((body) => {
|
||||||
throw ServerException(response.status, body);
|
throw ServerException(response.status, body);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error("other network error");
|
throw new Error("other network error");
|
||||||
}).catch((reason: any) => {
|
})
|
||||||
|
.catch((reason: any) => {
|
||||||
console.error(reason);
|
console.error(reason);
|
||||||
throw new Error(reason);
|
throw new Error(reason);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
export const fetchResults = async<T> (uri: string, params?: FetchParams): Promise<T[]> => {
|
export const fetchResults = async <T>(
|
||||||
|
uri: string,
|
||||||
|
params?: FetchParams,
|
||||||
|
): Promise<T[]> => {
|
||||||
let promises: Promise<T[]>[] = [],
|
let promises: Promise<T[]>[] = [],
|
||||||
page = 1;
|
page = 1;
|
||||||
let firstData: PaginationResponse<T> = await _fetchAction(page, uri, params) as PaginationResponse<T>;
|
const firstData: PaginationResponse<T> = (await _fetchAction(
|
||||||
|
page,
|
||||||
|
uri,
|
||||||
|
params,
|
||||||
|
)) as PaginationResponse<T>;
|
||||||
|
|
||||||
promises.push(Promise.resolve(firstData.results));
|
promises.push(Promise.resolve(firstData.results));
|
||||||
|
|
||||||
@ -185,61 +197,74 @@ export const fetchResults = async<T> (uri: string, params?: FetchParams): Promis
|
|||||||
do {
|
do {
|
||||||
page = ++page;
|
page = ++page;
|
||||||
promises.push(
|
promises.push(
|
||||||
_fetchAction<T>(page, uri, params)
|
_fetchAction<T>(page, uri, params).then((r) =>
|
||||||
.then(r => Promise.resolve(r.results))
|
Promise.resolve(r.results),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} while (page * firstData.pagination.items_per_page < firstData.count)
|
} while (page * firstData.pagination.items_per_page < firstData.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises).then((values) => values.flat());
|
return Promise.all(promises).then((values) => values.flat());
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchScopes = (): Promise<Scope[]> => {
|
export const fetchScopes = (): Promise<Scope[]> => {
|
||||||
return fetchResults('/api/1.0/main/scope.json');
|
return fetchResults("/api/1.0/main/scope.json");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error objects to be thrown
|
* Error objects to be thrown
|
||||||
*/
|
*/
|
||||||
const ValidationException = (response: ValidationErrorResponse): ValidationExceptionInterface => {
|
const ValidationException = (
|
||||||
|
response: ValidationErrorResponse,
|
||||||
|
): ValidationExceptionInterface => {
|
||||||
const error = {} as ValidationExceptionInterface;
|
const error = {} as ValidationExceptionInterface;
|
||||||
error.name = 'ValidationException';
|
error.name = "ValidationException";
|
||||||
error.violations = response.violations.map((violation) => `${violation.title}: ${violation.propertyPath}`);
|
error.violations = response.violations.map(
|
||||||
|
(violation) => `${violation.title}: ${violation.propertyPath}`,
|
||||||
|
);
|
||||||
error.titles = response.violations.map((violation) => violation.title);
|
error.titles = response.violations.map((violation) => violation.title);
|
||||||
error.propertyPaths = response.violations.map((violation) => violation.propertyPath);
|
error.propertyPaths = response.violations.map(
|
||||||
|
(violation) => violation.propertyPath,
|
||||||
|
);
|
||||||
return error;
|
return error;
|
||||||
}
|
};
|
||||||
|
|
||||||
const AccessException = (response: Response): AccessExceptionInterface => {
|
const AccessException = (response: Response): AccessExceptionInterface => {
|
||||||
const error = {} as AccessExceptionInterface;
|
const error = {} as AccessExceptionInterface;
|
||||||
error.name = 'AccessException';
|
error.name = "AccessException";
|
||||||
error.violations = ['You are not allowed to perform this action'];
|
error.violations = ["You are not allowed to perform this action"];
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
};
|
||||||
|
|
||||||
const NotFoundException = (response: Response): NotFoundExceptionInterface => {
|
const NotFoundException = (response: Response): NotFoundExceptionInterface => {
|
||||||
const error = {} as NotFoundExceptionInterface;
|
const error = {} as NotFoundExceptionInterface;
|
||||||
error.name = 'NotFoundException';
|
error.name = "NotFoundException";
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
};
|
||||||
|
|
||||||
const ServerException = (code: number, body: string): ServerExceptionInterface => {
|
const ServerException = (
|
||||||
|
code: number,
|
||||||
|
body: string,
|
||||||
|
): ServerExceptionInterface => {
|
||||||
const error = {} as ServerExceptionInterface;
|
const error = {} as ServerExceptionInterface;
|
||||||
error.name = 'ServerException';
|
error.name = "ServerException";
|
||||||
error.code = code;
|
error.code = code;
|
||||||
error.body = body;
|
error.body = body;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
};
|
||||||
|
|
||||||
const ConflictHttpException = (response: Response): ConflictHttpExceptionInterface => {
|
const ConflictHttpException = (
|
||||||
|
response: Response,
|
||||||
|
): ConflictHttpExceptionInterface => {
|
||||||
const error = {} as ConflictHttpExceptionInterface;
|
const error = {} as ConflictHttpExceptionInterface;
|
||||||
|
|
||||||
error.name = 'ConflictHttpException';
|
error.name = "ConflictHttpException";
|
||||||
error.violations = ['Sorry, but someone else has already changed this entity. Please refresh the page and apply the changes again']
|
error.violations = [
|
||||||
|
"Sorry, but someone else has already changed this entity. Please refresh the page and apply the changes again",
|
||||||
|
];
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
};
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// const _fetchAction = (page, uri, params) => {
|
// const _fetchAction = (page, uri, params) => {
|
||||||
// const item_per_page = 50;
|
// const item_per_page = 50;
|
||||||
// if (params === undefined) {
|
// if (params === undefined) {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { fetchResults } from "./apiMethods";
|
import { fetchResults } from "./apiMethods";
|
||||||
import { Location, LocationType } from "../../types";
|
import { Location, LocationType } from "../../types";
|
||||||
|
|
||||||
export const getLocations = (): Promise<Location[]> => fetchResults('/api/1.0/main/location.json');
|
export const getLocations = (): Promise<Location[]> =>
|
||||||
|
fetchResults("/api/1.0/main/location.json");
|
||||||
|
|
||||||
export const getLocationTypes = (): Promise<LocationType[]> => fetchResults('/api/1.0/main/location-type.json');
|
export const getLocationTypes = (): Promise<LocationType[]> =>
|
||||||
|
fetchResults("/api/1.0/main/location-type.json");
|
||||||
|
@ -3,17 +3,16 @@ import {makeFetch} from "./apiMethods";
|
|||||||
|
|
||||||
export const whoami = (): Promise<User> => {
|
export const whoami = (): Promise<User> => {
|
||||||
const url = `/api/1.0/main/whoami.json`;
|
const url = `/api/1.0/main/whoami.json`;
|
||||||
return fetch(url)
|
return fetch(url).then((response) => {
|
||||||
.then(response => {
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
throw {
|
throw {
|
||||||
msg: 'Error while getting whoami.',
|
msg: "Error while getting whoami.",
|
||||||
sta: response.status,
|
sta: response.status,
|
||||||
txt: response.statusText,
|
txt: response.statusText,
|
||||||
err: new Error(),
|
err: new Error(),
|
||||||
body: response.body
|
body: response.body,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -22,4 +21,4 @@ export const whereami = (): Promise<Location | null> => {
|
|||||||
const url = `/api/1.0/main/user-current-location.json`;
|
const url = `/api/1.0/main/user-current-location.json`;
|
||||||
|
|
||||||
return makeFetch<null, Location | null>("GET", url);
|
return makeFetch<null, Location | null>("GET", url);
|
||||||
}
|
};
|
||||||
|
@ -1,3 +1 @@
|
|||||||
require("./layout.scss");
|
require("./layout.scss");
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,40 +15,44 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import mime from 'mime';
|
import mime from "mime";
|
||||||
|
|
||||||
export const download_report = (url, container) => {
|
export const download_report = (url, container) => {
|
||||||
var download_text = container.dataset.downloadText,
|
var download_text = container.dataset.downloadText,
|
||||||
alias = container.dataset.alias;
|
alias = container.dataset.alias;
|
||||||
|
|
||||||
window.fetch(url, { credentials: 'same-origin' })
|
window
|
||||||
.then(response => {
|
.fetch(url, { credentials: "same-origin" })
|
||||||
|
.then((response) => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw Error(response.statusText);
|
throw Error(response.statusText);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.blob();
|
return response.blob();
|
||||||
}).then(blob => {
|
})
|
||||||
|
.then((blob) => {
|
||||||
var content = URL.createObjectURL(blob),
|
var content = URL.createObjectURL(blob),
|
||||||
link = document.createElement("a"),
|
link = document.createElement("a"),
|
||||||
type = blob.type,
|
type = blob.type,
|
||||||
hasForcedType = 'mimeType' in container.dataset,
|
hasForcedType = "mimeType" in container.dataset,
|
||||||
extension;
|
extension;
|
||||||
|
|
||||||
if (hasForcedType) {
|
if (hasForcedType) {
|
||||||
// force a type
|
// force a type
|
||||||
type = container.dataset.mimeType;
|
type = container.dataset.mimeType;
|
||||||
blob = new Blob([ blob ], { 'type': type });
|
blob = new Blob([blob], { type: type });
|
||||||
content = URL.createObjectURL(blob);
|
content = URL.createObjectURL(blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
const extensions = new Map();
|
const extensions = new Map();
|
||||||
extensions.set('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlsx');
|
extensions.set(
|
||||||
extensions.set('application/vnd.oasis.opendocument.spreadsheet', 'ods');
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
extensions.set('application/vnd.ms-excel', 'xlsx');
|
"xlsx",
|
||||||
extensions.set('text/csv', 'csv');
|
);
|
||||||
extensions.set('text/csv; charset=utf-8', 'csv');
|
extensions.set("application/vnd.oasis.opendocument.spreadsheet", "ods");
|
||||||
|
extensions.set("application/vnd.ms-excel", "xlsx");
|
||||||
|
extensions.set("text/csv", "csv");
|
||||||
|
extensions.set("text/csv; charset=utf-8", "csv");
|
||||||
|
|
||||||
extension = extensions.get(type);
|
extension = extensions.get(type);
|
||||||
|
|
||||||
@ -57,16 +61,15 @@ export const download_report = (url, container) => {
|
|||||||
link.href = content;
|
link.href = content;
|
||||||
link.download = alias;
|
link.download = alias;
|
||||||
if (extension !== false) {
|
if (extension !== false) {
|
||||||
link.download = link.download + '.' + extension;
|
link.download = link.download + "." + extension;
|
||||||
}
|
}
|
||||||
container.innerHTML = "";
|
container.innerHTML = "";
|
||||||
container.appendChild(link);
|
container.appendChild(link);
|
||||||
}).catch(function(error) {
|
})
|
||||||
|
.catch(function (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
var problem_text =
|
var problem_text = document.createTextNode("Problem during download");
|
||||||
document.createTextNode("Problem during download");
|
|
||||||
|
|
||||||
container
|
container.replaceChild(problem_text, container.firstChild);
|
||||||
.replaceChild(problem_text, container.firstChild);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
const buildLinkCreate = function (relatedEntityClass: string, relatedEntityId: number, to: number | null, returnPath: string | null): string
|
const buildLinkCreate = function (
|
||||||
{
|
relatedEntityClass: string,
|
||||||
|
relatedEntityId: number,
|
||||||
|
to: number | null,
|
||||||
|
returnPath: string | null,
|
||||||
|
): string {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.append('entityClass', relatedEntityClass);
|
params.append("entityClass", relatedEntityClass);
|
||||||
params.append('entityId', relatedEntityId.toString());
|
params.append("entityId", relatedEntityId.toString());
|
||||||
|
|
||||||
if (null !== to) {
|
if (null !== to) {
|
||||||
params.append('tos[0]', to.toString());
|
params.append("tos[0]", to.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== returnPath) {
|
if (null !== returnPath) {
|
||||||
params.append('returnPath', returnPath);
|
params.append("returnPath", returnPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `/fr/notification/create?${params.toString()}`;
|
return `/fr/notification/create?${params.toString()}`;
|
||||||
}
|
};
|
||||||
|
|
||||||
export {
|
export { buildLinkCreate };
|
||||||
buildLinkCreate,
|
|
||||||
}
|
|
||||||
|
@ -1,18 +1,12 @@
|
|||||||
|
window.addEventListener("load", function (e) {
|
||||||
window.addEventListener('load', function (e) {
|
var postalCodes = document.querySelectorAll(
|
||||||
var
|
"[data-select-interactive-loading]",
|
||||||
postalCodes = document.querySelectorAll('[data-select-interactive-loading]')
|
);
|
||||||
;
|
|
||||||
|
|
||||||
for (let i = 0; i < postalCodes.length; i++) {
|
for (let i = 0; i < postalCodes.length; i++) {
|
||||||
let
|
let searchUrl = postalCodes[i].dataset.searchUrl,
|
||||||
searchUrl = postalCodes[i].dataset.searchUrl,
|
|
||||||
noResultsLabel = postalCodes[i].dataset.noResultsLabel,
|
noResultsLabel = postalCodes[i].dataset.noResultsLabel,
|
||||||
errorLoadLabel = postalCodes[i].dataset.errorLoadLabel,
|
errorLoadLabel = postalCodes[i].dataset.errorLoadLabel,
|
||||||
searchingLabel = postalCodes[i].dataset.searchingLabel
|
searchingLabel = postalCodes[i].dataset.searchingLabel;
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
$(postalCodes[i]).select2({
|
$(postalCodes[i]).select2({
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
language: {
|
language: {
|
||||||
@ -24,13 +18,13 @@ window.addEventListener('load', function (e) {
|
|||||||
},
|
},
|
||||||
searching: function () {
|
searching: function () {
|
||||||
return searchingLabel;
|
return searchingLabel;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
ajax: {
|
ajax: {
|
||||||
url: searchUrl,
|
url: searchUrl,
|
||||||
dataType: 'json',
|
dataType: "json",
|
||||||
delay: 250
|
delay: 250,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//require("./show_hide.js");
|
//require("./show_hide.js");
|
||||||
|
|
||||||
import { ShowHide } from './show_hide.js'
|
import { ShowHide } from "./show_hide.js";
|
||||||
|
|
||||||
export { ShowHide }
|
export { ShowHide };
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user