TerrainDeVie.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. <script>
  2. import { mapActions, mapState } from 'pinia'
  3. import { ConcernementsStore } from '@stores/concernements'
  4. import { UserStore } from '@/stores/user'
  5. // import { CommonStore } from '@/stores/common'
  6. import { print } from 'graphql/language/printer'
  7. import gql from 'graphql-tag'
  8. import GQL from '@api/graphql-axios'
  9. import EntiteFields from '@api/gql/entite.fragment.gql'
  10. import CartoucheLayout from '@components/layout/CartoucheLayout.vue';
  11. import Entite from '@components/contents/Entite.vue';
  12. import VueSlider from 'vue-slider-component'
  13. import 'vue-slider-component/theme/default.css'
  14. import SvgIcon from '@jamescoyle/vue-icon';
  15. import { mdiChevronRight } from '@mdi/js';
  16. import { mdiChevronDown } from '@mdi/js';
  17. import ContentEditable from '@components/editable/ContentEditable.vue';
  18. import CheckboxEditable from '@components/editable/CheckboxEditable.vue';
  19. import SelectEditable from '@components/editable/SelectEditable.vue';
  20. export default {
  21. props: ['cid', 'eid'],
  22. data(){
  23. return {
  24. concernement: null,
  25. entite: null,
  26. history_value: 0,
  27. history_slider_ops: null,
  28. details_value: 1,
  29. details_slider_ops: null,
  30. infos_opened: false,
  31. chevronright_path: mdiChevronRight,
  32. chevrondown_path: mdiChevronDown,
  33. headerreduced: false,
  34. }
  35. },
  36. computed: {
  37. ...mapState(ConcernementsStore,['map_mode',
  38. 'opened_concernement',
  39. 'concernementsByID',
  40. 'ct_concernement',
  41. 'ct_entite',
  42. 'detailsZoomValue']),
  43. ...mapState(UserStore,['name']),
  44. created(){
  45. let d = new Date(this.concernement.created);
  46. console.log('d', d);
  47. return d.toLocaleDateString("fr-FR");//.toISOString().split('T')[0];
  48. },
  49. changed(){
  50. let d = new Date(this.concernement.changed);
  51. console.log('d', d);
  52. return d.toLocaleDateString("fr-FR");//.toISOString().split('T')[0];
  53. },
  54. display_concernement(){
  55. return this.ct_concernement && !this.entite && this.map_mode !== 'puissancedagir' && this.map_mode !== 'doleancer';
  56. },
  57. entity_title_label(){
  58. let menacemaintien_str;
  59. if (this.concernement.entites_byid[this.eid].menacemaintien > 0) {
  60. menacemaintien_str = 'maintenu';
  61. } else {
  62. menacemaintien_str = 'menacé';
  63. }
  64. let actuelfuture_str;
  65. if (this.concernement.entites_byid[this.eid].actuelfuture > 0) {
  66. actuelfuture_str = 'sera';
  67. } else {
  68. actuelfuture_str = 'est';
  69. }
  70. return `Pouvez-vous nommer par qui ou par quoi cet élément ${actuelfuture_str} ${menacemaintien_str} ?`;
  71. }
  72. },
  73. created () {
  74. this.concernement = this.concernementsByID[this.cid];
  75. console.log(`terraindevie created, cid: ${this.cid}, eid: ${this.eid}, this.concernement:`, this.concernement);
  76. //entite
  77. if (this.eid) {
  78. this.loadEntite()
  79. }
  80. // revisions
  81. let data=[];
  82. if (this.concernement && this.concernement.revisions) {
  83. this.concernement.revisions.forEach(rev => {
  84. if (rev.entites.length > 3) {
  85. let d = new Date(rev.changed);
  86. data.push({
  87. 'id': rev.revision_id,
  88. 'changed': d.toLocaleDateString("fr-FR")
  89. })
  90. this.history_value = Math.max(this.history_value, parseInt(rev.revision_id));
  91. }
  92. });
  93. }
  94. if (data.length > 1) {
  95. this.history_slider_ops = {
  96. dotSize:10,
  97. data: data,
  98. 'data-value': 'id',
  99. 'data-label': 'changed',
  100. adsorb: true,
  101. 'hide-label': true
  102. }
  103. } else {
  104. this.history_slider_ops = null;
  105. }
  106. // details
  107. this.details_slider_ops = {
  108. min: 1,
  109. max: 4,
  110. interval: 0.05,
  111. 'hide-label': true,
  112. tooltip: 'none',
  113. dotSize:10,
  114. }
  115. },
  116. // mounted(){
  117. // console.log('terrain de vie mounted', this);
  118. // // this.$refs.cartouche_main.addEventListener('scroll', (event) => {
  119. // // console.log('main is scrolling', event);
  120. // // })
  121. // },
  122. watch: {
  123. history_value: {
  124. handler (n, o) {
  125. // console.log(`TerrainDeVie watch history_value o:${o}, n:${n}`);
  126. this.setActiveRevision(this.cid, n);
  127. },
  128. deep: true
  129. },
  130. details_value: {
  131. handler (n, o) {
  132. // console.log(`TerrainDeVie watch history_value o:${o}, n:${n}`);
  133. this.setDetailsZoomValue(n);
  134. },
  135. deep: true
  136. },
  137. detailsZoomValue: {
  138. handler (n, o) {
  139. // console.log(`TerrainDeVie watch history_value o:${o}, n:${n}`);
  140. this.details_value = n;
  141. },
  142. deep: true
  143. },
  144. cid: {
  145. handler (n,o) {
  146. console.log(`TerrainDeVie watch cid o:${o}, n:${n}`);
  147. if (n) {
  148. this.concernement = this.concernementsByID[n];
  149. }
  150. },
  151. deep: true
  152. },
  153. eid: {
  154. handler (n, o) {
  155. console.log(`TerrainDeVie watch eid o:${o}, n:${n}`);
  156. if (n) {
  157. this.loadEntite()
  158. }else{
  159. this.entite = null;
  160. }
  161. },
  162. deep: true
  163. }
  164. },
  165. methods: {
  166. ...mapActions(ConcernementsStore, ['setActiveRevision', 'setDetailsZoomValue']), // 'loadConcernementsRevisions'
  167. onClickInfos(){
  168. this.infos_opened = !this.infos_opened;
  169. },
  170. loadEntite(){
  171. const ast = gql`{
  172. entite (id: ${this.eid}) {
  173. ...EntiteFields
  174. }
  175. }
  176. ${EntiteFields}
  177. `
  178. console.log('ast', ast);
  179. GQL.post('', { query: print(ast) })
  180. .then(({data: { data: { entite }}}) => {
  181. console.log('load entite loaded', entite)
  182. this.entite = entite
  183. })
  184. .catch(error => {
  185. console.warn('Issue with load entite', error)
  186. })
  187. },
  188. onMainScrolled(scrolled){
  189. // console.log('this.$refs', this.$refs);
  190. let cartouche_main = this.$refs.cartouche_layout.$refs.cartouche_main;
  191. // console.log('cartouche_main', cartouche_main);
  192. if(scrolled && cartouche_main.scrollHeight > 600){
  193. this.headerreduced = true;
  194. } else {
  195. this.headerreduced = false;
  196. }
  197. },
  198. onContentEditableFocusOut(e){
  199. console.log('onContentEditableFocusOut', e);
  200. let new_field_content = e.target.innerText;
  201. console.log('onContentEditableFocusOut', new_field_content);
  202. console.log('onContentEditableFocusOut this.concernement.title', this.concernement.title);
  203. }
  204. },
  205. components: {
  206. CartoucheLayout,
  207. Entite,
  208. VueSlider,
  209. SvgIcon,
  210. ContentEditable,
  211. CheckboxEditable,
  212. SelectEditable
  213. }
  214. }
  215. </script>
  216. <template>
  217. <CartoucheLayout ref="cartouche_layout" :cid="cid" @main_scrolled="onMainScrolled">
  218. <template v-slot:header>
  219. <div class="entite">
  220. <!-- TODO update entite with revisions -->
  221. <label v-if="entite" class="menacemaintient" :class="{ hidden: headerreduced}">{{ entity_title_label }}</label>
  222. <!-- <h3 v-if="entite" class="entite-title">{{ entite.title }}</h3> -->
  223. <ContentEditable
  224. v-if="entite"
  225. tag="h3"
  226. :value="entite.title"
  227. class="entite-title"
  228. :contenteditable="entite.can_update"
  229. :data="{
  230. entitytype: 'node',
  231. bundle: 'entite',
  232. id: this.entite.id,
  233. field: {field_name: 'title', value:'value'}
  234. }" />
  235. <CheckboxEditable
  236. v-if="entite && entite.can_update"
  237. :checked="entite.agissante"
  238. label="Entité action"
  239. :data="{
  240. entitytype: 'node',
  241. bundle: 'entite',
  242. nid: this.entite.id,
  243. field: 'field_entite_agissante'
  244. }" />
  245. <SelectEditable
  246. v-if="entite && entite.can_update"
  247. label="Confidentialité"
  248. :value="entite.confidentialite"
  249. :options="{
  250. 'confidentialite_prive': 'privé',
  251. 'confidentialite_interne': 'interne',
  252. 'confidentialite_public': 'public'
  253. }"
  254. :data="{
  255. entitytype: 'node',
  256. bundle: 'entite',
  257. nid: this.entite.id,
  258. field: 'field_confidentialite'
  259. }" />
  260. </div>
  261. </template>
  262. <template v-slot:main>
  263. <!-- concernement -->
  264. <template v-if="!entite">
  265. <section v-if="concernement.description || concernement.can_update" class="description">
  266. <label v-if="ct_concernement">{{ ct_concernement.field_description.description }}</label>
  267. <ContentEditable
  268. tag="p"
  269. :value="concernement.description"
  270. :html="true"
  271. :class="{ ellipsed: headerreduced }"
  272. :contenteditable="concernement.can_update"
  273. :data="{
  274. entitytype: 'node',
  275. bundle: 'concernement',
  276. id: this.concernement.id,
  277. field: {field_name: 'field_description', value:'value'}
  278. }" />
  279. </section>
  280. <section v-if="concernement.caillou || concernement.can_update" class="caillou">
  281. <label v-if="ct_concernement">{{ ct_concernement.field_caillou.description }}</label>
  282. <ContentEditable
  283. tag="p"
  284. :value="concernement.caillou"
  285. :class="{ ellipsed: headerreduced }"
  286. :contenteditable="concernement.can_update"
  287. :data="{
  288. entitytype: 'node',
  289. bundle: 'concernement',
  290. id: this.concernement.id,
  291. field: {field_name: 'field_caillou', value:'value'}
  292. }" />
  293. </section>
  294. </template>
  295. <!-- entite -->
  296. <Entite v-if="entite" :concernement="concernement" :entite="entite" :eid="eid" v-on:reloadEntite="loadEntite"/>
  297. </template>
  298. <template v-slot:footer>
  299. <section class="infos">
  300. <svg-icon
  301. type="mdi"
  302. :path="!infos_opened ? chevronright_path : chevrondown_path"
  303. class="open-btn"
  304. @click="onClickInfos"
  305. ></svg-icon>
  306. <div
  307. class="author info"
  308. @click="onClickInfos">
  309. <span>une enquête de</span> {{ concernement.author.username }}<br/>
  310. </div>
  311. <div class="wrapper" :class="{ 'opened': infos_opened }">
  312. <div class="info structure" v-if="concernement.author.structure.length"><span>avec</span> {{ concernement.author.structure[0].name }}<br/></div>
  313. <div class="info lieu" v-if="concernement.lieu.length"><span>à</span> {{ concernement.lieu[0].name }}<br/></div>
  314. <div class="info created"><span>démarrée le</span> {{ created }}<br/></div>
  315. <div class="info changed"><span>mise à jour le</span> {{ changed }}</div>
  316. <div class="info recit-colophon" v-if="concernement.recit_colophon" v-html="concernement.recit_colophon"/>
  317. </div>
  318. </section>
  319. <section class="sliders" v-if="history_slider_ops || details_slider_ops">
  320. <section class="historique" v-if="history_slider_ops">
  321. <label>Historique</label>
  322. <!-- <h3>{{ history_value }}</h3> -->
  323. <vue-slider
  324. ref="slider"
  325. v-model="history_value"
  326. v-bind="history_slider_ops"
  327. ></vue-slider>
  328. </section>
  329. <section class="details" v-if="details_slider_ops && map_mode === 'terraindevie'">
  330. <label>Détails</label>
  331. <!-- <h3>{{ details_value }}</h3> -->
  332. <vue-slider
  333. ref="details_slider"
  334. v-model="details_value"
  335. v-bind="details_slider_ops"
  336. ></vue-slider>
  337. </section>
  338. </section>
  339. </template>
  340. </CartoucheLayout>
  341. </template>
  342. <style lang="css">
  343. span.entite-point{
  344. color: #01ffe2;
  345. }
  346. </style>