Bladeren bron

initialisation with SMETI code

production
Thibaud 1 jaar geleden
commit
2030381b45
118 gewijzigde bestanden met toevoegingen van 5779 en 0 verwijderingen
  1. +6
    -0
      .gitignore
  2. BIN
      frontend/fonts/Assistant.woff2
  3. BIN
      frontend/fonts/Fonte-Texte.woff2
  4. BIN
      frontend/fonts/Fonte-Titre.woff2
  5. BIN
      frontend/fonts/Garamond.woff2
  6. BIN
      frontend/fonts/Marianne.woff2
  7. BIN
      frontend/fonts/original/Bangers_font.zip
  8. BIN
      frontend/fonts/original/Garamond_font.zip
  9. BIN
      frontend/fonts/original/Marianne.otf
  10. BIN
      frontend/fonts/original/Marianne/.DS_Store
  11. BIN
      frontend/fonts/original/Marianne/fontes desktop/.DS_Store
  12. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-Bold.otf
  13. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-BoldItalic.otf
  14. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-ExtraBold.otf
  15. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-ExtraBoldItalic.otf
  16. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-Light.otf
  17. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-LightItalic.otf
  18. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-Medium.otf
  19. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-MediumItalic.otf
  20. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-RegularItalic.otf
  21. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-Thin.otf
  22. BIN
      frontend/fonts/original/Marianne/fontes desktop/Marianne-ThinItalic.otf
  23. BIN
      frontend/fonts/original/Marianne/fontes web/.DS_Store
  24. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Bold.woff
  25. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Bold.woff2
  26. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Bold_Italic.woff
  27. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Bold_Italic.woff2
  28. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-ExtraBold.woff
  29. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-ExtraBold.woff2
  30. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-ExtraBold_Italic.woff
  31. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-ExtraBold_Italic.woff2
  32. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Light.woff
  33. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Light.woff2
  34. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Light_Italic.woff
  35. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Light_Italic.woff2
  36. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Medium.woff
  37. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Medium.woff2
  38. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Medium_Italic.woff
  39. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Medium_Italic.woff2
  40. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Regular.woff
  41. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Regular.woff2
  42. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Regular_Italic.woff
  43. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Regular_Italic.woff2
  44. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Thin.woff
  45. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Thin.woff2
  46. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Thin_Italic.woff
  47. BIN
      frontend/fonts/original/Marianne/fontes web/Marianne-Thin_Italic.woff2
  48. BIN
      frontend/fonts/original/Marianne/pdfs/.DS_Store
  49. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne 11.01.46.pdf
  50. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne Bold 11.01.46.pdf
  51. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne Bold Italic 11.01.46.pdf
  52. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne ExtraBold 11.01.46.pdf
  53. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne ExtraBold Italic 11.01.46.pdf
  54. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne Italic 11.01.46.pdf
  55. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne Light 11.01.46.pdf
  56. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne Light Italic 11.01.46.pdf
  57. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne Medium 11.01.46.pdf
  58. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne Medium Italic 11.01.46.pdf
  59. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne Thin 11.01.46.pdf
  60. BIN
      frontend/fonts/original/Marianne/pdfs/Marianne Thin Italic 11.01.46.pdf
  61. BIN
      frontend/fonts/original/Marianne_fd0ba9c190.zip
  62. BIN
      frontend/fonts/original/Source-sans-pro.zip
  63. BIN
      frontend/fonts/original/Spectral_2a059d2f08.zip
  64. +7
    -0
      frontend/fonts/process_fonts.sh
  65. BIN
      frontend/images/LoginBanner.jpg
  66. +7
    -0
      frontend/images/anonymous.svg
  67. +1
    -0
      frontend/images/filter.svg
  68. +55
    -0
      frontend/images/logo.svg
  69. +1
    -0
      frontend/images/setup.svg
  70. +351
    -0
      frontend/images/topisto.svg
  71. +12
    -0
      frontend/images/user.svg
  72. +298
    -0
      frontend/src/html/index.html
  73. +381
    -0
      frontend/src/html/logo.html
  74. +19
    -0
      frontend/src/scripts/UI/IntersectionObserver/footer.js
  75. +12
    -0
      frontend/src/scripts/UI/IntersectionObserver/header.js
  76. +17
    -0
      frontend/src/scripts/UI/IntersectionObserver/synthesis.js
  77. +855
    -0
      frontend/src/scripts/UI/calendrier.js
  78. +147
    -0
      frontend/src/scripts/UI/datagrid.js
  79. +154
    -0
      frontend/src/scripts/UI/modal.js
  80. +83
    -0
      frontend/src/scripts/UI/planning.js
  81. +74
    -0
      frontend/src/scripts/UI/pomodoro.js
  82. +163
    -0
      frontend/src/scripts/UI/settings.js
  83. +77
    -0
      frontend/src/scripts/api/clients.js
  84. +98
    -0
      frontend/src/scripts/api/collaborateurs.js
  85. +5
    -0
      frontend/src/scripts/api/entities.js
  86. +728
    -0
      frontend/src/scripts/api/items.js
  87. +118
    -0
      frontend/src/scripts/api/items/prestations.js
  88. +106
    -0
      frontend/src/scripts/api/items/taches.js
  89. +525
    -0
      frontend/src/scripts/api/items/todos.js
  90. +79
    -0
      frontend/src/scripts/api/status.js
  91. +11
    -0
      frontend/src/scripts/ariane.js
  92. +15
    -0
      frontend/src/scripts/contexte.js
  93. +497
    -0
      frontend/src/scripts/default.js
  94. +71
    -0
      frontend/src/scripts/filtres.js
  95. +13
    -0
      frontend/src/scripts/parametres.js
  96. +128
    -0
      frontend/src/scripts/tools/dates.js
  97. +27
    -0
      frontend/src/scripts/tools/delai.js
  98. +10
    -0
      frontend/src/scripts/tools/logs.js
  99. +19
    -0
      frontend/src/scripts/tools/postData.js
  100. +10
    -0
      frontend/src/scripts/tools/svg-inject.min.js

+ 6
- 0
.gitignore Bestand weergeven

@ -0,0 +1,6 @@
backend/data/*
backend/vendor/*
frontend/index.html
frontend/src/index.html
frontend/scripts/*
frontend/styles/*

BIN
frontend/fonts/Assistant.woff2 Bestand weergeven


BIN
frontend/fonts/Fonte-Texte.woff2 Bestand weergeven


BIN
frontend/fonts/Fonte-Titre.woff2 Bestand weergeven


BIN
frontend/fonts/Garamond.woff2 Bestand weergeven


BIN
frontend/fonts/Marianne.woff2 Bestand weergeven


BIN
frontend/fonts/original/Bangers_font.zip Bestand weergeven


BIN
frontend/fonts/original/Garamond_font.zip Bestand weergeven


BIN
frontend/fonts/original/Marianne.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/.DS_Store Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/.DS_Store Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-Bold.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-BoldItalic.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-ExtraBold.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-ExtraBoldItalic.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-Light.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-LightItalic.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-Medium.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-MediumItalic.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-RegularItalic.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-Thin.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes desktop/Marianne-ThinItalic.otf Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/.DS_Store Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Bold.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Bold.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Bold_Italic.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Bold_Italic.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-ExtraBold.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-ExtraBold.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-ExtraBold_Italic.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-ExtraBold_Italic.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Light.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Light.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Light_Italic.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Light_Italic.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Medium.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Medium.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Medium_Italic.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Medium_Italic.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Regular.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Regular.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Regular_Italic.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Regular_Italic.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Thin.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Thin.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Thin_Italic.woff Bestand weergeven


BIN
frontend/fonts/original/Marianne/fontes web/Marianne-Thin_Italic.woff2 Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/.DS_Store Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne Bold 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne Bold Italic 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne ExtraBold 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne ExtraBold Italic 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne Italic 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne Light 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne Light Italic 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne Medium 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne Medium Italic 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne Thin 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne/pdfs/Marianne Thin Italic 11.01.46.pdf Bestand weergeven


BIN
frontend/fonts/original/Marianne_fd0ba9c190.zip Bestand weergeven


BIN
frontend/fonts/original/Source-sans-pro.zip Bestand weergeven


BIN
frontend/fonts/original/Spectral_2a059d2f08.zip Bestand weergeven


+ 7
- 0
frontend/fonts/process_fonts.sh Bestand weergeven

@ -0,0 +1,7 @@
#!/bin/bash
# que le charset pour le Français
#pyftsubset $1 --unicodes="U+20-5F, U+61-7A, U+7C, U+A0, U+A7, U+A9, U+AB, U+B2-B3, U+BB, U+C0, U+C2, U+C6-CB, U+CE-CF, U+D4, U+D9, U+DB-DC, U+E0, U+E2, U+E6-EB, U+EE-EF, U+F4, U+F9, U+FB-FC, U+FF, U+152-153, U+178, U+2B3, U+2E2, U+1D48-1D49, U+2010-2011, U+2013-2014, U+2019, U+201C-201D, U+2020-2021, U+2026, U+202F-2030, U+20AC, U+2212" --layout-features='*' --flavor=woff2 --output-file=$2
# que les majuscules
pyftsubset $1 --unicodes="U+41-5A" --layout-features='*' --flavor=woff2 --output-file=$2

BIN
frontend/images/LoginBanner.jpg Bestand weergeven

Voor Na
Breedte: 1850  |  Hoogte: 692  |  Grootte: 322 KiB

+ 7
- 0
frontend/images/anonymous.svg Bestand weergeven

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
<g><g><g><path fill="#000000" d="M117.8,15.8c-14.5,2.6-27.1,10.4-35.9,22.1c-2.7,3.6-3.5,4.4-5.4,5.1c-4.5,1.7-6.2,2.7-6.9,4c-0.6,1.2-0.6,4.7,0.7,36l1.4,34.7l1.4,4.8c5.9,20.5,18.6,37,34.3,44.9c3.5,1.7,9.4,3.7,12.6,4.2c2.1,0.3,2,0.1,2.9,5.1c0.4,2.2,0.7,3,1.8,4.1l1.4,1.2h-1.8c-2.6,0-9-1.2-13.2-2.6c-8.8-2.8-16.8-7.7-24.1-14.7c-4.7-4.5-6.4-5.5-8.1-5c-6.8,2-28.9,10.1-33.2,12.2c-17.6,8.5-30.2,24.7-34.3,44c-1.2,5.9-1.8,20.1-0.9,22.4c1.2,3-8,2.8,117.5,2.8c81.2,0,114.6-0.1,115.4-0.5c2.2-1,2.6-2.5,2.6-9.4c0-16.7-4.6-30.2-14.5-42.5c-5.7-7.1-12.8-12.7-21.3-16.8c-4.2-2.1-26.6-10.2-33.2-12.2c-1.7-0.5-3.4,0.6-7.8,4.7c-7.5,7.2-15.3,12-23.9,14.8c-4.7,1.5-11,2.8-13.8,2.8h-1.9l1.2-0.9c1.2-1,1.9-2.5,2.4-5.8c0.5-3.2,0.6-3.4,2.7-3.7c3.2-0.6,9.1-2.5,12.5-4.2c15.7-7.9,28.3-24.4,34.3-44.9l1.4-4.8l1.4-34.7c1.3-31.3,1.4-34.8,0.7-36c-0.7-1.3-3.5-3-7.3-4.2c-1.4-0.5-2.4-1.5-4.9-4.8c-8.9-11.9-21.6-19.6-36.3-22.2C132.9,14.8,122.6,14.9,117.8,15.8z M140,26.2c7,1.8,14.3,5.6,19.5,10.3l1.4,1.2l-1.8-0.3c-15.6-2.4-28.4-3.2-38.8-2.6c-6.6,0.4-16.7,1.5-23.4,2.6L95,37.7l1.6-1.4c6.2-5.5,15.3-9.7,24.2-11.1C125.6,24.4,135,25,140,26.2z M142.1,45.2c8.3,0.8,14.7,1.8,20.7,3c7.3,1.6,7.5,1.7,8.6,4.1c3,6.6,4.6,13.6,4.6,20.7c0,5.3-1.3,38.9-1.7,42.3l-0.2,2.4h-2.9c-5.5,0-16.4-2-20.5-3.8c-3-1.2-4.5-1.1-6.4,0.7c-1.1,1.1-1.6,2-1.6,3c0,3.3,2.1,5.1,8.1,6.7c1.5,0.4,3,0.8,3.3,1c0.4,0.1,0,1-1.2,2.8c-2.8,4.1-3.4,4.5-6.6,4.5c-2.4,0-2.9-0.1-4-1.4c-0.7-0.8-2.2-3.6-3.4-6.4c-2.7-6.9-2.6-6.8-11.1-6.8c-8.3,0-8.3,0-10.8,6.2c-2.6,6.6-2.9,7-4.7,7.8c-2,1-5.3,0.7-6.7-0.5c-1.8-1.6-4.6-6.2-4-6.4c0.3-0.1,1.8-0.6,3.3-1c6-1.7,8.1-3.4,8.1-6.7c0-1-0.5-1.9-1.6-3c-1.8-1.8-3.3-2-6.4-0.7c-4.3,1.8-14.8,3.7-20.5,3.8h-2.9l-0.2-2.4c-0.6-5.6-1.8-40.1-1.5-45c0.3-5.9,1.2-10.2,3.6-16.1c1.7-4.4,1.4-4.2,8.7-5.8C108.3,44.9,126.5,43.8,142.1,45.2z M94.3,132.9c3.7,5.5,4.7,6.5,8.3,8.4c1.8,1,2.7,1.1,6.9,1.1c4.4,0,5.1-0.1,7.5-1.3c3.6-1.8,6-4.6,7.8-9.4l1.5-3.9h1.7c1.8,0,1.8,0,3,3.3c2.3,6.1,5.1,9.1,10.2,10.7c3.4,1.1,9.2,0.8,12.1-0.7c3.5-1.8,4.6-2.9,8.3-8.4l3.7-5.4h2.5c1.4,0,2.5,0.2,2.5,0.5c0,1-4.3,9.1-6.8,12.9c-6.4,9.6-16.3,17.4-25.3,20.1c-2.4,0.7-2.4,0.7-2.4-0.4c0-0.6,0.4-3.3,0.9-6.1c0.5-2.8,0.9-5.7,0.9-6.5c0-3.1-2-5.2-5.1-5.2c-1,0-1.9,0.5-3,1.6l-1.6,1.6l-1.6-1.6c-3.3-3.3-8.1-1.1-8.1,3.6c0,0.8,0.4,3.9,0.9,6.8c1.3,7.5,1.4,7-1.5,6.2c-3.5-1.1-9.3-4-12.9-6.7c-4.1-3-9.5-8.8-12.6-13.5c-3-4.5-6.9-12.2-6.5-12.8c0.2-0.3,1.3-0.5,2.5-0.5h2.3L94.3,132.9z M81.2,172.6c6.5,6.4,18.3,13.4,27.3,16.1c7.2,2.2,12,3,19.5,3s12.3-0.7,19.5-3c8.9-2.7,20.7-9.7,27.3-16.1c1.3-1.2,2.6-2.3,3-2.3c1.2,0,24.5,8.3,27.8,9.9c17.7,8.6,28.9,25.6,30.4,46.2l0.3,4.7H128H19.5l0.4-4.6c1.4-20.4,12.5-37.6,29.9-46.1c3.4-1.7,26.8-10,28.2-10.1C78.5,170.4,79.9,171.4,81.2,172.6z"/><path fill="#000000" d="M90.1,67.4c-3,1-6.3,4.2-6.3,6.2c0,4.2,4.8,6.7,8.1,4.1c1-0.7,1.8-1,3.3-0.9c3.7,0.1,10.8,3.7,17.2,8.6c4.1,3.2,5.2,3.6,7.2,3c3.5-1.2,4.5-5.2,2.1-7.9c-1.7-1.9-7.7-6.3-12.4-8.9C102.2,67.4,94.8,65.9,90.1,67.4z"/><path fill="#000000" d="M158.4,67c-5,0.8-12.1,4.3-18.9,9.2c-5,3.6-6.4,5.3-6.4,7.6c0,3.3,3.3,5.7,6.2,4.6c0.6-0.2,2.6-1.6,4.5-3c9.2-7.1,17.3-10.1,20.5-7.7c2.3,1.8,5.9,1.1,7.3-1.6C174.4,70.9,166.7,65.6,158.4,67z"/><path fill="#000000" d="M101.5,94c-1.8,0.8-2.5,1.7-2.9,3.6c-0.3,2.1,0.9,4.4,2.9,5.2c2.3,0.9,11.8,0.9,13.8-0.1c1.4-0.6,3-3,3-4.3c0-1.4-1.6-3.7-3-4.3C113.4,93.2,103.6,93.1,101.5,94z"/><path fill="#000000" d="M140.6,94.1c-1.3,0.7-2.9,3-2.9,4.3c0,1.4,1.6,3.7,3,4.3c2,1,11.5,1,13.8,0.1c1.6-0.7,3-2.7,3-4.4c0-1.7-1.4-3.7-3-4.4C152.2,93.1,142.6,93.2,140.6,94.1z"/></g></g></g>
</svg>

+ 1
- 0
frontend/images/filter.svg Bestand weergeven

@ -0,0 +1 @@
<svg class="svg-icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M859.02 234.524l0.808-0.756 0.749-0.813c27.047-29.356 33.876-70.34 17.823-106.957-15.942-36.366-50.416-58.957-89.968-58.957H163.604c-38.83 0-73.043 22.012-89.29 57.444-16.361 35.683-10.632 76.301 14.949 106.004l0.97 1.126 280.311 266.85 2.032 312.074c0.107 16.502 13.517 29.805 29.995 29.805l0.2-0.001c16.568-0.107 29.912-13.626 29.804-30.194l-2.198-337.564-296.478-282.241c-9.526-11.758-11.426-26.933-5.044-40.851 6.446-14.059 19.437-22.452 34.75-22.452h624.828c15.6 0 28.69 8.616 35.017 23.047 6.31 14.391 3.924 29.831-6.354 41.497l-304.13 284.832 1.302 458.63c0.047 16.54 13.469 29.916 29.998 29.915h0.087c16.568-0.047 29.962-13.517 29.915-30.085L573.04 502.36l285.98-267.836z" fill="" /><path d="M657.265 595.287c0 16.498 13.499 29.997 29.997 29.997h243.897c16.498 0 29.997-13.498 29.997-29.997 0-16.498-13.499-29.997-29.997-29.997H687.262c-16.498 0-29.997 13.499-29.997 29.997z m273.894 138.882H687.262c-16.498 0-29.997 13.499-29.997 29.997s13.499 29.997 29.997 29.997h243.897c16.498 0 29.997-13.499 29.997-29.997 0-16.498-13.499-29.997-29.997-29.997z m0 168.878H687.262c-16.498 0-29.997 13.499-29.997 29.997s13.499 29.997 29.997 29.997h243.897c16.498 0 29.997-13.499 29.997-29.997 0-16.498-13.499-29.997-29.997-29.997z" fill="black" /></svg>

+ 55
- 0
frontend/images/logo.svg Bestand weergeven

@ -0,0 +1,55 @@
<svg width="116.333px" height="116.333px" viewBox="0 0 116.333 116.333" xmlns="http://www.w3.org/2000/svg">
<g id="Group_3478" data-name="Group 3478" transform="translate(-440.187 -454.667)">
<g id="Group_3475" data-name="Group 3475">
<path id="Path_4119" data-name="Path 4119" d="M498.354,571a58.167,58.167,0,1,1,58.166-58.167A58.233,58.233,0,0,1,498.354,571Zm0-112.335a54.169,54.169,0,1,0,54.168,54.168A54.23,54.23,0,0,0,498.354,458.665Z"/>
</g>
<g id="Group_3476" data-name="Group 3476">
<path id="Path_4120" data-name="Path 4120" d="M498.354,563.135A50.3,50.3,0,0,1,448.2,516.512l-.136-1.878,1.867-.248a1.567,1.567,0,0,0,0-3.106l-1.866-.248.136-1.878a50.288,50.288,0,0,1,100.3-.029l.163,2.237-2.331-.1a1.57,1.57,0,0,0,0,3.14l2.329-.111-.164,2.249a50.3,50.3,0,0,1-50.151,46.594Zm-46.031-45.383a46.291,46.291,0,0,0,92.031.272,5.568,5.568,0,0,1,0-10.381,46.291,46.291,0,0,0-92.031.272,5.561,5.561,0,0,1,0,9.837Z"/>
</g>
<g id="Group_3477" data-name="Group 3477">
<path id="Path_4121" data-name="Path 4121" d="M545.873,520.424h-5.689v15.394h.647a48,48,0,0,0,5.042-14.4Z"/>
<rect id="Rectangle_17" data-name="Rectangle 17" width="5.689" height="15.394" transform="translate(529.81 520.424)"/>
<rect id="Rectangle_18" data-name="Rectangle 18" width="15.394" height="5.689" transform="translate(510.429 530.464)"/>
<rect id="Rectangle_19" data-name="Rectangle 19" width="15.394" height="5.689" transform="translate(510.429 520.089)"/>
<rect id="Rectangle_20" data-name="Rectangle 20" width="5.689" height="15.394" transform="translate(500.753 520.424)"/>
<rect id="Rectangle_21" data-name="Rectangle 21" width="5.689" height="15.394" transform="translate(490.378 520.424)"/>
<rect id="Rectangle_22" data-name="Rectangle 22" width="15.394" height="5.689" transform="translate(470.997 530.464)"/>
<rect id="Rectangle_23" data-name="Rectangle 23" width="15.394" height="5.689" transform="translate(470.997 520.089)"/>
<rect id="Rectangle_24" data-name="Rectangle 24" width="5.689" height="15.394" transform="translate(461.322 520.424)"/>
<path id="Path_4122" data-name="Path 4122" d="M455.876,535.818h.76V520.424h-5.689v1.567A48.025,48.025,0,0,0,455.876,535.818Z"/>
<path id="Path_4123" data-name="Path 4123" d="M530.144,546.336h2.985a48.586,48.586,0,0,0,4.693-5.689h-7.678Z"/>
<path id="Path_4124" data-name="Path 4124" d="M526.157,540.981h-5.689v14.8a48.238,48.238,0,0,0,5.689-3.453Z"/>
<rect id="Rectangle_25" data-name="Rectangle 25" width="5.689" height="15.394" transform="translate(510.094 540.981)"/>
<rect id="Rectangle_26" data-name="Rectangle 26" width="15.394" height="5.689" transform="translate(490.713 551.021)"/>
<rect id="Rectangle_27" data-name="Rectangle 27" width="15.394" height="5.689" transform="translate(490.713 540.647)"/>
<rect id="Rectangle_28" data-name="Rectangle 28" width="5.689" height="15.394" transform="translate(481.037 540.981)"/>
<path id="Path_4125" data-name="Path 4125" d="M470.663,540.981v11.426a48.176,48.176,0,0,0,5.689,3.433V540.981Z"/>
<path id="Path_4126" data-name="Path 4126" d="M466.676,540.647h-7.79a48.572,48.572,0,0,0,4.692,5.689h3.1Z"/>
<path id="Path_4127" data-name="Path 4127" d="M540.184,488.713v5.99h2.925A48.086,48.086,0,0,0,540.184,488.713Z"/>
<path id="Path_4128" data-name="Path 4128" d="M535.5,481.982q-1.148-1.38-2.39-2.673h-3.3V494.7h5.69Z"/>
<rect id="Rectangle_29" data-name="Rectangle 29" width="15.394" height="5.689" transform="translate(510.429 489.349)"/>
<rect id="Rectangle_30" data-name="Rectangle 30" width="15.394" height="5.689" transform="translate(510.429 478.974)"/>
<rect id="Rectangle_31" data-name="Rectangle 31" width="5.689" height="15.394" transform="translate(500.753 479.309)"/>
<rect id="Rectangle_32" data-name="Rectangle 32" width="5.689" height="15.394" transform="translate(490.378 479.309)"/>
<rect id="Rectangle_33" data-name="Rectangle 33" width="15.394" height="5.689" transform="translate(470.997 489.349)"/>
<rect id="Rectangle_34" data-name="Rectangle 34" width="15.394" height="5.689" transform="translate(470.997 478.974)"/>
<path id="Path_4129" data-name="Path 4129" d="M467.011,479.309H463.6q-1.184,1.229-2.276,2.541V494.7h5.689Z"/>
<path id="Path_4130" data-name="Path 4130" d="M453.6,494.7h3.038v-6.186A48.055,48.055,0,0,0,453.6,494.7Z"/>
<path id="Path_4131" data-name="Path 4131" d="M526.157,473.336a48.385,48.385,0,0,0-5.689-3.454v4.264h5.689Z"/>
<path id="Path_4132" data-name="Path 4132" d="M510.094,474.146h5.689v-6.362a47.928,47.928,0,0,0-5.689-1.812Z"/>
<rect id="Rectangle_35" data-name="Rectangle 35" width="15.394" height="5.689" transform="translate(490.713 468.791)"/>
<path id="Path_4133" data-name="Path 4133" d="M486.726,465.942a47.933,47.933,0,0,0-5.689,1.8v6.4h5.689Z"/>
<path id="Path_4134" data-name="Path 4134" d="M470.663,474.146h5.689v-4.32a48.188,48.188,0,0,0-5.689,3.434Z"/>
<path id="Path_4135" data-name="Path 4135" d="M544.331,509.906H530.144v5.689H544.11a3.567,3.567,0,0,1,.221-5.689Z"/>
<path id="Path_4136" data-name="Path 4136" d="M530.144,499.532v5.689h15.394v-2.679c-.22-1.017-.48-2.019-.763-3.01Z"/>
<rect id="Rectangle_36" data-name="Rectangle 36" width="5.689" height="15.394" transform="translate(520.468 499.866)"/>
<rect id="Rectangle_37" data-name="Rectangle 37" width="5.689" height="15.394" transform="translate(510.094 499.866)"/>
<rect id="Rectangle_38" data-name="Rectangle 38" width="15.394" height="5.689" transform="translate(490.713 509.906)"/>
<rect id="Rectangle_39" data-name="Rectangle 39" width="15.394" height="5.689" transform="translate(490.713 499.532)"/>
<rect id="Rectangle_40" data-name="Rectangle 40" width="5.689" height="15.394" transform="translate(481.037 499.866)"/>
<rect id="Rectangle_41" data-name="Rectangle 41" width="5.689" height="15.394" transform="translate(470.663 499.866)"/>
<path id="Path_4137" data-name="Path 4137" d="M451.973,515.595h14.7v-5.689h-14.94a3.544,3.544,0,0,1,.237,5.689Z"/>
<path id="Path_4138" data-name="Path 4138" d="M466.676,499.532H451.933c-.238.831-.457,1.67-.651,2.519v3.17h15.394Z"/>
</g>
</g>
</svg>

+ 1
- 0
frontend/images/setup.svg Bestand weergeven

@ -0,0 +1 @@
<svg class="svg-icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M509.946 338.983c-95.925 0-173.983 78.034-173.983 173.935 0 95.913 78.057 173.947 173.983 173.947 27.333 0 53.132-6.515 76.17-17.797l-0.024-0.057c6.245-3.17 10.527-9.63 10.527-17.104 0-10.598-8.59-19.237-19.214-19.237-2.493 0-4.867 0.49-7.051 1.357l-0.102-0.225c-18.196 9.088-38.614 14.352-60.306 14.352-74.588 0-135.249-60.663-135.249-135.238 0-74.564 60.66-135.201 135.249-135.201s135.296 60.637 135.296 135.2c0 13.314-2.03 26.166-5.617 38.32l0.345 0.135c-0.365 1.48-0.58 3.02-0.58 4.61 0 10.598 8.59 19.19 19.212 19.19 7.32 0 13.676-4.081 16.919-10.09l0.334 0.13c0.33-1.05 0.653-2.105 0.964-3.163 0.153-0.455 0.28-0.92 0.398-1.39a173.233 173.233 0 0 0 6.711-47.74c0-95.9-78.032-173.934-173.982-173.934z m411.693 77.904h-66.23c-3.423-12.534-7.65-25.138-12.889-38.31l-3.87-9.3c-5.098-11.824-10.952-23.46-17.327-34.673l46.808-46.806c4.814-4.817 7.48-11.213 7.48-18.01 0-6.798-2.665-13.195-7.48-18.01l-96.987-96.965c-9.656-9.654-26.438-9.654-36.044 0l-46.806 46.806c-11.375-6.467-23.369-12.438-36.775-18.246l-8.686-3.54a366.101 366.101 0 0 0-36.82-12.298v-66.182c0-14.043-11.425-25.468-25.493-25.468H443.384c-14.069 0-25.492 11.448-25.492 25.468v66.186c-12.51 3.445-24.856 7.553-36.775 12.298l-10.764 4.46a354.674 354.674 0 0 0-34.697 17.325l-46.828-46.806c-9.63-9.63-26.39-9.63-36.043 0L155.82 251.78a25.282 25.282 0 0 0-7.482 18.01c0 6.798 2.643 13.17 7.482 18.01l46.806 46.807c-6.467 11.376-12.462 23.462-18.41 37.199l-3.423 8.286c-4.744 11.944-8.827 24.263-12.25 36.797h-66.232c-14.044 0-25.47 11.449-25.47 25.469v137.137c0 14.02 11.426 25.444 25.47 25.444h66.232c3.447 12.58 7.694 25.209 12.958 38.522l3.8 9.11a356.298 356.298 0 0 0 17.325 34.627l-46.782 46.817c-9.937 9.914-9.937 26.107 0 36.02L252.807 867c9.63 9.582 26.39 9.63 36.02 0l46.828-46.83a355.428 355.428 0 0 0 34.557 17.325l7.93 3.305 3.02 1.226a349.604 349.604 0 0 0 36.776 12.227v66.184c0 14.069 11.423 25.493 25.492 25.493h137.136c14.07 0 25.493-11.472 25.493-25.493v-66.184c12.558-3.446 25.137-7.648 38.238-12.84l9.348-3.87a354.975 354.975 0 0 0 34.697-17.374l46.83 46.83c9.607 9.582 26.388 9.63 36.018 0l97.011-96.963c9.915-9.914 9.915-26.107 0-36.02l-46.83-46.818c6.42-11.26 12.371-23.202 18.082-36.42l1.51-3.589 2.22-5.476a360.913 360.913 0 0 0 12.273-36.775h66.233c14.044 0 25.468-11.401 25.468-25.444V442.356c-0.048-14.02-11.472-25.47-25.518-25.47zM906.605 564.41h-83.061l-4.626 19.685c-3.471 14.635-8.048 29.057-13.973 43.997l-1.415 3.54-2.031 4.793c-5.949 13.738-12.911 27.096-20.725 39.701l-10.62 17.207 58.702 58.714-75.698 75.673-58.678-58.679-17.232 10.575c-12.936 7.978-26.154 14.823-41.59 21.574l-7.741 3.115a317.74 317.74 0 0 1-42.793 13.502l-19.664 4.672v82.896H458.42V822.48l-19.662-4.672c-14.918-3.588-29.315-8.167-45.319-14.494l-7.13-2.973c-13.595-5.901-26.907-12.887-39.676-20.724l-17.208-10.575-58.678 58.679-75.697-75.673 58.678-58.714-10.598-17.207c-7.907-12.77-14.87-26.223-21.315-41.07l-3.35-8.285a309.225 309.225 0 0 1-13.432-42.723l-4.696-19.638h-82.966V457.39h82.966l4.696-19.637c3.517-14.823 8.167-29.433 14.186-44.588l3.234-7.765c5.878-13.596 12.841-26.955 20.7-39.725l10.621-17.207-58.678-58.656 75.697-75.672 58.655 58.654 17.231-10.598c12.747-7.86 26.154-14.8 40.999-21.22l8.452-3.47c13.594-5.404 27.945-9.936 42.627-13.453l19.685-4.626v-82.991h107.066v82.991l19.683 4.626c14.731 3.494 28.94 8.002 44.613 14.186l7.743 3.258c13.76 5.947 27.143 12.91 39.747 20.7l17.207 10.599 58.655-58.655 75.72 75.672-58.678 58.656 10.573 17.183c7.883 12.817 14.87 26.294 21.363 41.26l3.373 8.167a320.605 320.605 0 0 1 13.456 42.628l4.626 19.684h83.014V564.41z" fill="black" /></svg>

+ 351
- 0
frontend/images/topisto.svg Bestand weergeven

@ -0,0 +1,351 @@
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="920.000000pt" height="920.000000pt" viewBox="0 0 920.000000 920.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,920.000000) scale(0.100000,-0.100000)"
stroke="none">
<path d="M319 9096 c-90 -32 -173 -111 -206 -194 -17 -45 -18 -209 -21 -4267
-2 -3005 0 -4238 8 -4284 20 -118 78 -198 175 -243 l50 -23 4265 -3 4265 -2
61 20 c82 28 136 76 176 158 l33 67 3 4255 c2 4621 6 4310 -51 4387 -41 56
-116 110 -176 127 -52 15 -439 16 -4302 16 -3444 -1 -4251 -3 -4280 -14z
m8488 -147 c66 -13 124 -55 160 -116 l28 -48 0 -4205 c0 -3952 -1 -4207 -17
-4236 -23 -41 -71 -82 -133 -110 l-50 -24 -4146 0 c-2773 0 -4164 3 -4200 10
-75 14 -144 63 -177 125 l-27 50 -3 4160 c-1 2929 1 4175 8 4212 6 28 21 67
33 85 30 43 95 88 149 102 60 15 8299 10 8375 -5z"/>
<path d="M6205 8623 c-324 -38 -610 -144 -869 -321 -65 -45 -135 -85 -154 -88
-56 -11 -174 25 -217 66 -34 31 -29 62 10 73 63 19 80 32 83 64 3 27 -1 33
-20 37 -166 34 -352 -16 -448 -120 -66 -72 -80 -110 -80 -221 0 -127 15 -179
84 -292 69 -115 79 -150 66 -222 -13 -68 -81 -210 -151 -314 -30 -45 -63 -98
-74 -120 -32 -64 -184 -208 -256 -244 -34 -17 -67 -31 -73 -31 -6 0 -31 28
-55 61 -24 33 -54 65 -67 70 -13 4 -24 14 -24 20 0 6 -19 41 -43 78 -35 52
-135 271 -187 407 -13 34 -67 91 -113 117 -61 36 -88 69 -150 182 -31 56 -70
112 -89 127 -40 33 -106 45 -166 29 l-42 -12 0 -48 c0 -32 6 -56 19 -72 17
-22 61 -103 61 -112 0 -3 -21 -8 -47 -12 -102 -15 -203 -48 -304 -98 l-105
-53 12 36 c7 20 18 73 24 119 9 68 9 86 -2 92 -42 27 -106 -11 -163 -96 -57
-85 -75 -148 -86 -310 -19 -267 -62 -437 -147 -582 -103 -176 -122 -221 -122
-287 0 -69 27 -138 59 -156 12 -6 44 -14 71 -17 l50 -6 0 -54 c0 -63 -10 -86
-53 -122 -17 -14 -62 -53 -100 -87 -38 -34 -94 -76 -124 -94 l-54 -33 -44 21
c-34 16 -63 47 -134 143 -50 66 -91 125 -91 130 0 5 -23 34 -51 65 -132 145
-194 290 -239 560 -29 172 -30 408 -1 539 25 117 30 129 88 201 78 96 97 145
89 232 -4 53 -15 92 -41 147 -60 125 -120 148 -331 125 -129 -15 -161 -29
-243 -114 -37 -38 -45 -52 -49 -94 l-4 -49 47 -19 48 -18 -7 -88 c-5 -71 -18
-124 -65 -266 -33 -97 -71 -222 -85 -277 -35 -139 -94 -456 -100 -540 -5 -60
-13 -391 -30 -1270 -3 -163 12 -477 29 -580 3 -16 16 -106 30 -200 32 -211 56
-315 96 -413 91 -225 92 -229 96 -442 2 -107 6 -205 8 -217 9 -38 33 -27 45
20 6 23 25 84 42 135 l31 92 43 0 c24 0 46 -6 51 -12 25 -40 65 -182 70 -249
9 -121 -18 -224 -125 -469 -78 -178 -90 -217 -113 -338 -25 -142 -23 -196 9
-200 14 -2 24 3 28 15 50 142 66 172 94 181 33 12 32 13 49 -82 19 -103 13
-175 -24 -317 -42 -165 -51 -246 -35 -322 6 -31 14 -57 17 -57 3 0 26 18 50
41 37 34 49 40 81 37 l37 -3 32 -100 c37 -114 83 -308 83 -352 l0 -30 -117 35
c-106 31 -130 35 -233 34 -135 0 -204 -18 -308 -80 -37 -21 -89 -50 -117 -63
-47 -23 -50 -26 -53 -66 -3 -42 -2 -43 27 -43 16 0 67 16 113 36 131 56 174
65 238 48 71 -18 124 -18 140 1 15 19 17 17 -45 40 -61 22 -74 32 -50 41 52
20 392 -88 403 -128 2 -9 16 -18 31 -20 25 -3 26 -5 26 -73 l0 -70 -215 -6
c-188 -4 -222 -8 -274 -27 -52 -19 -79 -22 -228 -22 l-168 0 0 -35 c0 -31 3
-35 38 -44 20 -5 77 -9 127 -10 121 -1 141 -6 154 -42 6 -16 16 -43 22 -59 24
-64 138 -130 226 -130 65 -1 171 -32 267 -80 98 -49 104 -51 211 -57 181 -10
341 32 409 107 29 32 76 131 76 160 0 22 55 8 108 -28 89 -60 146 -96 154 -97
3 0 10 -3 14 -8 4 -4 16 -7 26 -7 10 0 18 -4 18 -9 0 -5 38 -15 84 -21 86 -13
176 -11 461 11 177 13 555 23 890 24 l260 0 -4 -161 c-3 -127 0 -172 13 -217
22 -75 69 -135 136 -170 52 -27 60 -29 145 -24 50 3 110 12 135 21 33 13 85
18 198 19 113 1 155 5 161 15 14 22 140 49 207 44 46 -3 76 1 117 16 34 13 94
24 156 28 56 4 101 11 101 16 0 5 13 7 30 3 37 -8 86 25 122 82 19 32 23 51
23 123 0 74 -3 88 -22 107 -44 44 -87 263 -56 294 7 7 36 -18 98 -88 49 -54
95 -102 102 -106 7 -4 13 -14 13 -21 0 -22 102 -85 157 -96 35 -8 69 -8 110
-1 32 5 87 13 123 16 100 10 138 33 202 123 91 127 124 177 137 210 9 21 20
32 33 32 11 0 22 8 25 19 3 11 13 21 22 24 9 2 26 26 36 53 10 27 25 54 32 59
18 14 22 136 5 191 -18 63 -63 117 -149 180 -43 31 -112 86 -154 120 -93 77
-144 103 -278 143 -57 17 -105 31 -107 31 -2 0 -4 10 -4 22 0 29 -101 162
-152 198 -34 25 -51 30 -99 30 -58 0 -221 -44 -227 -61 -2 -5 -11 -9 -19 -9
-14 0 -15 11 -9 81 8 92 22 134 59 167 20 19 31 22 60 17 38 -7 67 -32 71 -61
2 -12 57 -49 162 -107 87 -49 191 -111 229 -140 349 -256 830 -573 1036 -683
256 -137 585 -292 816 -385 124 -50 251 -48 288 4 9 13 15 43 15 75 0 68 -26
108 -76 118 -25 4 -38 14 -45 30 -5 14 -26 48 -48 77 -108 144 -359 617 -451
848 -93 233 -191 618 -234 919 -92 637 5 1104 326 1588 51 76 100 153 110 170
21 39 57 62 105 69 31 4 44 0 75 -25 24 -18 56 -32 85 -37 67 -10 77 5 68 115
-14 189 -58 296 -229 550 -189 280 -235 341 -550 730 -98 120 -118 169 -128
310 -8 111 -14 155 -59 400 -17 96 -20 142 -16 280 5 184 28 296 86 424 46
102 162 258 276 372 138 137 164 147 372 149 144 0 154 2 175 23 19 18 23 35
26 95 2 46 -2 81 -10 97 -16 29 -122 102 -154 106 -25 2 -102 51 -149 94 -16
15 -40 30 -53 33 -20 5 -22 2 -16 -16 21 -68 65 -111 166 -163 57 -29 118 -81
118 -100 0 -11 -16 -14 -67 -14 -171 -1 -381 -90 -414 -177 -5 -13 -17 -23
-28 -23 -40 0 -236 -261 -318 -425 -90 -177 -143 -373 -143 -526 0 -97 42
-369 71 -454 11 -33 23 -91 26 -130 l6 -70 -139 135 c-214 208 -508 473 -629
566 -68 52 -315 219 -415 279 -52 32 -189 109 -305 173 -115 63 -250 137 -298
166 -85 49 -88 52 -83 80 10 47 32 63 181 136 384 186 664 276 1025 326 94 14
193 18 400 19 298 0 371 -9 551 -70 89 -31 120 -31 170 -3 28 15 39 28 39 45
0 20 -5 23 -39 23 -22 0 -113 18 -203 40 -243 60 -329 72 -523 72 -195 0 -498
-24 -665 -52 -208 -34 -484 -126 -679 -224 -47 -24 -176 -95 -286 -158 -175
-100 -202 -119 -219 -152 -18 -37 -18 -37 3 -60 12 -13 68 -43 124 -66 169
-72 291 -136 527 -278 399 -240 670 -432 914 -645 43 -38 89 -73 102 -79 13
-6 24 -19 24 -28 0 -20 84 -102 153 -149 26 -18 71 -61 100 -95 293 -351 324
-386 348 -386 10 0 19 -11 22 -27 6 -32 72 -113 92 -113 7 0 18 -12 24 -27 16
-37 77 -103 96 -103 8 0 15 -8 15 -17 0 -27 63 -113 83 -113 10 0 17 -8 17
-19 0 -10 32 -63 72 -117 39 -54 101 -144 136 -199 36 -55 75 -111 88 -125 15
-16 30 -56 43 -115 11 -49 25 -105 30 -122 l10 -33 -98 0 c-90 0 -100 -2 -144
-29 -89 -57 -164 -153 -286 -368 -155 -273 -253 -571 -276 -837 -8 -95 10
-483 31 -651 18 -141 112 -571 154 -700 16 -49 38 -126 50 -169 11 -44 28 -85
37 -91 9 -7 14 -19 10 -28 -4 -11 1 -20 12 -26 12 -7 21 -27 25 -60 4 -29 12
-51 21 -55 8 -3 15 -17 15 -30 0 -15 8 -30 20 -36 11 -6 20 -21 20 -34 0 -13
7 -26 15 -30 8 -3 18 -24 21 -46 4 -25 14 -45 25 -51 12 -6 19 -21 19 -38 0
-16 7 -31 15 -35 8 -3 15 -17 15 -31 0 -14 7 -28 15 -31 8 -4 15 -17 15 -30 0
-12 9 -29 20 -37 11 -8 23 -28 26 -45 4 -18 14 -34 25 -37 11 -4 21 -20 25
-41 3 -19 15 -39 25 -45 11 -5 19 -17 19 -26 0 -10 24 -56 53 -103 30 -47 68
-109 85 -138 l32 -52 -45 0 c-59 0 -109 21 -470 200 -481 239 -684 364 -1515
935 -177 121 -331 225 -343 232 -32 18 -47 43 -47 78 0 34 36 130 71 189 l22
37 41 -39 c23 -21 68 -61 101 -88 33 -27 88 -74 122 -105 34 -31 92 -78 130
-105 279 -195 424 -304 467 -353 11 -11 30 -21 43 -21 12 0 23 -6 23 -12 0
-21 206 -168 235 -168 8 0 15 -8 15 -18 0 -13 44 -39 163 -99 225 -112 318
-138 331 -91 4 17 -3 32 -28 58 -31 32 -118 146 -481 625 -148 195 -299 416
-435 635 -57 91 -153 242 -215 335 -111 168 -153 242 -250 443 -53 112 -89
152 -136 152 -24 0 -29 -4 -25 -17 3 -10 8 -40 12 -68 9 -61 45 -142 73 -161
13 -10 21 -26 21 -44 0 -18 9 -38 24 -52 13 -13 29 -41 36 -63 7 -22 21 -46
32 -53 10 -7 18 -22 18 -33 0 -11 7 -34 17 -52 29 -56 196 -302 214 -315 10
-6 20 -26 24 -42 4 -17 15 -35 25 -40 10 -5 21 -23 25 -40 4 -17 15 -35 25
-40 11 -6 22 -26 26 -45 4 -21 13 -37 25 -40 13 -4 19 -16 19 -34 0 -27 113
-205 169 -266 15 -16 65 -86 111 -155 46 -69 107 -153 136 -188 30 -35 68 -88
86 -118 20 -33 42 -57 56 -60 12 -4 22 -13 22 -22 0 -9 10 -26 22 -39 16 -18
18 -23 6 -23 -20 0 -289 179 -403 269 -49 39 -178 137 -285 218 -174 132 -411
325 -527 430 -67 61 -77 90 -79 233 -1 83 -9 163 -24 240 -21 107 -22 128 -14
305 5 105 9 240 9 300 l0 110 180 6 c99 3 196 10 215 14 70 15 135 57 205 132
39 42 114 119 167 172 103 102 138 158 159 259 9 44 6 84 -16 250 -35 252 -52
299 -170 477 -51 77 -107 169 -125 205 -18 36 -45 83 -61 106 -15 22 -31 54
-35 70 -4 18 -45 66 -108 128 -152 148 -223 197 -444 311 -101 52 -158 101
-262 230 -79 97 -185 181 -306 243 -202 105 -233 123 -319 192 -109 87 -132
100 -185 100 -39 0 -40 -1 -40 -32 0 -18 11 -51 25 -73 13 -22 25 -45 25 -50
0 -11 -72 -29 -160 -40 -44 -6 -164 -35 -365 -90 -72 -19 -134 -28 -221 -32
l-121 -6 -7 43 c-4 24 -3 46 1 50 4 4 53 41 108 83 136 103 226 184 330 297
148 161 275 375 306 512 l12 58 38 -6 c21 -4 50 -3 65 0 48 12 252 225 301
313 7 12 15 41 18 65 3 24 8 55 10 71 4 24 2 27 -24 27 -25 0 -31 -6 -42 -37
-24 -76 -62 -138 -128 -207 -38 -40 -73 -82 -80 -94 -6 -12 -18 -22 -25 -22
-7 0 -38 -18 -69 -40 -30 -22 -57 -40 -60 -40 -2 0 -7 20 -9 45 -4 29 -26 82
-66 154 -70 126 -82 163 -82 246 1 133 36 192 145 241 64 28 83 31 65 10 -9
-12 -8 -22 5 -50 21 -43 34 -54 120 -101 177 -97 171 -94 212 -83 52 14 91 35
208 113 243 160 449 245 780 320 113 26 206 62 220 85 6 10 -90 12 -160 3z
m-4607 -589 c43 -30 79 -90 74 -123 -2 -17 -8 -31 -12 -31 -4 0 -11 -12 -14
-26 -4 -14 -21 -56 -37 -94 -26 -57 -36 -70 -60 -75 -15 -4 -36 -2 -47 4 -10
5 -47 17 -83 25 -59 14 -65 14 -77 -1 -21 -29 38 -57 126 -62 l74 -3 -8 -52
c-4 -28 -8 -72 -8 -98 -1 -25 -4 -50 -8 -54 -12 -12 -10 -444 2 -444 6 0 10
-31 10 -74 0 -157 50 -353 120 -469 22 -36 40 -71 40 -76 0 -6 4 -11 10 -11 5
0 22 -25 37 -56 15 -30 50 -79 77 -108 52 -54 215 -279 223 -306 11 -40 -16
-71 -91 -105 -41 -18 -82 -32 -93 -29 -24 6 -144 -53 -208 -101 -48 -37 -95
-49 -124 -31 -5 4 -20 39 -33 78 -16 51 -29 74 -46 81 -16 7 -26 7 -34 -1 -15
-15 -47 -275 -35 -283 13 -9 -30 -201 -48 -214 -7 -6 -23 -42 -35 -80 -28 -88
-38 -300 -20 -413 16 -101 38 -172 52 -169 19 3 52 -121 52 -198 1 -78 -25
-162 -75 -247 -16 -26 -28 -54 -26 -60 2 -10 -55 -46 -75 -48 -13 0 -84 152
-101 215 -8 33 -18 87 -22 120 -3 33 -15 119 -25 190 -56 377 -75 696 -66
1080 6 250 28 659 41 765 3 25 10 112 14 195 6 92 13 151 20 153 6 2 11 26 11
52 0 45 54 333 67 352 2 5 16 57 29 116 28 127 92 342 107 360 5 7 12 55 15
106 l5 94 -32 17 c-26 13 -32 21 -29 43 3 30 65 70 148 96 64 21 189 20 218 0z
m1770 -217 c21 -22 52 -86 52 -107 0 -5 -13 -10 -29 -10 -31 0 -42 19 -57 103
-7 43 3 47 34 14z m14 -183 c20 -4 45 -14 55 -23 10 -9 49 -29 86 -45 65 -27
68 -31 62 -55 -3 -14 -9 -53 -12 -87 -6 -69 4 -94 61 -162 29 -36 47 -72 82
-172 3 -8 7 -51 9 -95 8 -141 27 -300 38 -313 15 -19 23 -192 9 -201 -6 -4
-21 -63 -33 -131 -12 -69 -28 -132 -35 -140 -7 -9 -23 -37 -34 -63 -14 -32
-27 -47 -40 -47 -10 0 -22 -5 -26 -11 -3 -6 -47 -38 -97 -70 -50 -33 -108 -77
-129 -97 -21 -20 -43 -37 -50 -37 -7 0 -47 -17 -88 -37 -188 -90 -363 -82
-466 23 -21 21 -46 39 -55 39 -10 0 -19 11 -22 28 -3 15 -22 72 -42 127 -55
151 -77 391 -54 591 7 60 15 172 18 249 4 88 9 132 14 118 4 -12 24 -36 44
-54 36 -31 38 -32 114 -26 96 6 166 35 175 71 9 36 -6 50 -94 87 -64 27 -90
32 -155 32 -65 1 -76 3 -72 16 17 55 24 133 18 214 -5 87 -4 97 22 155 15 34
31 62 35 62 7 0 30 -89 30 -116 0 -8 -11 -19 -25 -24 -14 -5 -25 -14 -25 -19
0 -4 -3 -23 -6 -40 -7 -31 -5 -30 52 29 96 101 237 171 414 209 100 21 161 25
222 15z m588 -714 c0 -13 9 -22 25 -26 14 -3 25 -13 25 -23 0 -9 3 -26 6 -38
5 -19 1 -23 -30 -29 -30 -5 -44 -1 -77 21 -52 34 -69 76 -69 167 l1 73 59 -63
c33 -34 60 -71 60 -82z m-1526 -276 c13 -5 16 -24 16 -100 0 -101 -5 -109 -48
-78 -19 13 -22 24 -22 77 0 40 6 70 16 85 17 25 16 24 38 16z m2556 -40 c63
-3 120 -10 125 -14 6 -4 41 -17 78 -28 79 -24 337 -168 337 -188 0 -8 10 -18
23 -23 25 -10 49 -41 81 -105 43 -86 191 -197 322 -244 27 -9 63 -27 78 -40
16 -12 37 -22 47 -22 10 0 26 -11 35 -25 9 -13 33 -32 54 -41 21 -10 41 -25
43 -36 3 -10 14 -18 25 -18 21 0 60 -44 115 -126 16 -23 39 -52 52 -64 14 -13
25 -31 25 -41 0 -9 7 -19 15 -23 8 -3 15 -16 15 -29 0 -14 7 -30 15 -37 20
-17 19 -40 -2 -40 -10 0 -45 7 -78 14 -218 50 -489 11 -787 -114 -76 -31 -78
-33 -78 -67 l0 -36 69 7 c38 4 118 23 176 41 217 70 384 88 557 62 l96 -15 54
-53 c30 -30 70 -63 91 -74 25 -13 37 -26 37 -41 0 -13 8 -24 20 -27 12 -3 20
-14 20 -25 0 -12 4 -23 9 -27 17 -10 68 -157 97 -275 36 -151 37 -238 5 -305
-28 -55 -305 -346 -355 -372 -68 -35 -321 -56 -406 -34 -19 6 -54 15 -77 21
-31 8 -43 16 -43 29 0 13 -16 25 -49 40 -104 44 -119 21 -56 -87 25 -43 51
-106 60 -142 19 -83 19 -220 0 -346 -19 -123 -19 -215 -1 -279 7 -28 21 -77
30 -110 9 -33 19 -103 23 -155 11 -189 -33 -361 -170 -660 -110 -241 -141
-436 -103 -654 21 -118 20 -198 -4 -306 -38 -171 -34 -207 38 -360 27 -58 57
-136 66 -175 31 -129 48 -174 67 -180 19 -6 27 -25 10 -25 -6 0 -6 -13 0 -32
5 -18 7 -54 3 -80 -9 -74 -60 -101 -214 -114 -47 -3 -111 -16 -145 -29 -97
-37 -310 -78 -395 -77 -113 2 -150 10 -150 33 0 31 42 66 88 74 23 4 44 11 48
16 3 5 24 9 48 9 38 0 44 3 58 34 16 33 16 34 -15 64 -45 43 -74 52 -131 40
-50 -10 -116 -4 -116 12 0 10 -74 52 -100 57 -8 2 -48 6 -88 9 -86 7 -108 -3
-148 -71 -23 -40 -25 -49 -14 -74 11 -27 15 -28 94 -34 45 -3 112 -11 149 -18
73 -14 71 -11 80 -95 l5 -40 -47 -13 c-25 -7 -61 -19 -79 -27 -38 -16 -111
-18 -163 -4 -70 20 -125 110 -136 223 -7 80 3 157 21 157 9 0 16 19 20 53 8
60 30 86 157 185 90 70 140 127 175 197 27 55 29 70 31 180 1 66 12 188 25
270 29 191 32 413 5 462 -9 18 -29 69 -43 115 -14 46 -66 169 -115 273 -48
105 -96 219 -105 255 -23 88 -22 289 1 385 38 160 44 294 30 678 -7 183 -6
212 9 252 22 58 74 102 181 153 75 37 85 45 85 68 l0 27 -69 -7 c-144 -13
-241 -70 -287 -171 -22 -47 -24 -62 -24 -230 1 -99 5 -225 10 -280 16 -175
-20 -450 -70 -531 -19 -29 -23 -31 -54 -24 -18 4 -38 10 -43 13 -6 4 -13 50
-16 104 -7 127 -26 183 -91 282 -29 45 -59 102 -65 129 -21 80 -46 137 -61
137 -8 0 -21 -18 -29 -40 -20 -61 -2 -150 48 -236 64 -111 81 -167 81 -267 0
-48 -4 -93 -9 -100 -5 -9 -25 -12 -61 -10 l-52 3 -18 70 c-27 106 -95 269
-114 273 -9 2 -16 13 -16 28 0 17 -6 24 -19 24 -18 0 -38 53 -71 190 -6 25
-18 63 -28 85 l-17 39 -6 -29 c-23 -106 -4 -202 71 -365 57 -124 82 -196 95
-277 7 -43 6 -43 -23 -43 -17 0 -41 4 -54 9 -36 13 -39 24 -155 436 -15 56
-18 212 -4 265 30 116 42 155 51 164 5 5 10 20 10 33 0 12 11 51 24 85 14 35
34 95 46 133 12 39 34 97 50 130 15 33 31 76 35 95 9 45 53 115 102 162 41 39
210 146 314 198 35 18 111 52 169 75 58 24 182 77 275 118 94 41 224 98 290
127 203 89 235 107 235 134 0 21 -6 24 -61 30 -88 10 -104 19 -191 102 -90 86
-196 158 -316 215 -90 42 -118 44 -108 6 3 -12 6 -30 6 -40 0 -10 11 -22 25
-27 14 -5 25 -16 25 -24 0 -19 85 -77 212 -145 54 -29 101 -57 104 -63 3 -5 3
-29 0 -52 -7 -43 -7 -44 -97 -85 -82 -39 -139 -63 -364 -156 -350 -144 -549
-278 -660 -445 -55 -84 -89 -164 -136 -325 -20 -72 -56 -180 -79 -240 -81
-213 -92 -260 -86 -360 3 -53 15 -124 30 -172 14 -46 39 -144 56 -220 17 -75
42 -162 56 -193 22 -50 32 -60 72 -78 67 -29 129 -34 240 -18 53 8 156 18 227
21 l131 7 13 -76 c20 -121 58 -239 122 -382 53 -119 149 -357 149 -370 0 -10
-95 8 -200 37 -272 74 -324 84 -520 94 -144 8 -236 -2 -425 -46 -200 -46 -213
-49 -248 -49 -17 0 -85 18 -150 40 -114 39 -123 40 -247 40 -72 0 -130 -2
-130 -4 0 -24 24 -39 98 -62 48 -14 138 -46 201 -71 161 -63 208 -65 381 -20
196 52 277 61 469 54 173 -6 355 -32 476 -67 126 -37 195 -50 259 -50 74 0 72
3 82 -120 6 -75 -27 -341 -45 -364 -17 -22 -41 -147 -40 -208 2 -153 -90 -306
-226 -375 -42 -22 -20 -20 -650 -53 -102 -6 -181 -14 -183 -20 -2 -6 -73 -10
-185 -9 -111 0 -174 4 -162 9 32 14 -81 11 -250 -5 -218 -21 -250 -20 -347 16
-46 17 -92 38 -103 48 -11 10 -36 26 -55 35 -32 15 -140 108 -140 121 0 3 -22
44 -49 93 -69 121 -92 207 -98 367 l-5 130 55 163 c79 233 137 320 247 370 46
22 76 27 195 33 103 5 163 14 225 32 254 75 515 133 707 158 141 18 287 8 418
-30 109 -31 293 -66 302 -57 3 2 -6 19 -18 36 -65 87 -392 180 -637 180 -85 0
-118 12 -136 50 -65 132 -94 192 -140 300 -30 69 -53 126 -51 128 2 2 42 12
89 22 105 23 142 42 150 76 4 14 4 29 1 32 -3 3 -72 1 -153 -6 -178 -14 -231
-6 -279 40 -39 38 -48 60 -34 86 11 21 20 24 240 77 80 19 155 42 167 50 25
16 35 66 18 89 -10 15 -15 14 -56 -4 -72 -31 -256 -72 -334 -73 -61 -1 -80 3
-137 31 -37 18 -67 37 -67 42 0 5 44 23 98 40 123 41 281 115 358 168 108 74
221 210 246 295 17 60 13 272 -6 348 -17 63 -50 129 -66 129 -17 0 -28 -75
-34 -225 -8 -213 -40 -308 -135 -401 -86 -84 -199 -143 -358 -185 -60 -16
-121 -22 -261 -26 l-183 -5 -15 -30 -15 -29 53 -23 c29 -13 64 -26 78 -29 44
-11 117 -64 152 -111 18 -25 40 -45 49 -46 9 0 23 -17 31 -39 26 -65 148 -240
184 -262 19 -11 34 -27 34 -35 0 -8 7 -14 15 -14 8 0 15 -6 15 -14 0 -8 7 -16
16 -18 8 -2 27 -30 41 -63 125 -297 142 -360 107 -403 -19 -22 -163 -67 -175
-54 -3 4 -14 45 -23 92 -10 47 -44 158 -76 247 -78 214 -144 325 -270 453
-132 134 -218 195 -308 222 -65 20 -72 25 -67 43 8 23 27 105 54 225 27 117
45 349 38 478 -4 86 -12 128 -41 216 -20 60 -46 124 -57 143 -22 35 -73 68
-89 58 -19 -12 -10 -112 15 -182 47 -130 57 -197 57 -383 1 -157 -2 -187 -26
-290 -35 -147 -92 -280 -170 -400 -96 -144 -102 -163 -68 -192 39 -34 50 -30
88 34 44 71 51 66 60 -43 7 -89 48 -245 112 -429 46 -133 47 -137 47 -260 -1
-153 -14 -189 -90 -236 -87 -55 -113 -82 -135 -142 -12 -31 -25 -61 -30 -67
-13 -16 -102 -312 -122 -410 -27 -124 -17 -191 58 -424 13 -40 36 -90 51 -110
22 -28 28 -46 27 -85 0 -31 -6 -53 -16 -60 -8 -6 -23 -27 -33 -46 -20 -40
-106 -127 -138 -139 -12 -5 -64 -14 -115 -21 -123 -16 -213 3 -257 55 -16 19
-105 67 -105 57 0 -6 -20 -4 -47 3 -27 7 -68 18 -93 24 -25 7 -65 16 -89 21
-45 10 -135 69 -145 96 -21 55 13 75 139 82 76 3 108 0 196 -23 90 -23 112
-25 146 -16 118 32 143 141 77 338 -20 60 -43 119 -52 133 -9 14 -19 43 -23
65 -5 22 -19 74 -32 115 -13 41 -32 115 -41 164 -9 49 -25 105 -35 125 -25 49
-67 247 -75 351 -4 46 -11 87 -15 90 -5 3 -11 55 -15 115 -4 61 -12 112 -17
113 -13 5 -12 459 1 467 6 3 10 18 10 33 0 48 39 215 51 223 9 5 10 35 6 106
-6 101 -24 168 -71 260 -24 49 -26 62 -26 185 0 174 23 356 62 493 27 96 40
197 26 210 -2 3 -29 -2 -59 -9 -30 -8 -57 -12 -61 -8 -4 4 -16 52 -27 107 -62
314 -23 495 152 712 38 47 61 62 232 149 l190 97 85 -6 c47 -3 121 -15 165
-27 121 -33 247 -41 410 -25 77 7 266 18 420 25 317 12 382 17 390 31 4 5 26
9 51 9 59 0 134 44 199 117 133 148 127 143 189 143 31 0 69 6 84 14 15 8 73
64 129 124 56 60 140 137 186 171 100 73 155 142 132 161 -13 10 -28 8 -83
-12 -96 -36 -143 -68 -203 -140 -49 -60 -125 -137 -198 -203 l-34 -30 6 65
c29 282 57 321 235 325 99 2 236 30 226 46 -3 5 9 9 27 9 17 0 64 12 103 26
39 14 100 32 136 41 66 16 213 32 240 27 8 -2 67 -6 130 -10z m-2450 -572 c12
-67 41 -123 80 -155 19 -16 30 -35 30 -51 0 -22 -5 -26 -30 -26 -16 0 -55 -7
-87 -15 -85 -22 -177 -19 -278 10 -48 14 -96 30 -107 36 -19 10 -19 11 -1 31
21 23 51 40 73 42 20 1 149 77 147 86 -3 11 106 97 128 102 28 6 33 -1 45 -60z
m35 -2594 c78 -39 165 -110 211 -171 20 -26 49 -54 64 -62 53 -27 142 -165
155 -240 4 -21 13 -44 20 -50 7 -5 36 -77 64 -158 40 -117 51 -162 51 -211 0
-70 -9 -87 -60 -106 -19 -8 -51 -24 -70 -36 -60 -38 -134 -51 -280 -50 l-135
1 -6 165 c-6 159 -16 227 -37 253 -15 19 -69 203 -88 302 -9 50 -22 93 -27 96
-12 8 1 266 15 292 12 24 41 18 123 -25z m3422 -1362 c50 -11 67 -20 95 -51
44 -50 57 -75 58 -107 0 -18 5 -28 15 -28 8 0 15 -7 15 -15 0 -15 22 -22 150
-51 89 -19 200 -69 200 -89 0 -20 116 -131 152 -146 15 -6 28 -19 28 -28 0
-10 15 -25 35 -34 21 -10 35 -24 35 -34 0 -10 9 -24 21 -31 11 -7 18 -19 16
-26 -3 -7 -1 -34 4 -61 14 -73 -3 -120 -67 -187 -30 -31 -57 -52 -60 -46 -3 5
-26 -20 -50 -57 -25 -36 -42 -70 -38 -76 3 -6 -3 -13 -14 -16 -11 -2 -37 -30
-58 -60 -41 -60 -83 -85 -162 -98 -23 -4 -40 -10 -37 -15 8 -13 -118 -21 -158
-9 -38 10 -135 87 -231 184 -40 39 -51 58 -52 84 -2 42 -34 74 -98 98 -69 26
-90 57 -94 146 -2 43 3 99 12 140 9 38 16 98 16 135 0 75 -25 298 -40 352 -8
30 -7 38 16 61 34 35 117 71 147 64 12 -3 34 -2 47 4 32 12 25 13 97 -3z"/>
<path d="M1406 7258 c-10 -57 -29 -150 -42 -208 -26 -115 -67 -350 -114 -650
-55 -349 -62 -839 -14 -1000 21 -73 31 -81 47 -39 10 24 16 109 21 299 3 146
11 319 16 385 26 313 32 372 39 405 l7 35 7 -41 c4 -24 14 -44 23 -48 10 -4
14 -12 10 -22 -4 -9 0 -21 9 -28 8 -6 19 -33 24 -60 5 -27 16 -53 25 -58 9 -5
16 -20 16 -34 0 -13 7 -27 15 -30 8 -4 15 -15 15 -25 0 -34 31 -98 51 -104 10
-4 19 -15 19 -26 0 -26 47 -119 64 -125 8 -3 21 -25 30 -48 9 -24 25 -51 35
-60 17 -16 21 -16 59 -1 l41 17 -104 208 c-121 246 -153 327 -188 475 -39 165
-48 262 -56 585 -5 252 -8 295 -21 298 -12 2 -19 -20 -34 -100z"/>
<path d="M3394 7241 c-58 -14 -259 -122 -291 -156 -18 -19 -33 -39 -33 -45 0
-17 44 -22 204 -18 126 2 159 6 166 18 15 24 30 80 37 143 5 48 3 57 -10 57
-8 0 -21 2 -29 4 -7 2 -27 1 -44 -3z"/>
<path d="M3015 6740 c-17 -4 -45 -14 -62 -24 -26 -13 -33 -23 -33 -46 0 -30 1
-30 55 -30 84 0 124 28 125 86 0 15 -46 22 -85 14z"/>
<path d="M3200 6440 c-81 -21 -326 -138 -353 -168 -9 -10 -18 -29 -19 -43 -5
-41 53 -38 173 11 142 57 222 73 339 64 88 -6 96 -5 114 15 15 16 17 29 12 65
-4 24 -14 50 -22 57 -26 22 -161 21 -244 -1z"/>
<path d="M4287 5975 c-16 -8 -70 -49 -120 -92 -106 -88 -190 -145 -297 -198
-41 -20 -77 -39 -79 -41 -2 -2 0 -15 3 -30 7 -26 9 -27 62 -21 84 9 182 64
339 190 134 109 194 172 178 188 -17 17 -59 19 -86 4z"/>
<path d="M2166 5461 c-3 -5 -3 -22 0 -39 6 -29 10 -31 148 -68 l141 -39 222 0
c220 0 222 0 247 24 14 14 26 27 26 31 0 21 -70 33 -235 41 -99 4 -216 15
-260 23 -44 8 -104 20 -134 26 -66 12 -148 13 -155 1z"/>
<path d="M2960 3874 c-68 -31 -92 -62 -98 -127 l-5 -50 60 5 c61 6 173 49 194
74 6 7 15 30 19 51 7 29 5 42 -7 55 -24 27 -96 23 -163 -8z"/>
<path d="M4665 3583 c18 -133 77 -259 134 -284 18 -8 31 -21 31 -31 0 -11 8
-18 20 -18 16 0 20 -7 20 -33 0 -73 89 -273 127 -288 38 -14 43 -11 43 24 0
97 -73 281 -145 367 -55 65 -78 105 -114 196 -28 69 -37 83 -67 97 -52 25 -56
23 -49 -30z"/>
<path d="M5580 3422 c-7 -15 -16 -85 -20 -157 -8 -146 -20 -189 -87 -314 -40
-75 -43 -85 -30 -99 14 -13 20 -11 55 16 79 63 135 170 167 325 18 81 18 110
5 175 -9 41 -16 51 -44 65 -33 15 -34 15 -46 -11z"/>
<path d="M2065 2688 c-49 -103 -119 -223 -204 -353 -36 -55 -75 -120 -86 -145
-11 -25 -22 -47 -26 -50 -3 -3 -14 -38 -24 -78 -26 -109 -18 -348 14 -414 13
-27 27 -48 31 -48 8 0 22 38 34 92 3 15 11 81 16 147 12 150 51 276 120 391
66 109 130 194 140 183 4 -4 31 -61 59 -125 29 -64 59 -119 67 -122 44 -17 57
74 28 206 -8 40 -26 142 -39 226 -13 84 -27 157 -30 162 -3 6 -19 10 -34 10
-24 0 -31 -9 -66 -82z"/>
<path d="M2387 1383 c22 -84 59 -153 83 -153 13 0 20 -7 20 -19 0 -10 9 -21
20 -24 11 -3 20 -12 20 -20 0 -15 89 -81 156 -115 105 -53 297 -75 424 -48 50
10 81 23 92 37 10 11 33 25 52 30 40 11 70 64 45 80 -25 15 -55 10 -125 -23
-155 -73 -372 -38 -561 90 -88 60 -157 126 -184 176 -14 26 -31 46 -41 46 -15
0 -15 -5 -1 -57z"/>
<path d="M4830 895 c-11 -14 -10 -98 2 -110 2 -3 19 -8 36 -11 l32 -6 0 61 c0
57 -2 62 -26 71 -32 12 -29 13 -44 -5z"/>
<path d="M5695 701 c-3 -6 -24 -20 -45 -31 -34 -18 -56 -20 -167 -18 -135 3
-149 0 -213 -51 -21 -17 -22 -21 -10 -37 14 -15 31 -16 193 -11 240 9 297 32
297 123 0 13 -4 24 -9 24 -5 0 -16 3 -24 6 -8 3 -18 0 -22 -5z"/>
<path d="M6324 1379 c2 -8 7 -26 10 -41 4 -18 13 -28 25 -28 13 0 20 -10 25
-30 3 -18 12 -30 21 -30 8 0 15 -9 15 -20 0 -13 7 -20 20 -20 11 0 20 -6 20
-14 0 -8 15 -24 34 -35 19 -12 36 -28 39 -35 3 -8 14 -13 24 -11 10 2 35 7 56
10 31 5 37 10 37 29 0 20 -8 26 -51 36 -38 9 -53 18 -59 36 -5 13 -14 24 -19
24 -6 0 -28 27 -51 59 -47 71 -46 69 -104 77 -37 5 -46 4 -42 -7z"/>
<path d="M6266 1145 c-12 -33 -5 -66 19 -87 14 -12 25 -31 25 -43 0 -44 85
-95 159 -95 34 0 42 5 60 34 24 38 26 46 10 46 -6 0 -42 9 -80 21 -54 16 -69
25 -69 40 0 26 -59 87 -91 94 -19 5 -28 2 -33 -10z"/>
<path d="M6120 1020 c-12 -23 -10 -28 34 -84 36 -45 73 -66 116 -66 27 0 30 3
30 33 0 25 -9 42 -38 70 -21 20 -46 37 -55 37 -9 0 -17 7 -17 15 0 24 -57 19
-70 -5z"/>
<path d="M5190 7540 c-24 -6 -25 -10 -24 -71 1 -82 51 -286 76 -309 10 -9 16
-24 13 -32 -4 -9 0 -18 9 -21 9 -4 12 -14 9 -26 -3 -13 -1 -21 7 -21 8 0 10
-8 6 -24 -4 -16 -1 -26 8 -29 8 -3 17 -21 21 -39 8 -39 40 -145 62 -204 8 -23
25 -47 37 -53 12 -7 27 -26 33 -42 9 -23 17 -29 42 -29 24 0 31 4 31 20 0 22
-43 156 -104 325 -42 118 -139 435 -134 440 7 7 224 -90 373 -165 337 -172
819 -494 1189 -795 72 -58 136 -105 143 -105 7 0 13 -9 13 -19 0 -12 44 -59
118 -124 64 -58 157 -150 206 -206 53 -61 96 -101 107 -101 12 0 19 -7 19 -20
0 -13 7 -20 20 -20 12 0 20 -7 20 -16 0 -14 101 -149 236 -314 52 -63 182
-268 225 -352 27 -54 32 -58 65 -58 l35 0 -6 48 c-15 107 -163 340 -431 672
-90 112 -544 570 -654 661 -135 111 -250 196 -402 299 -90 61 -226 155 -303
210 -196 139 -357 233 -606 354 -305 148 -397 181 -459 166z"/>
<path d="M4877 7345 c-50 -38 -109 -119 -202 -280 -65 -112 -129 -206 -188
-278 -43 -52 -40 -67 13 -67 52 0 87 38 245 261 87 123 160 226 162 229 3 3
15 -8 27 -23 23 -29 74 -67 89 -67 4 0 15 16 23 35 12 30 12 40 -2 82 -21 63
-38 95 -60 114 -37 33 -58 31 -107 -6z"/>
<path d="M6415 4012 c-21 -21 27 -214 59 -238 9 -6 14 -18 10 -28 -4 -10 0
-18 10 -22 9 -4 16 -18 16 -34 0 -16 7 -30 15 -34 8 -3 15 -16 15 -29 0 -14 7
-30 15 -37 8 -7 15 -21 15 -32 0 -32 41 -122 66 -143 13 -12 24 -31 24 -43 0
-13 7 -25 15 -28 8 -4 15 -16 15 -29 0 -28 46 -111 65 -119 9 -3 15 -18 15
-35 0 -16 6 -31 15 -35 8 -3 15 -12 15 -21 0 -8 4 -15 9 -15 5 0 12 -13 16
-29 3 -15 17 -38 30 -50 14 -11 25 -32 25 -46 0 -14 8 -29 20 -35 11 -6 20
-18 20 -26 0 -25 50 -103 69 -109 10 -3 23 -22 30 -43 6 -20 38 -75 71 -122
32 -47 92 -135 133 -195 41 -61 81 -116 90 -124 10 -7 17 -17 17 -22 0 -4 51
-78 113 -163 61 -85 146 -204 187 -263 65 -93 82 -111 127 -133 28 -14 52 -29
52 -35 1 -14 64 -115 72 -115 17 0 16 47 -2 95 -16 44 -167 273 -246 375 -44
56 -346 497 -459 670 -282 430 -424 701 -554 1055 -55 150 -83 209 -102 221
-16 10 -96 22 -103 16z"/>
</g>
</svg>

+ 12
- 0
frontend/images/user.svg Bestand weergeven

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg fill="#333" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 550 550" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<rect x="10" y="10" rx="20" ry="20" width="530" height="530" stroke="black" fill="transparent" stroke-width="20"/>
<g transform="translate(30 40) scale(0.95 0.95)">>
<path d="M256,0c-74.439,0-135,60.561-135,135s60.561,135,135,135s135-60.561,135-135S330.439,0,256,0z"/>
<path d="M423.966,358.195C387.006,320.667,338.009,300,286,300h-60c-52.008,0-101.006,20.667-137.966,58.195
C51.255,395.539,31,444.833,31,497c0,8.284,6.716,15,15,15h420c8.284,0,15-6.716,15-15
C481,444.833,460.745,395.539,423.966,358.195z"/>
</g>
</svg>

+ 298
- 0
frontend/src/html/index.html Bestand weergeven

@ -0,0 +1,298 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<link
rel="preload"
as="font"
type="font/woff2"
href="./fonts/Fonte-Texte.woff2"
crossorigin
/>
<link
rel="preload"
as="font"
type="font/woff2"
href="./fonts/Fonte-Titre.woff2"
crossorigin
/>
<title>template TOPISTO</title>
<meta name="description" content="Suivi activité">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="styles/app.css?TIMESTAMP">
</head>
<body>
<header>
<div id="marque">TEMPLATE</div>
<div id="logo">
<svg viewBox="0 0 920 920" class="js-open-modal-trigger" data-modal-info="type=settings">
<use href="#topisto"></use>
</svg>
</div>
</header>
<nav>
<section id="ariane">
<div id="fil"></div>
<div id="aide"><a onclick="show_modal('type=login')"><span id="username" style="font-weight: bold;">Log In</span></a> - <a alt="aide" onclick="gotoHelp()">?</a></div>
</section>
<section id="bandeau">
<div id="menu">
<a onclick="activeMenu(this)">Menu1</a>
<a onclick="activeMenu(this)">Menu2</a>
<a onclick="activeMenu(this)">Menu3</a>
</div>
<svg viewBox="0 0 920 920" id="settings" class="js-open-modal-trigger" data-modal-info="type=settings" >
<use href="#topisto"></use>
</svg>
</section>
</nav>
<section id="synthesis">
<div id="synthesis_top">&nbsp;</div>
<div id="synthesis_body"></div>
<div id="synthesis_bottom">&nbsp;</div>
</section>
<section id="datagrid"></section>
<footer id="footer" ref="footer"></footer>
<dialog id="fiche" style="display:flex;flex-direction: row;">
<section style="width:100%;height:100%">
<div style="overflow-y: hidden;overflow-x: hidden;height: 10%;">
<div style="float:left"><div class="modal_header">This is a modal header</div></div>
<div style="float:right"><span class="js-close-modal-trigger" data-modal-info="">&#x2715;</span></div>
<div style="clear:both"></div>
</div>
<div class="modal_body" style="overflow-y: auto;overflow-x: hidden;height: 80%;">
</div>
<footer style="overflow-y: hidden;overflow-x: hidden;height: 10%; vertical-align: bottom;">
<span class="modal_footer">This is a modal footer</span>
</footer>
</section>
</dialog>
<dialog id="popup">
<div style="overflow-y: hidden;overflow-x: hidden;height: 10%">
<div style="float:left"><span class="modal_header">This is a modal header</span></div>
<div style="float:right"><span class="js-close-modal-trigger" data-modal-info="">&#x2715;</span></div>
<div style="clear:both"></div>
</div>
<div class="modal_body" style="overflow-y: auto;overflow-x: hidden;height: 80%;"></div>
<div style="overflow-y: hidden;overflow-x: hidden;height: 10%;vertical-align: text-bottom;"><span class="modal_footer">This is a modal footer</span></div>
</dialog>
<template id="filtre_level">
<select onchange="changeAffichageNiveauxEvent(event)">
<option value="9999" selected>Tous les niveaux</option>
<option value="1">1 niveau</option>
<option value="2">2 niveaux</option>
<option value="3">3 niveaux</option>
<option value="4">4 niveaux</option>
<option value="5">5 niveaux</option>
<option value="6">6 niveaux</option>
<option value="7">7 niveaux</option>
<option value="8">8 niveaux</option>
<option value="9">9 niveaux</option>
<option value="10">10 niveaux</option>
</select>
</template>
<template id="settings_header">
<section style="display: flex">
<svg viewBox="0 0 920 920" onclick="settingsSetModeInfo()">
<use href="#topisto"></use>
</svg>
<svg viewBox="0 0 550 550" onclick="settingsSetModeLogin()">
<use href="#user"></use>
</svg>
<svg viewBox="0 0 1024 1024" onclick="settingsSetModeFilter()">
<use href="#filter"></use>
</svg>
<svg viewBox="0 0 1024 1024" onclick="settingsSetModeSetup()">
<use href="#setup"></use>
</svg>
</section>
</template>
<template id="settings_body">
<section style="height: 90%;text-align: center;display: flex;justify-content: center;align-items: center;">
<div>
<h2>TEMPLATE</h2>
<h3>Fournir un template générique pour les applis HTML</h3>
<p>Version 0.1</p>
<p><small>
contributeurs:<br>
Albert Seandhils<br>
</small></p>
</div>
</section>
</template>
<template id="synthesis_body_accueil">
</template>
<template id="synthesis_body_taches">
<div class="statrow" style="margin-top: 5px">
<div class="statbox1" onclick="changeModeAffichage('taches','Tasks')">Tasks</div>
<div class="statbox1" onclick="changeModeAffichage('releases','Realeases')">Realeases</div>
<div class="statbox1" onclick="changeModeAffichage('feries','Hollidays')">Hollidays</div>
<div class="statbox1" onclick="changeModeAffichage('rdv','Rendez-Vous')">RdV</div>
<div class="statbox1" onclick="changeModeAffichage('items','Items')">Items</div>
</div>
<br>
<!--
<select onchange="changeModeAffichageEvent(event)">
<option value="taches" selected>Tasks</option>
<option value="releases">Releases</option>
<option value="feries">Hollidays</option>
<option value="rdv">Rendez-Vous</option>
<option value="items">Items</option>
</select>
-->
<select onchange="changeAffichageNiveauxEvent(event)">
<option value="9999" selected>Tous les niveaux</option>
<option value="1">1 niveau</option>
<option value="2">2 niveaux</option>
<option value="3">3 niveaux</option>
<option value="4">4 niveaux</option>
<option value="5">5 niveaux</option>
<option value="6">6 niveaux</option>
<option value="7">7 niveaux</option>
<option value="8">8 niveaux</option>
<option value="9">9 niveaux</option>
<option value="10">10 niveaux</option>
</select>
<select onchange="changeFiltreClient(event)">
<option value="ALL">Tous les clients</option>
<option value="TME">TME</option>
<option value="REL">Realeases</option>
<option value="FER">Fériés</option>
<option value="RDV">Rendez-vous</option>
<option value="CGI">CGI</option>
<option value="CD56">CD56</option>
<option value="CD44">CD44</option>
<option value="CD49">CD49</option>
<option value="CD61">CD61</option>
<option value="CD33">CD33</option>
<option value="CD58">CD58</option>
<option value="CD18">CD18</option>
<option value="CTM">CTM</option>
<option value="CNFPT">CNFPT</option>
<option value="CRNA">CRNA</option>
<option value="CRNA">TME</option>
</select>
<select onchange="changeAffichageItemsTermine(event)">
<option value="oui">Afficher les items terminés</option>
<option value="non">Masquer les items terminés</option>
</select>
</template>
<template id="synthesis_body_calendrier">
<select onchange="changeModeAffichageEvent(event)">
<option value="calendar_intervenants" selected>Calendrier Intervenants</option>
<option value="calendar_clients">Calendrier Clients</option>
</select><br>
<select onchange="changeCalendarEvent(event)">
<option value="1" selected>Cette semaine</option>
<option value="2">Cette année</option>
</select><br>
</template>
<template id="synthesis_body_planning">
<select onchange="changeAffichageItemsTermine(event)">
<option value="non">Masquer les items terminés</option>
<option value="oui">Afficher les items terminés</option>
</select>
</template>
<template id="synthesis_body_project">
<select onchange="changeAffichageItemsTermine(event)">
<option value="non">Masquer les items terminés</option>
<option value="oui" selected>Afficher les items terminés</option>
</select>
<select onchange="changeAffichageItemsPrestations(event)">
<option value="non">Tous les items</option>
<option value="oui" selected>Uniquement les prestations</option>
</select>
</template>
<template id="footer_accueil">
<h2>Gestion de Projet</h2>
<p>
<small>
Un projet est un ensemble d'efforts fournis de manière limitée dans le temps afin de produire un résultat
unique.
<br>La gestion de projet met en oeuvre un ensemble de techniques et de compétences pour garantir le succès
d'un
projet.
<br>
<br>Loi de Parkinson : le travail s'étale de façon à occuper tout le temps disponible pour son achèvement.
<br>Loi de Hofstadter: il est presque impossible de prévoir le temps qui sera nécessaire à l'accomplissement
d'une
tâche complexe.
<br>Principe de Pareto : 20% des efforts produisent 80% des effets.
<br>
<br>Loi de Conway : un produit est le reflet de l'organisation qui l'a conçu.
<br>On ne peut améliorer que ce que l'on mesure : résultats, performances,...
<br>
<br>La tranquillité ce n'est pas l'inaction.
</small>
</p>
<p>
<i>
NB : En Tchèque, SMETI c'est la poussière (littéralement : "ce qui peut être balayé")
</i>
</p>
<h2>Explications</h2>
<p>
L'objectif de cette page est de présenter des données sous forme de tableau.<br>
La page permet en outre :
<ul>
<li>De rappeler l'identité visuelle : logo, bannière</li>
<li>De naviguer dans l'application</li>
<li>D'accéder à une synthèse et à une explication des données</li>
</ul>
</p>
<p>
Le header est une bannière qui fait 30% du viewport.
Elle contient une image de background alignée à gauche et un texte aligné à droite.
</p>
<p>
Lorsque le header sort de la partie visible de la page :
<ul>
<li>La barre de navigation devient "collée" au haut de page.</li>
<li>Le pied de tableau devient "collé" en bas de page</li>
<li>le logo apparaît à gauche de la barre de navigation.</li>
</ul>
</p>
<p>Lorsque le tableau sort de la partie visible de la page, le footer et la zone d'explication peuvent occuper
toute
la page.</p>
<p> Provident pariatur fugit sint autem laudantium omnis. Dolores repudiandae voluptatem molestiae ratione placeat
similique eaque. Aliquam sit ullam non non qui. Dicta molestiae neque repellendus dicta iure tempora. Et ipsam
voluptatum nesciunt eligendi. Eos harum rerum vitae.
</p>
<h2>Focus sur la gestion des thèmes</h2>
<p>
Voici comment s'opère la gestion des couleurs.<br>
Dans le default.css, la section CSS root contient des variables CSS.<br>
On a le triplet (R,G,B) de la couleur dominante et celui de la couleur de fond.<br>
Ces couleurs sont respectivement appelées "sombre" et "clair".<br>
<br>
Des variables sont ensuite définies pour décliner des dégradés de couleurs.<br>
<ul>
<li>- Soit par ajout de transparence, ce sont les variables --nuance-{sombre|clair}-alpha-XX</li>
<li>- Soit par calul de dégradé</li>
</ul>
<br>
Enfin une batterie de fonctions javascript permettent de modifier à la volée les couleurs "sombre" et "clair".
</template>

+ 381
- 0
frontend/src/html/logo.html Bestand weergeven

@ -0,0 +1,381 @@
<div style="display:none">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol id="user" viewBox="0 0 550 550">
<g transform="translate(30 40) scale(0.95 0.95)">
<path d="M256,0c-74.439,0-135,60.561-135,135s60.561,135,135,135s135-60.561,135-135S330.439,0,256,0z"/>
<path d="M423.966,358.195C387.006,320.667,338.009,300,286,300h-60c-52.008,0-101.006,20.667-137.966,58.195
C51.255,395.539,31,444.833,31,497c0,8.284,6.716,15,15,15h420c8.284,0,15-6.716,15-15
C481,444.833,460.745,395.539,423.966,358.195z"/>
</g>
</symbol>
<symbol id="filter" viewBox="0 0 1024 1024">
<g>
<path d="M859.02 234.524l0.808-0.756 0.749-0.813c27.047-29.356 33.876-70.34 17.823-106.957-15.942-36.366-50.416-58.957-89.968-58.957H163.604c-38.83 0-73.043 22.012-89.29 57.444-16.361 35.683-10.632 76.301 14.949 106.004l0.97 1.126 280.311 266.85 2.032 312.074c0.107 16.502 13.517 29.805 29.995 29.805l0.2-0.001c16.568-0.107 29.912-13.626 29.804-30.194l-2.198-337.564-296.478-282.241c-9.526-11.758-11.426-26.933-5.044-40.851 6.446-14.059 19.437-22.452 34.75-22.452h624.828c15.6 0 28.69 8.616 35.017 23.047 6.31 14.391 3.924 29.831-6.354 41.497l-304.13 284.832 1.302 458.63c0.047 16.54 13.469 29.916 29.998 29.915h0.087c16.568-0.047 29.962-13.517 29.915-30.085L573.04 502.36l285.98-267.836z" fill="" /><path d="M657.265 595.287c0 16.498 13.499 29.997 29.997 29.997h243.897c16.498 0 29.997-13.498 29.997-29.997 0-16.498-13.499-29.997-29.997-29.997H687.262c-16.498 0-29.997 13.499-29.997 29.997z m273.894 138.882H687.262c-16.498 0-29.997 13.499-29.997 29.997s13.499 29.997 29.997 29.997h243.897c16.498 0 29.997-13.499 29.997-29.997 0-16.498-13.499-29.997-29.997-29.997z m0 168.878H687.262c-16.498 0-29.997 13.499-29.997 29.997s13.499 29.997 29.997 29.997h243.897c16.498 0 29.997-13.499 29.997-29.997 0-16.498-13.499-29.997-29.997-29.997z" />
</g>
</symbol>
<symbol id="setup" viewBox="0 0 1024 1024">
<g>
<path d="M509.946 338.983c-95.925 0-173.983 78.034-173.983 173.935 0 95.913 78.057 173.947 173.983 173.947 27.333 0 53.132-6.515 76.17-17.797l-0.024-0.057c6.245-3.17 10.527-9.63 10.527-17.104 0-10.598-8.59-19.237-19.214-19.237-2.493 0-4.867 0.49-7.051 1.357l-0.102-0.225c-18.196 9.088-38.614 14.352-60.306 14.352-74.588 0-135.249-60.663-135.249-135.238 0-74.564 60.66-135.201 135.249-135.201s135.296 60.637 135.296 135.2c0 13.314-2.03 26.166-5.617 38.32l0.345 0.135c-0.365 1.48-0.58 3.02-0.58 4.61 0 10.598 8.59 19.19 19.212 19.19 7.32 0 13.676-4.081 16.919-10.09l0.334 0.13c0.33-1.05 0.653-2.105 0.964-3.163 0.153-0.455 0.28-0.92 0.398-1.39a173.233 173.233 0 0 0 6.711-47.74c0-95.9-78.032-173.934-173.982-173.934z m411.693 77.904h-66.23c-3.423-12.534-7.65-25.138-12.889-38.31l-3.87-9.3c-5.098-11.824-10.952-23.46-17.327-34.673l46.808-46.806c4.814-4.817 7.48-11.213 7.48-18.01 0-6.798-2.665-13.195-7.48-18.01l-96.987-96.965c-9.656-9.654-26.438-9.654-36.044 0l-46.806 46.806c-11.375-6.467-23.369-12.438-36.775-18.246l-8.686-3.54a366.101 366.101 0 0 0-36.82-12.298v-66.182c0-14.043-11.425-25.468-25.493-25.468H443.384c-14.069 0-25.492 11.448-25.492 25.468v66.186c-12.51 3.445-24.856 7.553-36.775 12.298l-10.764 4.46a354.674 354.674 0 0 0-34.697 17.325l-46.828-46.806c-9.63-9.63-26.39-9.63-36.043 0L155.82 251.78a25.282 25.282 0 0 0-7.482 18.01c0 6.798 2.643 13.17 7.482 18.01l46.806 46.807c-6.467 11.376-12.462 23.462-18.41 37.199l-3.423 8.286c-4.744 11.944-8.827 24.263-12.25 36.797h-66.232c-14.044 0-25.47 11.449-25.47 25.469v137.137c0 14.02 11.426 25.444 25.47 25.444h66.232c3.447 12.58 7.694 25.209 12.958 38.522l3.8 9.11a356.298 356.298 0 0 0 17.325 34.627l-46.782 46.817c-9.937 9.914-9.937 26.107 0 36.02L252.807 867c9.63 9.582 26.39 9.63 36.02 0l46.828-46.83a355.428 355.428 0 0 0 34.557 17.325l7.93 3.305 3.02 1.226a349.604 349.604 0 0 0 36.776 12.227v66.184c0 14.069 11.423 25.493 25.492 25.493h137.136c14.07 0 25.493-11.472 25.493-25.493v-66.184c12.558-3.446 25.137-7.648 38.238-12.84l9.348-3.87a354.975 354.975 0 0 0 34.697-17.374l46.83 46.83c9.607 9.582 26.388 9.63 36.018 0l97.011-96.963c9.915-9.914 9.915-26.107 0-36.02l-46.83-46.818c6.42-11.26 12.371-23.202 18.082-36.42l1.51-3.589 2.22-5.476a360.913 360.913 0 0 0 12.273-36.775h66.233c14.044 0 25.468-11.401 25.468-25.444V442.356c-0.048-14.02-11.472-25.47-25.518-25.47zM906.605 564.41h-83.061l-4.626 19.685c-3.471 14.635-8.048 29.057-13.973 43.997l-1.415 3.54-2.031 4.793c-5.949 13.738-12.911 27.096-20.725 39.701l-10.62 17.207 58.702 58.714-75.698 75.673-58.678-58.679-17.232 10.575c-12.936 7.978-26.154 14.823-41.59 21.574l-7.741 3.115a317.74 317.74 0 0 1-42.793 13.502l-19.664 4.672v82.896H458.42V822.48l-19.662-4.672c-14.918-3.588-29.315-8.167-45.319-14.494l-7.13-2.973c-13.595-5.901-26.907-12.887-39.676-20.724l-17.208-10.575-58.678 58.679-75.697-75.673 58.678-58.714-10.598-17.207c-7.907-12.77-14.87-26.223-21.315-41.07l-3.35-8.285a309.225 309.225 0 0 1-13.432-42.723l-4.696-19.638h-82.966V457.39h82.966l4.696-19.637c3.517-14.823 8.167-29.433 14.186-44.588l3.234-7.765c5.878-13.596 12.841-26.955 20.7-39.725l10.621-17.207-58.678-58.656 75.697-75.672 58.655 58.654 17.231-10.598c12.747-7.86 26.154-14.8 40.999-21.22l8.452-3.47c13.594-5.404 27.945-9.936 42.627-13.453l19.685-4.626v-82.991h107.066v82.991l19.683 4.626c14.731 3.494 28.94 8.002 44.613 14.186l7.743 3.258c13.76 5.947 27.143 12.91 39.747 20.7l17.207 10.599 58.655-58.655 75.72 75.672-58.678 58.656 10.573 17.183c7.883 12.817 14.87 26.294 21.363 41.26l3.373 8.167a320.605 320.605 0 0 1 13.456 42.628l4.626 19.684h83.014V564.41z" />
</g>
</symbol>
<symbol id="topisto" viewBox="0 0 920 920">
<g transform="translate(0,920) scale(0.100000,-0.100000)" stroke="none">
<path d="M319 9096 c-90 -32 -173 -111 -206 -194 -17 -45 -18 -209 -21 -4267
-2 -3005 0 -4238 8 -4284 20 -118 78 -198 175 -243 l50 -23 4265 -3 4265 -2
61 20 c82 28 136 76 176 158 l33 67 3 4255 c2 4621 6 4310 -51 4387 -41 56
-116 110 -176 127 -52 15 -439 16 -4302 16 -3444 -1 -4251 -3 -4280 -14z
m8488 -147 c66 -13 124 -55 160 -116 l28 -48 0 -4205 c0 -3952 -1 -4207 -17
-4236 -23 -41 -71 -82 -133 -110 l-50 -24 -4146 0 c-2773 0 -4164 3 -4200 10
-75 14 -144 63 -177 125 l-27 50 -3 4160 c-1 2929 1 4175 8 4212 6 28 21 67
33 85 30 43 95 88 149 102 60 15 8299 10 8375 -5z"/>
<path d="M6205 8623 c-324 -38 -610 -144 -869 -321 -65 -45 -135 -85 -154 -88
-56 -11 -174 25 -217 66 -34 31 -29 62 10 73 63 19 80 32 83 64 3 27 -1 33
-20 37 -166 34 -352 -16 -448 -120 -66 -72 -80 -110 -80 -221 0 -127 15 -179
84 -292 69 -115 79 -150 66 -222 -13 -68 -81 -210 -151 -314 -30 -45 -63 -98
-74 -120 -32 -64 -184 -208 -256 -244 -34 -17 -67 -31 -73 -31 -6 0 -31 28
-55 61 -24 33 -54 65 -67 70 -13 4 -24 14 -24 20 0 6 -19 41 -43 78 -35 52
-135 271 -187 407 -13 34 -67 91 -113 117 -61 36 -88 69 -150 182 -31 56 -70
112 -89 127 -40 33 -106 45 -166 29 l-42 -12 0 -48 c0 -32 6 -56 19 -72 17
-22 61 -103 61 -112 0 -3 -21 -8 -47 -12 -102 -15 -203 -48 -304 -98 l-105
-53 12 36 c7 20 18 73 24 119 9 68 9 86 -2 92 -42 27 -106 -11 -163 -96 -57
-85 -75 -148 -86 -310 -19 -267 -62 -437 -147 -582 -103 -176 -122 -221 -122
-287 0 -69 27 -138 59 -156 12 -6 44 -14 71 -17 l50 -6 0 -54 c0 -63 -10 -86
-53 -122 -17 -14 -62 -53 -100 -87 -38 -34 -94 -76 -124 -94 l-54 -33 -44 21
c-34 16 -63 47 -134 143 -50 66 -91 125 -91 130 0 5 -23 34 -51 65 -132 145
-194 290 -239 560 -29 172 -30 408 -1 539 25 117 30 129 88 201 78 96 97 145
89 232 -4 53 -15 92 -41 147 -60 125 -120 148 -331 125 -129 -15 -161 -29
-243 -114 -37 -38 -45 -52 -49 -94 l-4 -49 47 -19 48 -18 -7 -88 c-5 -71 -18
-124 -65 -266 -33 -97 -71 -222 -85 -277 -35 -139 -94 -456 -100 -540 -5 -60
-13 -391 -30 -1270 -3 -163 12 -477 29 -580 3 -16 16 -106 30 -200 32 -211 56
-315 96 -413 91 -225 92 -229 96 -442 2 -107 6 -205 8 -217 9 -38 33 -27 45
20 6 23 25 84 42 135 l31 92 43 0 c24 0 46 -6 51 -12 25 -40 65 -182 70 -249
9 -121 -18 -224 -125 -469 -78 -178 -90 -217 -113 -338 -25 -142 -23 -196 9
-200 14 -2 24 3 28 15 50 142 66 172 94 181 33 12 32 13 49 -82 19 -103 13
-175 -24 -317 -42 -165 -51 -246 -35 -322 6 -31 14 -57 17 -57 3 0 26 18 50
41 37 34 49 40 81 37 l37 -3 32 -100 c37 -114 83 -308 83 -352 l0 -30 -117 35
c-106 31 -130 35 -233 34 -135 0 -204 -18 -308 -80 -37 -21 -89 -50 -117 -63
-47 -23 -50 -26 -53 -66 -3 -42 -2 -43 27 -43 16 0 67 16 113 36 131 56 174
65 238 48 71 -18 124 -18 140 1 15 19 17 17 -45 40 -61 22 -74 32 -50 41 52
20 392 -88 403 -128 2 -9 16 -18 31 -20 25 -3 26 -5 26 -73 l0 -70 -215 -6
c-188 -4 -222 -8 -274 -27 -52 -19 -79 -22 -228 -22 l-168 0 0 -35 c0 -31 3
-35 38 -44 20 -5 77 -9 127 -10 121 -1 141 -6 154 -42 6 -16 16 -43 22 -59 24
-64 138 -130 226 -130 65 -1 171 -32 267 -80 98 -49 104 -51 211 -57 181 -10
341 32 409 107 29 32 76 131 76 160 0 22 55 8 108 -28 89 -60 146 -96 154 -97
3 0 10 -3 14 -8 4 -4 16 -7 26 -7 10 0 18 -4 18 -9 0 -5 38 -15 84 -21 86 -13
176 -11 461 11 177 13 555 23 890 24 l260 0 -4 -161 c-3 -127 0 -172 13 -217
22 -75 69 -135 136 -170 52 -27 60 -29 145 -24 50 3 110 12 135 21 33 13 85
18 198 19 113 1 155 5 161 15 14 22 140 49 207 44 46 -3 76 1 117 16 34 13 94
24 156 28 56 4 101 11 101 16 0 5 13 7 30 3 37 -8 86 25 122 82 19 32 23 51
23 123 0 74 -3 88 -22 107 -44 44 -87 263 -56 294 7 7 36 -18 98 -88 49 -54
95 -102 102 -106 7 -4 13 -14 13 -21 0 -22 102 -85 157 -96 35 -8 69 -8 110
-1 32 5 87 13 123 16 100 10 138 33 202 123 91 127 124 177 137 210 9 21 20
32 33 32 11 0 22 8 25 19 3 11 13 21 22 24 9 2 26 26 36 53 10 27 25 54 32 59
18 14 22 136 5 191 -18 63 -63 117 -149 180 -43 31 -112 86 -154 120 -93 77
-144 103 -278 143 -57 17 -105 31 -107 31 -2 0 -4 10 -4 22 0 29 -101 162
-152 198 -34 25 -51 30 -99 30 -58 0 -221 -44 -227 -61 -2 -5 -11 -9 -19 -9
-14 0 -15 11 -9 81 8 92 22 134 59 167 20 19 31 22 60 17 38 -7 67 -32 71 -61
2 -12 57 -49 162 -107 87 -49 191 -111 229 -140 349 -256 830 -573 1036 -683
256 -137 585 -292 816 -385 124 -50 251 -48 288 4 9 13 15 43 15 75 0 68 -26
108 -76 118 -25 4 -38 14 -45 30 -5 14 -26 48 -48 77 -108 144 -359 617 -451
848 -93 233 -191 618 -234 919 -92 637 5 1104 326 1588 51 76 100 153 110 170
21 39 57 62 105 69 31 4 44 0 75 -25 24 -18 56 -32 85 -37 67 -10 77 5 68 115
-14 189 -58 296 -229 550 -189 280 -235 341 -550 730 -98 120 -118 169 -128
310 -8 111 -14 155 -59 400 -17 96 -20 142 -16 280 5 184 28 296 86 424 46
102 162 258 276 372 138 137 164 147 372 149 144 0 154 2 175 23 19 18 23 35
26 95 2 46 -2 81 -10 97 -16 29 -122 102 -154 106 -25 2 -102 51 -149 94 -16
15 -40 30 -53 33 -20 5 -22 2 -16 -16 21 -68 65 -111 166 -163 57 -29 118 -81
118 -100 0 -11 -16 -14 -67 -14 -171 -1 -381 -90 -414 -177 -5 -13 -17 -23
-28 -23 -40 0 -236 -261 -318 -425 -90 -177 -143 -373 -143 -526 0 -97 42
-369 71 -454 11 -33 23 -91 26 -130 l6 -70 -139 135 c-214 208 -508 473 -629
566 -68 52 -315 219 -415 279 -52 32 -189 109 -305 173 -115 63 -250 137 -298
166 -85 49 -88 52 -83 80 10 47 32 63 181 136 384 186 664 276 1025 326 94 14
193 18 400 19 298 0 371 -9 551 -70 89 -31 120 -31 170 -3 28 15 39 28 39 45
0 20 -5 23 -39 23 -22 0 -113 18 -203 40 -243 60 -329 72 -523 72 -195 0 -498
-24 -665 -52 -208 -34 -484 -126 -679 -224 -47 -24 -176 -95 -286 -158 -175
-100 -202 -119 -219 -152 -18 -37 -18 -37 3 -60 12 -13 68 -43 124 -66 169
-72 291 -136 527 -278 399 -240 670 -432 914 -645 43 -38 89 -73 102 -79 13
-6 24 -19 24 -28 0 -20 84 -102 153 -149 26 -18 71 -61 100 -95 293 -351 324
-386 348 -386 10 0 19 -11 22 -27 6 -32 72 -113 92 -113 7 0 18 -12 24 -27 16
-37 77 -103 96 -103 8 0 15 -8 15 -17 0 -27 63 -113 83 -113 10 0 17 -8 17
-19 0 -10 32 -63 72 -117 39 -54 101 -144 136 -199 36 -55 75 -111 88 -125 15
-16 30 -56 43 -115 11 -49 25 -105 30 -122 l10 -33 -98 0 c-90 0 -100 -2 -144
-29 -89 -57 -164 -153 -286 -368 -155 -273 -253 -571 -276 -837 -8 -95 10
-483 31 -651 18 -141 112 -571 154 -700 16 -49 38 -126 50 -169 11 -44 28 -85
37 -91 9 -7 14 -19 10 -28 -4 -11 1 -20 12 -26 12 -7 21 -27 25 -60 4 -29 12
-51 21 -55 8 -3 15 -17 15 -30 0 -15 8 -30 20 -36 11 -6 20 -21 20 -34 0 -13
7 -26 15 -30 8 -3 18 -24 21 -46 4 -25 14 -45 25 -51 12 -6 19 -21 19 -38 0
-16 7 -31 15 -35 8 -3 15 -17 15 -31 0 -14 7 -28 15 -31 8 -4 15 -17 15 -30 0
-12 9 -29 20 -37 11 -8 23 -28 26 -45 4 -18 14 -34 25 -37 11 -4 21 -20 25
-41 3 -19 15 -39 25 -45 11 -5 19 -17 19 -26 0 -10 24 -56 53 -103 30 -47 68
-109 85 -138 l32 -52 -45 0 c-59 0 -109 21 -470 200 -481 239 -684 364 -1515
935 -177 121 -331 225 -343 232 -32 18 -47 43 -47 78 0 34 36 130 71 189 l22
37 41 -39 c23 -21 68 -61 101 -88 33 -27 88 -74 122 -105 34 -31 92 -78 130
-105 279 -195 424 -304 467 -353 11 -11 30 -21 43 -21 12 0 23 -6 23 -12 0
-21 206 -168 235 -168 8 0 15 -8 15 -18 0 -13 44 -39 163 -99 225 -112 318
-138 331 -91 4 17 -3 32 -28 58 -31 32 -118 146 -481 625 -148 195 -299 416
-435 635 -57 91 -153 242 -215 335 -111 168 -153 242 -250 443 -53 112 -89
152 -136 152 -24 0 -29 -4 -25 -17 3 -10 8 -40 12 -68 9 -61 45 -142 73 -161
13 -10 21 -26 21 -44 0 -18 9 -38 24 -52 13 -13 29 -41 36 -63 7 -22 21 -46
32 -53 10 -7 18 -22 18 -33 0 -11 7 -34 17 -52 29 -56 196 -302 214 -315 10
-6 20 -26 24 -42 4 -17 15 -35 25 -40 10 -5 21 -23 25 -40 4 -17 15 -35 25
-40 11 -6 22 -26 26 -45 4 -21 13 -37 25 -40 13 -4 19 -16 19 -34 0 -27 113
-205 169 -266 15 -16 65 -86 111 -155 46 -69 107 -153 136 -188 30 -35 68 -88
86 -118 20 -33 42 -57 56 -60 12 -4 22 -13 22 -22 0 -9 10 -26 22 -39 16 -18
18 -23 6 -23 -20 0 -289 179 -403 269 -49 39 -178 137 -285 218 -174 132 -411
325 -527 430 -67 61 -77 90 -79 233 -1 83 -9 163 -24 240 -21 107 -22 128 -14
305 5 105 9 240 9 300 l0 110 180 6 c99 3 196 10 215 14 70 15 135 57 205 132
39 42 114 119 167 172 103 102 138 158 159 259 9 44 6 84 -16 250 -35 252 -52
299 -170 477 -51 77 -107 169 -125 205 -18 36 -45 83 -61 106 -15 22 -31 54
-35 70 -4 18 -45 66 -108 128 -152 148 -223 197 -444 311 -101 52 -158 101
-262 230 -79 97 -185 181 -306 243 -202 105 -233 123 -319 192 -109 87 -132
100 -185 100 -39 0 -40 -1 -40 -32 0 -18 11 -51 25 -73 13 -22 25 -45 25 -50
0 -11 -72 -29 -160 -40 -44 -6 -164 -35 -365 -90 -72 -19 -134 -28 -221 -32
l-121 -6 -7 43 c-4 24 -3 46 1 50 4 4 53 41 108 83 136 103 226 184 330 297
148 161 275 375 306 512 l12 58 38 -6 c21 -4 50 -3 65 0 48 12 252 225 301
313 7 12 15 41 18 65 3 24 8 55 10 71 4 24 2 27 -24 27 -25 0 -31 -6 -42 -37
-24 -76 -62 -138 -128 -207 -38 -40 -73 -82 -80 -94 -6 -12 -18 -22 -25 -22
-7 0 -38 -18 -69 -40 -30 -22 -57 -40 -60 -40 -2 0 -7 20 -9 45 -4 29 -26 82
-66 154 -70 126 -82 163 -82 246 1 133 36 192 145 241 64 28 83 31 65 10 -9
-12 -8 -22 5 -50 21 -43 34 -54 120 -101 177 -97 171 -94 212 -83 52 14 91 35
208 113 243 160 449 245 780 320 113 26 206 62 220 85 6 10 -90 12 -160 3z
m-4607 -589 c43 -30 79 -90 74 -123 -2 -17 -8 -31 -12 -31 -4 0 -11 -12 -14
-26 -4 -14 -21 -56 -37 -94 -26 -57 -36 -70 -60 -75 -15 -4 -36 -2 -47 4 -10
5 -47 17 -83 25 -59 14 -65 14 -77 -1 -21 -29 38 -57 126 -62 l74 -3 -8 -52
c-4 -28 -8 -72 -8 -98 -1 -25 -4 -50 -8 -54 -12 -12 -10 -444 2 -444 6 0 10
-31 10 -74 0 -157 50 -353 120 -469 22 -36 40 -71 40 -76 0 -6 4 -11 10 -11 5
0 22 -25 37 -56 15 -30 50 -79 77 -108 52 -54 215 -279 223 -306 11 -40 -16
-71 -91 -105 -41 -18 -82 -32 -93 -29 -24 6 -144 -53 -208 -101 -48 -37 -95
-49 -124 -31 -5 4 -20 39 -33 78 -16 51 -29 74 -46 81 -16 7 -26 7 -34 -1 -15
-15 -47 -275 -35 -283 13 -9 -30 -201 -48 -214 -7 -6 -23 -42 -35 -80 -28 -88
-38 -300 -20 -413 16 -101 38 -172 52 -169 19 3 52 -121 52 -198 1 -78 -25
-162 -75 -247 -16 -26 -28 -54 -26 -60 2 -10 -55 -46 -75 -48 -13 0 -84 152
-101 215 -8 33 -18 87 -22 120 -3 33 -15 119 -25 190 -56 377 -75 696 -66
1080 6 250 28 659 41 765 3 25 10 112 14 195 6 92 13 151 20 153 6 2 11 26 11
52 0 45 54 333 67 352 2 5 16 57 29 116 28 127 92 342 107 360 5 7 12 55 15
106 l5 94 -32 17 c-26 13 -32 21 -29 43 3 30 65 70 148 96 64 21 189 20 218 0z
m1770 -217 c21 -22 52 -86 52 -107 0 -5 -13 -10 -29 -10 -31 0 -42 19 -57 103
-7 43 3 47 34 14z m14 -183 c20 -4 45 -14 55 -23 10 -9 49 -29 86 -45 65 -27
68 -31 62 -55 -3 -14 -9 -53 -12 -87 -6 -69 4 -94 61 -162 29 -36 47 -72 82
-172 3 -8 7 -51 9 -95 8 -141 27 -300 38 -313 15 -19 23 -192 9 -201 -6 -4
-21 -63 -33 -131 -12 -69 -28 -132 -35 -140 -7 -9 -23 -37 -34 -63 -14 -32
-27 -47 -40 -47 -10 0 -22 -5 -26 -11 -3 -6 -47 -38 -97 -70 -50 -33 -108 -77
-129 -97 -21 -20 -43 -37 -50 -37 -7 0 -47 -17 -88 -37 -188 -90 -363 -82
-466 23 -21 21 -46 39 -55 39 -10 0 -19 11 -22 28 -3 15 -22 72 -42 127 -55
151 -77 391 -54 591 7 60 15 172 18 249 4 88 9 132 14 118 4 -12 24 -36 44
-54 36 -31 38 -32 114 -26 96 6 166 35 175 71 9 36 -6 50 -94 87 -64 27 -90
32 -155 32 -65 1 -76 3 -72 16 17 55 24 133 18 214 -5 87 -4 97 22 155 15 34
31 62 35 62 7 0 30 -89 30 -116 0 -8 -11 -19 -25 -24 -14 -5 -25 -14 -25 -19
0 -4 -3 -23 -6 -40 -7 -31 -5 -30 52 29 96 101 237 171 414 209 100 21 161 25
222 15z m588 -714 c0 -13 9 -22 25 -26 14 -3 25 -13 25 -23 0 -9 3 -26 6 -38
5 -19 1 -23 -30 -29 -30 -5 -44 -1 -77 21 -52 34 -69 76 -69 167 l1 73 59 -63
c33 -34 60 -71 60 -82z m-1526 -276 c13 -5 16 -24 16 -100 0 -101 -5 -109 -48
-78 -19 13 -22 24 -22 77 0 40 6 70 16 85 17 25 16 24 38 16z m2556 -40 c63
-3 120 -10 125 -14 6 -4 41 -17 78 -28 79 -24 337 -168 337 -188 0 -8 10 -18
23 -23 25 -10 49 -41 81 -105 43 -86 191 -197 322 -244 27 -9 63 -27 78 -40
16 -12 37 -22 47 -22 10 0 26 -11 35 -25 9 -13 33 -32 54 -41 21 -10 41 -25
43 -36 3 -10 14 -18 25 -18 21 0 60 -44 115 -126 16 -23 39 -52 52 -64 14 -13
25 -31 25 -41 0 -9 7 -19 15 -23 8 -3 15 -16 15 -29 0 -14 7 -30 15 -37 20
-17 19 -40 -2 -40 -10 0 -45 7 -78 14 -218 50 -489 11 -787 -114 -76 -31 -78
-33 -78 -67 l0 -36 69 7 c38 4 118 23 176 41 217 70 384 88 557 62 l96 -15 54
-53 c30 -30 70 -63 91 -74 25 -13 37 -26 37 -41 0 -13 8 -24 20 -27 12 -3 20
-14 20 -25 0 -12 4 -23 9 -27 17 -10 68 -157 97 -275 36 -151 37 -238 5 -305
-28 -55 -305 -346 -355 -372 -68 -35 -321 -56 -406 -34 -19 6 -54 15 -77 21
-31 8 -43 16 -43 29 0 13 -16 25 -49 40 -104 44 -119 21 -56 -87 25 -43 51
-106 60 -142 19 -83 19 -220 0 -346 -19 -123 -19 -215 -1 -279 7 -28 21 -77
30 -110 9 -33 19 -103 23 -155 11 -189 -33 -361 -170 -660 -110 -241 -141
-436 -103 -654 21 -118 20 -198 -4 -306 -38 -171 -34 -207 38 -360 27 -58 57
-136 66 -175 31 -129 48 -174 67 -180 19 -6 27 -25 10 -25 -6 0 -6 -13 0 -32
5 -18 7 -54 3 -80 -9 -74 -60 -101 -214 -114 -47 -3 -111 -16 -145 -29 -97
-37 -310 -78 -395 -77 -113 2 -150 10 -150 33 0 31 42 66 88 74 23 4 44 11 48
16 3 5 24 9 48 9 38 0 44 3 58 34 16 33 16 34 -15 64 -45 43 -74 52 -131 40
-50 -10 -116 -4 -116 12 0 10 -74 52 -100 57 -8 2 -48 6 -88 9 -86 7 -108 -3
-148 -71 -23 -40 -25 -49 -14 -74 11 -27 15 -28 94 -34 45 -3 112 -11 149 -18
73 -14 71 -11 80 -95 l5 -40 -47 -13 c-25 -7 -61 -19 -79 -27 -38 -16 -111
-18 -163 -4 -70 20 -125 110 -136 223 -7 80 3 157 21 157 9 0 16 19 20 53 8
60 30 86 157 185 90 70 140 127 175 197 27 55 29 70 31 180 1 66 12 188 25
270 29 191 32 413 5 462 -9 18 -29 69 -43 115 -14 46 -66 169 -115 273 -48
105 -96 219 -105 255 -23 88 -22 289 1 385 38 160 44 294 30 678 -7 183 -6
212 9 252 22 58 74 102 181 153 75 37 85 45 85 68 l0 27 -69 -7 c-144 -13
-241 -70 -287 -171 -22 -47 -24 -62 -24 -230 1 -99 5 -225 10 -280 16 -175
-20 -450 -70 -531 -19 -29 -23 -31 -54 -24 -18 4 -38 10 -43 13 -6 4 -13 50
-16 104 -7 127 -26 183 -91 282 -29 45 -59 102 -65 129 -21 80 -46 137 -61
137 -8 0 -21 -18 -29 -40 -20 -61 -2 -150 48 -236 64 -111 81 -167 81 -267 0
-48 -4 -93 -9 -100 -5 -9 -25 -12 -61 -10 l-52 3 -18 70 c-27 106 -95 269
-114 273 -9 2 -16 13 -16 28 0 17 -6 24 -19 24 -18 0 -38 53 -71 190 -6 25
-18 63 -28 85 l-17 39 -6 -29 c-23 -106 -4 -202 71 -365 57 -124 82 -196 95
-277 7 -43 6 -43 -23 -43 -17 0 -41 4 -54 9 -36 13 -39 24 -155 436 -15 56
-18 212 -4 265 30 116 42 155 51 164 5 5 10 20 10 33 0 12 11 51 24 85 14 35
34 95 46 133 12 39 34 97 50 130 15 33 31 76 35 95 9 45 53 115 102 162 41 39
210 146 314 198 35 18 111 52 169 75 58 24 182 77 275 118 94 41 224 98 290
127 203 89 235 107 235 134 0 21 -6 24 -61 30 -88 10 -104 19 -191 102 -90 86
-196 158 -316 215 -90 42 -118 44 -108 6 3 -12 6 -30 6 -40 0 -10 11 -22 25
-27 14 -5 25 -16 25 -24 0 -19 85 -77 212 -145 54 -29 101 -57 104 -63 3 -5 3
-29 0 -52 -7 -43 -7 -44 -97 -85 -82 -39 -139 -63 -364 -156 -350 -144 -549
-278 -660 -445 -55 -84 -89 -164 -136 -325 -20 -72 -56 -180 -79 -240 -81
-213 -92 -260 -86 -360 3 -53 15 -124 30 -172 14 -46 39 -144 56 -220 17 -75
42 -162 56 -193 22 -50 32 -60 72 -78 67 -29 129 -34 240 -18 53 8 156 18 227
21 l131 7 13 -76 c20 -121 58 -239 122 -382 53 -119 149 -357 149 -370 0 -10
-95 8 -200 37 -272 74 -324 84 -520 94 -144 8 -236 -2 -425 -46 -200 -46 -213
-49 -248 -49 -17 0 -85 18 -150 40 -114 39 -123 40 -247 40 -72 0 -130 -2
-130 -4 0 -24 24 -39 98 -62 48 -14 138 -46 201 -71 161 -63 208 -65 381 -20
196 52 277 61 469 54 173 -6 355 -32 476 -67 126 -37 195 -50 259 -50 74 0 72
3 82 -120 6 -75 -27 -341 -45 -364 -17 -22 -41 -147 -40 -208 2 -153 -90 -306
-226 -375 -42 -22 -20 -20 -650 -53 -102 -6 -181 -14 -183 -20 -2 -6 -73 -10
-185 -9 -111 0 -174 4 -162 9 32 14 -81 11 -250 -5 -218 -21 -250 -20 -347 16
-46 17 -92 38 -103 48 -11 10 -36 26 -55 35 -32 15 -140 108 -140 121 0 3 -22
44 -49 93 -69 121 -92 207 -98 367 l-5 130 55 163 c79 233 137 320 247 370 46
22 76 27 195 33 103 5 163 14 225 32 254 75 515 133 707 158 141 18 287 8 418
-30 109 -31 293 -66 302 -57 3 2 -6 19 -18 36 -65 87 -392 180 -637 180 -85 0
-118 12 -136 50 -65 132 -94 192 -140 300 -30 69 -53 126 -51 128 2 2 42 12
89 22 105 23 142 42 150 76 4 14 4 29 1 32 -3 3 -72 1 -153 -6 -178 -14 -231
-6 -279 40 -39 38 -48 60 -34 86 11 21 20 24 240 77 80 19 155 42 167 50 25
16 35 66 18 89 -10 15 -15 14 -56 -4 -72 -31 -256 -72 -334 -73 -61 -1 -80 3
-137 31 -37 18 -67 37 -67 42 0 5 44 23 98 40 123 41 281 115 358 168 108 74
221 210 246 295 17 60 13 272 -6 348 -17 63 -50 129 -66 129 -17 0 -28 -75
-34 -225 -8 -213 -40 -308 -135 -401 -86 -84 -199 -143 -358 -185 -60 -16
-121 -22 -261 -26 l-183 -5 -15 -30 -15 -29 53 -23 c29 -13 64 -26 78 -29 44
-11 117 -64 152 -111 18 -25 40 -45 49 -46 9 0 23 -17 31 -39 26 -65 148 -240
184 -262 19 -11 34 -27 34 -35 0 -8 7 -14 15 -14 8 0 15 -6 15 -14 0 -8 7 -16
16 -18 8 -2 27 -30 41 -63 125 -297 142 -360 107 -403 -19 -22 -163 -67 -175
-54 -3 4 -14 45 -23 92 -10 47 -44 158 -76 247 -78 214 -144 325 -270 453
-132 134 -218 195 -308 222 -65 20 -72 25 -67 43 8 23 27 105 54 225 27 117
45 349 38 478 -4 86 -12 128 -41 216 -20 60 -46 124 -57 143 -22 35 -73 68
-89 58 -19 -12 -10 -112 15 -182 47 -130 57 -197 57 -383 1 -157 -2 -187 -26
-290 -35 -147 -92 -280 -170 -400 -96 -144 -102 -163 -68 -192 39 -34 50 -30
88 34 44 71 51 66 60 -43 7 -89 48 -245 112 -429 46 -133 47 -137 47 -260 -1
-153 -14 -189 -90 -236 -87 -55 -113 -82 -135 -142 -12 -31 -25 -61 -30 -67
-13 -16 -102 -312 -122 -410 -27 -124 -17 -191 58 -424 13 -40 36 -90 51 -110
22 -28 28 -46 27 -85 0 -31 -6 -53 -16 -60 -8 -6 -23 -27 -33 -46 -20 -40
-106 -127 -138 -139 -12 -5 -64 -14 -115 -21 -123 -16 -213 3 -257 55 -16 19
-105 67 -105 57 0 -6 -20 -4 -47 3 -27 7 -68 18 -93 24 -25 7 -65 16 -89 21
-45 10 -135 69 -145 96 -21 55 13 75 139 82 76 3 108 0 196 -23 90 -23 112
-25 146 -16 118 32 143 141 77 338 -20 60 -43 119 -52 133 -9 14 -19 43 -23
65 -5 22 -19 74 -32 115 -13 41 -32 115 -41 164 -9 49 -25 105 -35 125 -25 49
-67 247 -75 351 -4 46 -11 87 -15 90 -5 3 -11 55 -15 115 -4 61 -12 112 -17
113 -13 5 -12 459 1 467 6 3 10 18 10 33 0 48 39 215 51 223 9 5 10 35 6 106
-6 101 -24 168 -71 260 -24 49 -26 62 -26 185 0 174 23 356 62 493 27 96 40
197 26 210 -2 3 -29 -2 -59 -9 -30 -8 -57 -12 -61 -8 -4 4 -16 52 -27 107 -62
314 -23 495 152 712 38 47 61 62 232 149 l190 97 85 -6 c47 -3 121 -15 165
-27 121 -33 247 -41 410 -25 77 7 266 18 420 25 317 12 382 17 390 31 4 5 26
9 51 9 59 0 134 44 199 117 133 148 127 143 189 143 31 0 69 6 84 14 15 8 73
64 129 124 56 60 140 137 186 171 100 73 155 142 132 161 -13 10 -28 8 -83
-12 -96 -36 -143 -68 -203 -140 -49 -60 -125 -137 -198 -203 l-34 -30 6 65
c29 282 57 321 235 325 99 2 236 30 226 46 -3 5 9 9 27 9 17 0 64 12 103 26
39 14 100 32 136 41 66 16 213 32 240 27 8 -2 67 -6 130 -10z m-2450 -572 c12
-67 41 -123 80 -155 19 -16 30 -35 30 -51 0 -22 -5 -26 -30 -26 -16 0 -55 -7
-87 -15 -85 -22 -177 -19 -278 10 -48 14 -96 30 -107 36 -19 10 -19 11 -1 31
21 23 51 40 73 42 20 1 149 77 147 86 -3 11 106 97 128 102 28 6 33 -1 45 -60z
m35 -2594 c78 -39 165 -110 211 -171 20 -26 49 -54 64 -62 53 -27 142 -165
155 -240 4 -21 13 -44 20 -50 7 -5 36 -77 64 -158 40 -117 51 -162 51 -211 0
-70 -9 -87 -60 -106 -19 -8 -51 -24 -70 -36 -60 -38 -134 -51 -280 -50 l-135
1 -6 165 c-6 159 -16 227 -37 253 -15 19 -69 203 -88 302 -9 50 -22 93 -27 96
-12 8 1 266 15 292 12 24 41 18 123 -25z m3422 -1362 c50 -11 67 -20 95 -51
44 -50 57 -75 58 -107 0 -18 5 -28 15 -28 8 0 15 -7 15 -15 0 -15 22 -22 150
-51 89 -19 200 -69 200 -89 0 -20 116 -131 152 -146 15 -6 28 -19 28 -28 0
-10 15 -25 35 -34 21 -10 35 -24 35 -34 0 -10 9 -24 21 -31 11 -7 18 -19 16
-26 -3 -7 -1 -34 4 -61 14 -73 -3 -120 -67 -187 -30 -31 -57 -52 -60 -46 -3 5
-26 -20 -50 -57 -25 -36 -42 -70 -38 -76 3 -6 -3 -13 -14 -16 -11 -2 -37 -30
-58 -60 -41 -60 -83 -85 -162 -98 -23 -4 -40 -10 -37 -15 8 -13 -118 -21 -158
-9 -38 10 -135 87 -231 184 -40 39 -51 58 -52 84 -2 42 -34 74 -98 98 -69 26
-90 57 -94 146 -2 43 3 99 12 140 9 38 16 98 16 135 0 75 -25 298 -40 352 -8
30 -7 38 16 61 34 35 117 71 147 64 12 -3 34 -2 47 4 32 12 25 13 97 -3z"/>
<path d="M1406 7258 c-10 -57 -29 -150 -42 -208 -26 -115 -67 -350 -114 -650
-55 -349 -62 -839 -14 -1000 21 -73 31 -81 47 -39 10 24 16 109 21 299 3 146
11 319 16 385 26 313 32 372 39 405 l7 35 7 -41 c4 -24 14 -44 23 -48 10 -4
14 -12 10 -22 -4 -9 0 -21 9 -28 8 -6 19 -33 24 -60 5 -27 16 -53 25 -58 9 -5
16 -20 16 -34 0 -13 7 -27 15 -30 8 -4 15 -15 15 -25 0 -34 31 -98 51 -104 10
-4 19 -15 19 -26 0 -26 47 -119 64 -125 8 -3 21 -25 30 -48 9 -24 25 -51 35
-60 17 -16 21 -16 59 -1 l41 17 -104 208 c-121 246 -153 327 -188 475 -39 165
-48 262 -56 585 -5 252 -8 295 -21 298 -12 2 -19 -20 -34 -100z"/>
<path d="M3394 7241 c-58 -14 -259 -122 -291 -156 -18 -19 -33 -39 -33 -45 0
-17 44 -22 204 -18 126 2 159 6 166 18 15 24 30 80 37 143 5 48 3 57 -10 57
-8 0 -21 2 -29 4 -7 2 -27 1 -44 -3z"/>
<path d="M3015 6740 c-17 -4 -45 -14 -62 -24 -26 -13 -33 -23 -33 -46 0 -30 1
-30 55 -30 84 0 124 28 125 86 0 15 -46 22 -85 14z"/>
<path d="M3200 6440 c-81 -21 -326 -138 -353 -168 -9 -10 -18 -29 -19 -43 -5
-41 53 -38 173 11 142 57 222 73 339 64 88 -6 96 -5 114 15 15 16 17 29 12 65
-4 24 -14 50 -22 57 -26 22 -161 21 -244 -1z"/>
<path d="M4287 5975 c-16 -8 -70 -49 -120 -92 -106 -88 -190 -145 -297 -198
-41 -20 -77 -39 -79 -41 -2 -2 0 -15 3 -30 7 -26 9 -27 62 -21 84 9 182 64
339 190 134 109 194 172 178 188 -17 17 -59 19 -86 4z"/>
<path d="M2166 5461 c-3 -5 -3 -22 0 -39 6 -29 10 -31 148 -68 l141 -39 222 0
c220 0 222 0 247 24 14 14 26 27 26 31 0 21 -70 33 -235 41 -99 4 -216 15
-260 23 -44 8 -104 20 -134 26 -66 12 -148 13 -155 1z"/>
<path d="M2960 3874 c-68 -31 -92 -62 -98 -127 l-5 -50 60 5 c61 6 173 49 194
74 6 7 15 30 19 51 7 29 5 42 -7 55 -24 27 -96 23 -163 -8z"/>
<path d="M4665 3583 c18 -133 77 -259 134 -284 18 -8 31 -21 31 -31 0 -11 8
-18 20 -18 16 0 20 -7 20 -33 0 -73 89 -273 127 -288 38 -14 43 -11 43 24 0
97 -73 281 -145 367 -55 65 -78 105 -114 196 -28 69 -37 83 -67 97 -52 25 -56
23 -49 -30z"/>
<path d="M5580 3422 c-7 -15 -16 -85 -20 -157 -8 -146 -20 -189 -87 -314 -40
-75 -43 -85 -30 -99 14 -13 20 -11 55 16 79 63 135 170 167 325 18 81 18 110
5 175 -9 41 -16 51 -44 65 -33 15 -34 15 -46 -11z"/>
<path d="M2065 2688 c-49 -103 -119 -223 -204 -353 -36 -55 -75 -120 -86 -145
-11 -25 -22 -47 -26 -50 -3 -3 -14 -38 -24 -78 -26 -109 -18 -348 14 -414 13
-27 27 -48 31 -48 8 0 22 38 34 92 3 15 11 81 16 147 12 150 51 276 120 391
66 109 130 194 140 183 4 -4 31 -61 59 -125 29 -64 59 -119 67 -122 44 -17 57
74 28 206 -8 40 -26 142 -39 226 -13 84 -27 157 -30 162 -3 6 -19 10 -34 10
-24 0 -31 -9 -66 -82z"/>
<path d="M2387 1383 c22 -84 59 -153 83 -153 13 0 20 -7 20 -19 0 -10 9 -21
20 -24 11 -3 20 -12 20 -20 0 -15 89 -81 156 -115 105 -53 297 -75 424 -48 50
10 81 23 92 37 10 11 33 25 52 30 40 11 70 64 45 80 -25 15 -55 10 -125 -23
-155 -73 -372 -38 -561 90 -88 60 -157 126 -184 176 -14 26 -31 46 -41 46 -15
0 -15 -5 -1 -57z"/>
<path d="M4830 895 c-11 -14 -10 -98 2 -110 2 -3 19 -8 36 -11 l32 -6 0 61 c0
57 -2 62 -26 71 -32 12 -29 13 -44 -5z"/>
<path d="M5695 701 c-3 -6 -24 -20 -45 -31 -34 -18 -56 -20 -167 -18 -135 3
-149 0 -213 -51 -21 -17 -22 -21 -10 -37 14 -15 31 -16 193 -11 240 9 297 32
297 123 0 13 -4 24 -9 24 -5 0 -16 3 -24 6 -8 3 -18 0 -22 -5z"/>
<path d="M6324 1379 c2 -8 7 -26 10 -41 4 -18 13 -28 25 -28 13 0 20 -10 25
-30 3 -18 12 -30 21 -30 8 0 15 -9 15 -20 0 -13 7 -20 20 -20 11 0 20 -6 20
-14 0 -8 15 -24 34 -35 19 -12 36 -28 39 -35 3 -8 14 -13 24 -11 10 2 35 7 56
10 31 5 37 10 37 29 0 20 -8 26 -51 36 -38 9 -53 18 -59 36 -5 13 -14 24 -19
24 -6 0 -28 27 -51 59 -47 71 -46 69 -104 77 -37 5 -46 4 -42 -7z"/>
<path d="M6266 1145 c-12 -33 -5 -66 19 -87 14 -12 25 -31 25 -43 0 -44 85
-95 159 -95 34 0 42 5 60 34 24 38 26 46 10 46 -6 0 -42 9 -80 21 -54 16 -69
25 -69 40 0 26 -59 87 -91 94 -19 5 -28 2 -33 -10z"/>
<path d="M6120 1020 c-12 -23 -10 -28 34 -84 36 -45 73 -66 116 -66 27 0 30 3
30 33 0 25 -9 42 -38 70 -21 20 -46 37 -55 37 -9 0 -17 7 -17 15 0 24 -57 19
-70 -5z"/>
<path d="M5190 7540 c-24 -6 -25 -10 -24 -71 1 -82 51 -286 76 -309 10 -9 16
-24 13 -32 -4 -9 0 -18 9 -21 9 -4 12 -14 9 -26 -3 -13 -1 -21 7 -21 8 0 10
-8 6 -24 -4 -16 -1 -26 8 -29 8 -3 17 -21 21 -39 8 -39 40 -145 62 -204 8 -23
25 -47 37 -53 12 -7 27 -26 33 -42 9 -23 17 -29 42 -29 24 0 31 4 31 20 0 22
-43 156 -104 325 -42 118 -139 435 -134 440 7 7 224 -90 373 -165 337 -172
819 -494 1189 -795 72 -58 136 -105 143 -105 7 0 13 -9 13 -19 0 -12 44 -59
118 -124 64 -58 157 -150 206 -206 53 -61 96 -101 107 -101 12 0 19 -7 19 -20
0 -13 7 -20 20 -20 12 0 20 -7 20 -16 0 -14 101 -149 236 -314 52 -63 182
-268 225 -352 27 -54 32 -58 65 -58 l35 0 -6 48 c-15 107 -163 340 -431 672
-90 112 -544 570 -654 661 -135 111 -250 196 -402 299 -90 61 -226 155 -303
210 -196 139 -357 233 -606 354 -305 148 -397 181 -459 166z"/>
<path d="M4877 7345 c-50 -38 -109 -119 -202 -280 -65 -112 -129 -206 -188
-278 -43 -52 -40 -67 13 -67 52 0 87 38 245 261 87 123 160 226 162 229 3 3
15 -8 27 -23 23 -29 74 -67 89 -67 4 0 15 16 23 35 12 30 12 40 -2 82 -21 63
-38 95 -60 114 -37 33 -58 31 -107 -6z"/>
<path d="M6415 4012 c-21 -21 27 -214 59 -238 9 -6 14 -18 10 -28 -4 -10 0
-18 10 -22 9 -4 16 -18 16 -34 0 -16 7 -30 15 -34 8 -3 15 -16 15 -29 0 -14 7
-30 15 -37 8 -7 15 -21 15 -32 0 -32 41 -122 66 -143 13 -12 24 -31 24 -43 0
-13 7 -25 15 -28 8 -4 15 -16 15 -29 0 -28 46 -111 65 -119 9 -3 15 -18 15
-35 0 -16 6 -31 15 -35 8 -3 15 -12 15 -21 0 -8 4 -15 9 -15 5 0 12 -13 16
-29 3 -15 17 -38 30 -50 14 -11 25 -32 25 -46 0 -14 8 -29 20 -35 11 -6 20
-18 20 -26 0 -25 50 -103 69 -109 10 -3 23 -22 30 -43 6 -20 38 -75 71 -122
32 -47 92 -135 133 -195 41 -61 81 -116 90 -124 10 -7 17 -17 17 -22 0 -4 51
-78 113 -163 61 -85 146 -204 187 -263 65 -93 82 -111 127 -133 28 -14 52 -29
52 -35 1 -14 64 -115 72 -115 17 0 16 47 -2 95 -16 44 -167 273 -246 375 -44
56 -346 497 -459 670 -282 430 -424 701 -554 1055 -55 150 -83 209 -102 221
-16 10 -96 22 -103 16z"/>
</g>
</symbol>
</defs>
</svg>
</div>
</body>
<script src="scripts/app.js?TIMESTAMP"></script>
<script src="scripts/env.js"></script>
</html>

+ 19
- 0
frontend/src/scripts/UI/IntersectionObserver/footer.js Bestand weergeven

@ -0,0 +1,19 @@
// Create a function that will handle any intersection between some elements and the viewport.
const handleFooterIntersection = function (entries) {
// Loop through all the observed elements
for (let entry of entries) {
// Check if the element is intersecting the viewport
if (entry.isIntersecting) {
console.log("The footer is visible in the viewport");
if (typeof footerIsNowVisible === 'function') footerIsNowVisible(entry);
} else {
console.log("The footer is invisible in the viewport");
if (typeof footerIsNowInvisible === 'function') footerIsNowInvisible(entry);
}
}
}
const footer = document.querySelector("#footer");
if (footer) {
const footerObserver = new IntersectionObserver(handleFooterIntersection);
footerObserver.observe(footer);
}

+ 12
- 0
frontend/src/scripts/UI/IntersectionObserver/header.js Bestand weergeven

@ -0,0 +1,12 @@
const headerObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (typeof headerIsVisible === 'function') headerIsVisible(entry.isIntersecting);
});
});
const header = document.querySelector("header");
if (header) headerObserver.observe(header);
else myLog('No header to observe');

+ 17
- 0
frontend/src/scripts/UI/IntersectionObserver/synthesis.js Bestand weergeven

@ -0,0 +1,17 @@
const synthesisTopObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
// Check if the element is intersecting the viewport
if (entry.isIntersecting) {
myLog("The synthesis is visible in the viewport");
if (typeof synthesisTopIsNowVisible === 'function') synthesisTopIsNowVisible(entry);
} else {
myLog("The synthesis is invisible in the viewport");
if (typeof synthesisTopIsNowInvisible === 'function') synthesisTopIsNowInvisible(entry);
}
});
});
const synthesis_top = document.querySelector("#synthesis_top");
if (synthesis_top) synthesisTopObserver.observe(synthesis_top);
else myLog('No #synthesis_top to obseve');

+ 855
- 0
frontend/src/scripts/UI/calendrier.js Bestand weergeven

@ -0,0 +1,855 @@
// Affichage une colonne par intervenant
//function afficher_planning_atos_2(unModeAffichage) {
function ajouterClientColonne(client, colonne, indexCol) {
if (colonne[indexCol].indexOf(client) == -1) {
colonne[indexCol] += '/' + client;
}
}
datagrid_hooks['calendar_intervenants'] = function(){
let element = document.querySelector("#datagrid");
let filtre = getTrigrammeCollaborateur(getContexteValeur('intervenant'));
let lebreak = 0;
let annee = new Date().getFullYear();
let ladate = dateGetPrevMonday(new Date(annee, 0, 1));
let ladateToString;
let intervenants = [];
let jours_semaine = ["D", "L", "M", "M", "J", "V", "S"];
let lastWeekNumber = 99;
let tamponWeek = "";
let tamponWeekFlag = false;
let header = '';
let jours_feries = [];
let contenu = '';
// Tout le calendirer est encapsulé dans une cellule d'un tableau
// Permet de garantir le comportement du scroll avec le sticky des thead et tfoot
/*
contenu += '<table width="100vw">';
contenu += '<thead><tr><th>Calendrier</th></tr></thead>';
contenu += '<tr><td align="center" style="background:#aaaaaa">';
*/
sortItemsByStartDate();
setItemsVisibility();
if (getContexteValeur('debut'))
{
ladate = stringdateToDate(getContexteValeur('debut'));
ladate = dateGetPrevMonday(ladate);
}
ladateToString = formatDatetoStringDate(ladate);
// Se limiter à un an
annee = ladate.getFullYear() + 1;
annee += 1;
// Et à 2 ans si calendrier glissant
// TODO : ajouter un contexte qui indique si on est en calendrier annuel ou glissant
//if (select_date_debut == 2) annee += 1;
// Définir la liste des intervenants
items.forEach(element => {
let item = getItemFromElement(element);
let debut = item['debut'].substring(0,8);
let fin = item['fin'].substring(0,8);
// On ne s'occupe que des feuilles
if (item.childs.length != 0) return true;
// Au passage alimenter les jours fériés , mais ne pas les compter
if (item['client'] == 'FER') {
jours_feries.push(item['fin'].substring(0,8));
return true;
}
// On élimine ce qui est masqué
if (!item["visible"]) return true;
// On élimine les items non affectés
if (parseInt(item["intervenant"]) == 0) return true;
// Ne pas compter les Releases
if (item['client'] == 'REL') return true;
// Appliquer le filtre
if (filtre != 'ANO')
if (getTrigrammeCollaborateur(item['intervenant']) != filtre) return true;
// On ne compte pas ce qui n'est pas dans la période concernée
if (fin < ladateToString ) return true;
if (fin == '99999999' ) return true;
if (debut > (annee+'1231') ) return true;
if (intervenants.indexOf(item["intervenant"]) == -1) {
intervenants.push(item["intervenant"]);
}
});
intervenants.sort();
header += ' <th colspan="3">Calendrier</th>';
intervenants.forEach((intervenant) => {
let trigramme = getTrigrammeCollaborateur(intervenant);
header += '<th colspan="11"><center>' + trigramme + "</center></th>";
});
contenu += '<table width="100vw">';
contenu += " <thead><tr>" + header +"</tr></thead>";
contenu += " <tbody>";
let semaine_vide = "";
let semaine_paire = false;
let couleur = '';
semaine_vide += '<tr class="calendrier" style="background:#777777">';
semaine_vide += '<td width="30px" style="border-top:1px solid black;font-size:2vh">SXX</td>';
semaine_vide += '<td colspan="' + ( 2 + (11 * intervenants.length)) + '" align="center" style="border-top:1px solid black;font-size:2vh">&nbsp;</td>';
semaine_vide += "</tr>";
while (annee > ladate.getFullYear()) {
let bgcolor = "white";
let font_weight = 'normal';
let jour = ladate.getDay();
let jour_courant = formatDatetoStringDate(ladate);
let weekNumber = stringdateGetWeekOfYear(jour_courant)%100;
let colonnes = [];
let colonnes_bw = []; // Before Work
let colonnes_am = []; // Matin
let colonnes_md = []; // Midi
let colonnes_pm = []; // Après-Midi
let colonnes_aw = []; // After Work
let style_tr = '';
let style_td = '';
let jour_libelle = '';
intervenants.forEach((intervenant) => {
colonnes.push("");
colonnes_bw.push("");
colonnes_am.push("");
colonnes_md.push("");
colonnes_pm.push("");
colonnes_aw.push("");
});
// On change de semaine
// Si la semaine est vide, tamponWeekFlag == false
if (weekNumber != lastWeekNumber) {
let semaine = '';
if (lastWeekNumber != 99) semaine = semaine_vide.replace("SXX", "S" + stringDatePadDigits(lastWeekNumber,2));
if (tamponWeekFlag) {
semaine = tamponWeek;
semaine_paire = !semaine_paire;
}
contenu += semaine;
tamponWeek = "";
tamponWeekFlag = false;
}
// Couleur pour les samedi et dimanche
if (jour == 0 || jour == 6) bgcolor = "#f1d4af";
// Couleur pour les lundi et vendredi
if (jour == 1 || jour == 5) bgcolor = "#eeeeee";
// Couleur pour les jours fériés
if (jours_feries.includes(jour_courant)) bgcolor = "#f1d4af";
// Couleur d'aujourd'hui
if (jour_courant == todayStringDate){
bgcolor='#87cefa';
font_weight='bold';
tamponWeekFlag = true;
}
items.forEach((element) => {
let item = getItemFromElement(element);
let debut = item["debut"];
let fin = item["fin"];
let jour_debut;
let jour_fin;
let ajout = false;
if (isDebugItem(item)){
myLog('item ICI');
}
if (!item["visible"]) return true; // Invisible
if (item["intervenant"] == 0) return true; // Non affecté
if (item.childs.length != 0) return true; // Noeud
if ((fin.substring(8,12) == '0000')||(fin.substring(8,12) == '9999')) fin = fin.substring(0,8)+'2000';
if (item['type'] == 'TODO') debut = fin; // Un TODO est un jalon
jour_debut = debut.substring(0,8);
jour_fin = fin.substring(0,8);
// if (jour_debut > jour_courant) return false;
// Ceci n'est pas réellement planifié
if ((jour_debut == '00000000') && (jour_fin.substring(0,8) == (1+parseInt(todayStringDate.substring(0,4))+'1231'))) {
return true;
}
// L'item débute ou finit le jour courant
if (jour_debut == jour_courant) ajout = true;
if (jour_fin == jour_courant) ajout = true;
// Le jour courant est entièrement contenu dans l'item
if (jour_debut < jour_courant && jour_fin > jour_courant) ajout = true;
if (ajout) {
let indexCol = intervenants.indexOf(item["intervenant"]);
let client = item["client"];
let horaire_debut = 0;
let horaire_fin = 20;
let colonne = null;
tamponWeekFlag = true;
if (jour_courant == jour_debut) horaire_debut = parseInt(debut.substring(8, 10));
if (jour_courant == jour_fin) horaire_fin = parseInt(fin.substring(8, 10));
// Pour les releases et les jour fériés, on affiche le libellé
if ((client == 'REL')||(client == 'FER')) {
jour_libelle = item['libelle'];
return true;
}
if (client == 'REL') return true;
if (client == 'FER') return true;
//if (client == "ABS") bgcolor = "#f1d4af";
//if (client == "CGI") font_weight += ";color:blue";
if (indexCol == -1) {
myLog(item["intervenant"] + " inconnu");
return true;
}
if ((horaire_debut <= 9) && (horaire_fin<=9)) ajouterClientColonne(client, colonnes_bw, indexCol);
if ((horaire_debut >= 12) && (horaire_fin<=14)) ajouterClientColonne(client, colonnes_md, indexCol);
if ((horaire_debut >= 17) && (horaire_fin<=21)) ajouterClientColonne(client, colonnes_aw, indexCol);
if ((horaire_debut < 12) && (horaire_fin > 9)) ajouterClientColonne(client, colonnes_am, indexCol);
if ((horaire_debut < 17) && (horaire_fin > 14)) ajouterClientColonne(client ,colonnes_pm, indexCol);
}
});
style_tr = 'background:'+bgcolor+';font-weight:'+font_weight;
tamponWeek += '<tr style="'+style_tr+'" class="js-open-modal-trigger" data-modal-info="type=calendrier:jour=' + jour_courant + '">';
if (weekNumber != lastWeekNumber) {
if (semaine_paire) couleur = '#eeeeee';
else couleur = 'white';
lastWeekNumber = weekNumber;
/*
tamponWeek += '<td class="calendrier" width="10px" style="font-family: fixed; width: 30px;background: ' + couleur + '; font-weight: bold" rowspan="7" align="center">';
tamponWeek += "S" + lastWeekNumber.toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += "</td>";
*/
}
if (jour == 1) style_td = 'border-top:1px solid black'; // Le lundi
tamponWeek += '<td style="font-family: fixed; width: 30px; background:'+couleur+';text-align:center;border-right:1px solid;font-size:2vh;'+style_td+'">';
if (jour == 4) tamponWeek += 'S'+lastWeekNumber.toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += '&nbsp;</td>';
tamponWeek += '<td style="font-family: fixed;font-size:2vh; width: 20px;background:'+bgcolor+';font-weight:bold;'+style_td+'">'+jours_semaine[jour]+'</td>';
if (jour_libelle != '' ) {
tamponWeek += '<td style="font-family: fixed;font-size:2vh;width:80px;background:'+bgcolor+';color:red;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-right:1px solid black;'+style_td+'"><small>'+ jour_libelle +'</small></td>';
} else {
tamponWeek += '<td style="font-family: fixed;font-size:2vh;width: 80px;background:'+bgcolor+';font-weight:bold;border-right:1px solid;'+style_td+'">';
tamponWeek +=
ladate.getDate().toLocaleString(undefined, { minimumIntegerDigits: 2 }) +
" / " +
(ladate.getMonth() + 1).toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += "</td>";
}
intervenants.forEach((intervenant) => {
let index = intervenants.indexOf(intervenant);
let aligne = "center";
let colonne = colonnes[index].substring(1);
let colonne_bw = colonnes_bw[index];
let colonne_am = colonnes_am[index];
let colonne_md = colonnes_md[index];
let colonne_pm = colonnes_pm[index];
let colonne_aw = colonnes_aw[index];
let style_am = "";
let style_pm = "";
let style_tr_td = "";
// if (colonne_bw != '' || colonne_am != '' || colonne_md != '' || colonne_pm != '' || colonne_aw != '') {
//tamponWeekFlag = true;
if (colonne != '') {
let tempo = colonne.replace('</span>','');
let valeurs = tempo.split('/');
valeurs.forEach(valeur => {
if (!colonne_am.includes(valeur)) colonne_am += '/'+valeur+'</span>';
if (!colonne_pm.includes(valeur)) colonne_pm += '/'+valeur+'</span>';
// if (!colonne_aw.includes(valeur)) colonne_aw += '/'+valeur+'</span>';
})
}
colonne_bw = colonne_bw.substring(1);
colonne_am = colonne_am.substring(1);
colonne_md = colonne_md.substring(1);
colonne_pm = colonne_pm.substring(1);
colonne_aw = colonne_aw.substring(1);
if (jour == 0 || jour ==6) {
colonne_bw = "";
colonne_am = "";
colonne_md = "";
colonne_pm = "";
colonne_aw = "";
}
style_tr = 'overflow: hidden;white-space: nowrap;text-overflow:ellipsis';
style_tr += ';border-color:black;border-width:1px';
style_tr += ';padding-left: 5px; padding-right: 5px';
style_tr += ';background:' + bgcolor;
style_tr_td = style_tr+";"+style_td;
if (colonne_am.includes("ABS")) style_am+=";background:#f004";
if (colonne_pm.includes("ABS")) style_pm+=";background:#f004";
if (colonne_am.includes("CGI")) style_am+=";color:blue";
if (colonne_pm.includes("CGI")) style_pm+=";color:blue";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5" align="' + aligne + '"><center>' + colonne_bw + "</center></td>";
tamponWeek += '<td colspan="4" style="width:80px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_tr_td+';'+style_am + '"' + aligne + '"><center>' + colonne_am + "</center></td>";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5" align="' + aligne + '"><center>' + colonne_md + "</center></td>";
tamponWeek += '<td colspan="4" style="width:80px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_tr_td+';'+style_pm+ ';" align="' + aligne + '"><center>' + colonne_pm + "</center></td>";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5;border-right: 1px solid" align="' + aligne + '"><center>' + colonne_aw + "</center></td>";
/*} else {
//if (colonne != '') tamponWeekFlag = true;
tamponWeek += '<td colspan="5" style="background:' + bgcolor + ';min-width: 60px;padding-left: 5px; padding-right: 5px" align="' + aligne + '"><center>' + colonne + "</center></td>";
}
*/
});
tamponWeek += "</tr>";
// Pour ne pas boucler indéfiniment
if (++lebreak > 400) break;
/*
if (select_date_debut == 1) {
// Planning glissant
// Stop au dimanche suivant anniversaire
if (intJourCourant > intValToDay + 10000) if (jour == 0) break;
}
*/
ladate.setDate(ladate.getDate() + 1);
}
contenu += tamponWeek;
contenu += " <tfoot><tr>" + header +"</tr></tfoot>";
contenu += "</table>";
/*
contenu += "</td></tr>";
contenu += "<tfoot><tr><th>Calendrier</th></tr></tfoot>";
contenu += "</table>";
*/
//element.innerHTML = '<div align="center" style="background:#aaaaaa">'+contenu+'</div>';
element.innerHTML = contenu;
}
datagrid_hooks['calendar_clients'] = function(){
let element = document.querySelector("#datagrid");
let filtre = getContexteValeur('client');
let lebreak = 0;
let annee = new Date().getFullYear();
let ladate = dateGetPrevMonday(new Date(annee, 0, 1));
let ladateToString;
let entetes = [];
let jours_semaine = ["D", "L", "M", "M", "J", "V", "S"];
let lastWeekNumber = 99;
let tamponWeek = "";
let tamponWeekFlag = false;
let header = '';
let jours_feries = [];
let contenu = '';
sortItemsByStartDate();
setItemsVisibility();
if (getContexteValeur('debut'))
{
ladate = stringdateToDate(getContexteValeur('debut'));
ladate = dateGetPrevMonday(ladate);
}
ladateToString = formatDatetoStringDate(ladate);
// Se limiter à un an
annee = ladate.getFullYear() + 1;
annee += 1;
// Et à 2 ans si calendrier glissant
// TODO : ajouter un contexte qui indique si on est en calendrier annuel ou glissant
//if (select_date_debut == 2) annee += 1;
// Définir la liste des intervenants
items.forEach(element => {
let item = getItemFromElement(element);
let debut = item['debut'].substring(0,8);
let fin = item['fin'].substring(0,8);
// On ne s'occupe que des feuilles
if (item.childs.length != 0) return true;
// Au passage alimenter les jours fériés , mais ne pas les compter
if (item['client'] == 'FER') {
jours_feries.push(item['fin'].substring(0,8));
return true;
}
// Ne pas compter les Releases
if (item['client'] == 'REL') return true;
if (filtre != '')
if (item['client'] != filtre) return true;
// On élimine ce qui est masqué
if (!item["visible"]) return true;
// On élimine les items non affectés
if (parseInt(item["client"]) == 0) return true;
// On ne compte pas ce qui n'est pas dans la période concernée
if (fin < ladateToString ) return true;
if (fin == '99999999' ) return true;
if (debut > (annee+'1231') ) return true;
if (entetes.indexOf(item['client']) == -1) {
entetes.push(item['client']);
}
});
entetes.sort();
header += ' <th colspan="3">Calendrier</th>';
entetes.forEach((entete) => {
header += '<th colspan="11"><center>' + entete + "</center></th>";
});
contenu += '<table width="100vw">';
contenu += " <thead><tr>" + header +"</tr></thead>";
contenu += " <tbody>";
let semaine_vide = "";
let semaine_paire = false;
let couleur = '';
semaine_vide += '<tr class="calendrier" style="background:#777777">';
semaine_vide += '<td width="30px" style="border-top:1px solid black;font-size:2vh">SXX</td>';
semaine_vide += '<td colspan="' + ( 2 + (11 * entetes.length)) + '" align="center" style="border-top:1px solid black;font-size:2vh">&nbsp;</td>';
semaine_vide += "</tr>";
while (annee > ladate.getFullYear()) {
let bgcolor = "white";
let font_weight = 'normal';
let jour = ladate.getDay();
let jour_courant = formatDatetoStringDate(ladate);
let weekNumber = stringdateGetWeekOfYear(jour_courant)%100;
let colonnes = [];
let colonnes_bw = []; // Before Work
let colonnes_am = []; // Matin
let colonnes_md = []; // Midi
let colonnes_pm = []; // Après-Midi
let colonnes_aw = []; // After Work
let style_tr = '';
let style_td = '';
let jour_libelle = '';
entetes.forEach((intervenant) => {
colonnes.push("");
colonnes_bw.push("");
colonnes_am.push("");
colonnes_md.push("");
colonnes_pm.push("");
colonnes_aw.push("");
});
// On change de semaine
// Si la semaine est vide, tamponWeekFlag == false
if (weekNumber != lastWeekNumber) {
let semaine = '';
if (lastWeekNumber != 99) semaine = semaine_vide.replace("SXX", "S" + stringDatePadDigits(lastWeekNumber,2));
if (tamponWeekFlag) {
semaine = tamponWeek;
semaine_paire = !semaine_paire;
}
contenu += semaine;
tamponWeek = "";
tamponWeekFlag = false;
}
// Couleur pour les samedi et dimanche
if (jour == 0 || jour == 6) bgcolor = "#f1d4af";
// Couleur pour les lundi et vendredi
if (jour == 1 || jour == 5) bgcolor = "#eeeeee";
// Couleur pour les jours fériés
if (jours_feries.includes(jour_courant)) bgcolor = "#f1d4af";
// Couleur d'aujourd'hui
if (jour_courant == todayStringDate){
bgcolor='#87cefa';
font_weight='bold';
tamponWeekFlag = true;
}
items.forEach((element) => {
let item = getItemFromElement(element);
let debut = item["debut"];
let fin = item["fin"];
let jour_debut;
let jour_fin;
let ajout = false;
if (isDebugItem(item)){
myLog('item ICI');
}
if (!item["visible"]) return true; // Invisible
if (item["client"] == 0) return true; // Non affecté
if (item.childs.length != 0) return true; // Noeud
if ((fin.substring(8,12) == '0000')||(fin.substring(8,12) == '9999')) fin = fin.substring(0,8)+'2000';
if (item['type'] == 'TODO') debut = fin; // Un TODO est un jalon
jour_debut = debut.substring(0,8);
jour_fin = fin.substring(0,8);
// if (jour_debut > jour_courant) return false;
// Ceci n'est pas réellement planifié
if ((jour_debut == '00000000') && (jour_fin.substring(0,8) == (1+parseInt(todayStringDate.substring(0,4))+'1231'))) {
return true;
}
// L'item débute ou finit le jour courant
if (jour_debut == jour_courant) ajout = true;
if (jour_fin == jour_courant) ajout = true;
// Le jour courant est entièrement contenu dans l'item
if (jour_debut < jour_courant && jour_fin > jour_courant) ajout = true;
if (ajout) {
let indexCol = entetes.indexOf(item["client"]);
let intervenant = getTrigrammeCollaborateur(item["intervenant"]);
let client = item["client"];
let horaire_debut = 0;
let horaire_fin = 20;
let colonne = null;
tamponWeekFlag = true;
if (jour_courant == jour_debut) horaire_debut = parseInt(debut.substring(8, 10));
if (jour_courant == jour_fin) horaire_fin = parseInt(fin.substring(8, 10));
// Pour les releases et les jour fériés, on affiche le libellé
if ((client == 'REL')||(client == 'FER')) {
jour_libelle = item['libelle'];
return true;
}
if (client == 'REL') return true;
if (client == 'FER') return true;
if (client == "ABS") bgcolor = "#f1d4af";
if (client == "CGI") font_weight += ";color:blue";
if (indexCol == -1) {
myLog(item["client"] + " inconnu");
return true;
}
if ((horaire_debut <= 9) && (horaire_fin<=9)) ajouterClientColonne(intervenant, colonnes_bw, indexCol);
if ((horaire_debut >= 12) && (horaire_fin<=14)) ajouterClientColonne(intervenant, colonnes_md, indexCol);
if ((horaire_debut >= 17) && (horaire_fin<=21)) ajouterClientColonne(intervenant, colonnes_aw, indexCol);
if ((horaire_debut < 12) && (horaire_fin > 9)) ajouterClientColonne(intervenant, colonnes_am, indexCol);
if ((horaire_debut < 17) && (horaire_fin > 14)) ajouterClientColonne(intervenant ,colonnes_pm, indexCol);
}
});
style_tr = 'background:'+bgcolor+';font-weight:'+font_weight;
tamponWeek += '<tr style="'+style_tr+'" class="js-open-modal-trigger" data-modal-info="type=calendrier:jour=' + jour_courant + '">';
if (weekNumber != lastWeekNumber) {
if (semaine_paire) couleur = '#eeeeee';
else couleur = 'white';
lastWeekNumber = weekNumber;
/*
tamponWeek += '<td class="calendrier" width="10px" style="font-family: fixed; width: 30px;background: ' + couleur + '; font-weight: bold" rowspan="7" align="center">';
tamponWeek += "S" + lastWeekNumber.toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += "</td>";
*/
}
if (jour == 1) style_td = 'border-top:1px solid black'; // Le lundi
tamponWeek += '<td style="font-family: fixed; width: 30px; background:'+couleur+';text-align:center;border-right:1px solid;font-size:2vh;'+style_td+'">';
if (jour == 4) tamponWeek += 'S'+lastWeekNumber.toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += '&nbsp;</td>';
tamponWeek += '<td style="font-family: fixed;font-size:2vh; width: 20px;background:'+bgcolor+';font-weight:bold;'+style_td+'">'+jours_semaine[jour]+'</td>';
if (jour_libelle != '' ) {
tamponWeek += '<td style="font-family: fixed;font-size:2vh;width:80px;background:'+bgcolor+';color:red;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-right:1px solid black;'+style_td+'"><small>'+ jour_libelle +'</small></td>';
} else {
tamponWeek += '<td style="font-family: fixed;font-size:2vh;width: 80px;background:'+bgcolor+';font-weight:bold;border-right:1px solid;'+style_td+'">';
tamponWeek +=
ladate.getDate().toLocaleString(undefined, { minimumIntegerDigits: 2 }) +
" / " +
(ladate.getMonth() + 1).toLocaleString(undefined, { minimumIntegerDigits: 2 });
tamponWeek += "</td>";
}
entetes.forEach((entete) => {
let index = entetes.indexOf(entete);
let aligne = "center";
let colonne = colonnes[index].substring(1);
let colonne_bw = colonnes_bw[index];
let colonne_am = colonnes_am[index];
let colonne_md = colonnes_md[index];
let colonne_pm = colonnes_pm[index];
let colonne_aw = colonnes_aw[index];
// if (colonne_bw != '' || colonne_am != '' || colonne_md != '' || colonne_pm != '' || colonne_aw != '') {
//tamponWeekFlag = true;
if (colonne != '') {
let tempo = colonne.replace('</span>','');
let valeurs = tempo.split('/');
valeurs.forEach(valeur => {
if (!colonne_am.includes(valeur)) colonne_am += '/'+valeur+'</span>';
if (!colonne_pm.includes(valeur)) colonne_pm += '/'+valeur+'</span>';
// if (!colonne_aw.includes(valeur)) colonne_aw += '/'+valeur+'</span>';
})
}
colonne_bw = colonne_bw.substring(1);
colonne_am = colonne_am.substring(1);
colonne_md = colonne_md.substring(1);
colonne_pm = colonne_pm.substring(1);
colonne_aw = colonne_aw.substring(1);
style_tr = 'overflow: hidden;white-space: nowrap;text-overflow:ellipsis';
style_tr += ';border-color:black;border-width:1px';
style_tr += ';padding-left: 5px; padding-right: 5px';
style_tr += ';background:' + bgcolor;
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5" align="' + aligne + '"><center>' + colonne_bw + "</center></td>";
tamponWeek += '<td colspan="4" style="width:80px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_tr+';'+style_td + '"' + aligne + '"><center>' + colonne_am + "</center></td>";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5" align="' + aligne + '"><center>' + colonne_md + "</center></td>";
tamponWeek += '<td colspan="4" style="width:80px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_tr+';'+style_td + ';" align="' + aligne + '"><center>' + colonne_pm + "</center></td>";
tamponWeek += '<td style="width:40px;font-size:2vh;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' + style_td + ';opacity:0.5;border-right: 1px solid" align="' + aligne + '"><center>' + colonne_aw + "</center></td>";
/*} else {
//if (colonne != '') tamponWeekFlag = true;
tamponWeek += '<td colspan="5" style="background:' + bgcolor + ';min-width: 60px;padding-left: 5px; padding-right: 5px" align="' + aligne + '"><center>' + colonne + "</center></td>";
}
*/
});
tamponWeek += "</tr>";
// Pour ne pas boucler indéfiniment
if (++lebreak > 400) break;
/*
if (select_date_debut == 1) {
// Planning glissant
// Stop au dimanche suivant anniversaire
if (intJourCourant > intValToDay + 10000) if (jour == 0) break;
}
*/
ladate.setDate(ladate.getDate() + 1);
}
contenu += tamponWeek;
contenu += " <tfoot><tr>" + header +"</tr></tfoot>";
contenu += "</table>";
element.innerHTML = contenu;
}
modal_hooks['calendrier'] = function(parametres){
let jour_courant='00000000';
let paramSplit = parametres.split(':');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0]==='jour') jourInfo(elemSplit[1].substring(0,8));
});
};
function testDateItem(item, jour_courant)
{
let retour = false;
let jour_debut = item["debut"].substring(0,8);
let jour_fin = item["fin"].substring(0,8);
// Les TODO sont des jalons
if (item['type']=='TODO') jour_debut = jour_fin;
// Se limiter aux items réellement entièrement plannifiés
if ((jour_debut != '00000000') && (jour_fin != (1+parseInt(todayStringDate.substring(0,4))+'1231'))) {
// L'item débute ou finit le jour courant
if (jour_debut == jour_courant) retour = true;
if (jour_fin == jour_courant) retour = true;
// Le jour courant est entièrement contenu dans l'item
if (jour_debut < jour_courant && jour_fin > jour_courant) retour = true;
}
return retour;
}
function jourInfo(jour_courant) {
let modal_header='Détail <b>'+formatLocaleDateFromStringDate(jour_courant)+'</b>';
let modal_body='TODO inconnu !';
let modal_footer='';
let start = 7; // Mettre un contexte ...
let finish = 14; // Mettre un contexte ...
let horaires = [];
for(i=0;i<finish;i++){
horaires[(i*2)] = '';
horaires[(i*2)+1] = '';
}
items.forEach(element => {
let resultat = getItemFromElement(element);
let debut = resultat["debut"];
let fin = resultat["fin"];
let jour_debut;
let jour_fin;
let heure_debut;
let heure_fin;
if (isDebugItem(resultat)){
myLog('item ICI');
}
// L'item concerne-t-il bien la date courante ?
if (!testDateItem(resultat, jour_courant)) return true;
heure_fin=fin.substring(8,12);
if (heure_fin =='0000') fin=fin.substring(0,8)+'2000';
// Les TODO sont des jalons
if (resultat.type=='TODO') debut = fin;
jour_debut = debut.substring(0,8);
jour_fin = fin.substring(0,8);
heure_debut = parseInt(debut.substring(8,12));
heure_fin = parseInt(fin.substring(8,12));
// L'item commence avant le jour courant
if (jour_debut < jour_courant) heure_debut = '0900';
// L'item termine après le jour courant
if (jour_fin > jour_courant) heure_fin = '1800';
// Recalibrer les heures de debut et de fin
if (heure_debut=='0000') heure_debut='0900';
if (heure_fin=='0000') heure_fin='2000';
for(i=0;i<finish;i++) {
let cur_debut, cur_fin;
let flag;
cur_debut = parseInt((start+i)+'00');
cur_fin = parseInt((start+i)+'30');
flag = false;
if ((heure_debut <= cur_debut)&&(heure_fin >= cur_fin)) flag = true;
if ((heure_debut >= cur_debut)&&(heure_fin <= cur_fin)) flag = true;
if ((heure_debut == heure_fin)&&(heure_fin == cur_fin)) flag = false;
// Cas particulier de la pause de midi
if (cur_debut == '1300')
if ((heure_debut<'1230')&&(heure_fin>'1330')) flag = false;
if (flag) horaires[(i*2)] += resultat.libelle+'<br>';
cur_debut = parseInt((start+i)+'30');
cur_fin = parseInt((start+i)+1+'00');
flag = false;
if ((heure_debut <= cur_debut)&&(heure_fin >= cur_fin)) flag = true;
if ((heure_debut >= cur_debut)&&(heure_fin <= cur_fin)) flag = true;
if ((heure_debut == heure_fin)&&(heure_fin == cur_fin)) flag = false;
// Cas particulier de la pause de midi
if (cur_debut == '1230')
if ((heure_debut<'1230')&&(heure_fin>'1330')) flag = false;
if (flag) horaires[(i*2)+1] += resultat.libelle+'<br>';
}
});
modal_body = '<table class="modal_table">';
for(i=0;i<finish;i++) {
let debut;
let fin;
let style_tr;
debut = stringDatePadDigits((i+start),2)+':00';
fin = stringDatePadDigits((i+start),2)+':30';
style_tr=' class="tr1"';
if (debut < '09:00') style_tr=' class="tr2"';
if (fin > '18:00') style_tr=' class="tr2"';
if (debut == '13:00') style_tr=' class="tr2"';
modal_body += '<tr'+style_tr+'>';
modal_body += '<td style="width:40px">'+debut+' - '+fin+'</td>';
modal_body += '<td>'+horaires[i*2]+'</td></tr>';
modal_body += '</tr>';
debut = stringDatePadDigits((i+start),2)+':30';
fin = stringDatePadDigits((i+start)+1,2)+':00';
style_tr=' class="tr1"';
if (debut < '09:00') style_tr=' class="tr2"';
if (fin > '18:00') style_tr=' class="tr2"';
if (debut == '12:30') style_tr=' class="tr2"';
modal_body += '<tr'+style_tr+'>';
modal_body += '<td style="width:40px">'+debut+' - '+fin+'</td>';
modal_body += '<td>'+horaires[(i*2)+1]+'</td></tr>';
modal_body += '</tr>';
}
modal_body += '</table>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}

+ 147
- 0
frontend/src/scripts/UI/datagrid.js Bestand weergeven

@ -0,0 +1,147 @@
// ---------------------------------------------------------------------------------------
// ---- Fonctions pour charger des lignes identiques dans le tableau
// ---------------------------------------------------------------------------------------
function datagridLignesIdentiques(nblignes, valeur) {
let element = document.querySelector('#datagrid');
let contenu='';
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
for(let i=0; i<nblignes; i++)
{
contenu += ' <tr>';
contenu += ' <td align="center">'+valeur+'</td>';
contenu += ' </tr>';
}
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th>&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
}
// ---------------------------------------------------------------------------------------
// ---- Fonctions pour charger des lignes vides
// ---------------------------------------------------------------------------------------
function datagridEmptyLines(nblignes) {
return datagridLignesIdentiques(nblignes,'&nbsp;');
}
// ---------------------------------------------------------------------------------------
// ---- Fonctions utilitaires
// ---------------------------------------------------------------------------------------
function datagridLoading() {
let nblignes = 25 + Math.floor(Math.random() * 475); // Nbre entre ntre 25 et 500
return datagridLignesIdentiques(nblignes, 'Loading data ..');
}
// ---------------------------------------------------------------------------------------
// ---- Fonctions pour charger des données au hasard dans le datagrid
// ---------------------------------------------------------------------------------------
var nbCols = 5;
function setDatagridRandomValues(element, nbcols, nblignes)
{
let contenu='';
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>ID HEAD</th>';
for(let i= 0; i<nbcols; i++)
{
contenu += ' <th>HEAD'+i+'</th>';
}
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
for(let i=0; i<nblignes; i++)
{
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="random:idligne='+i+'">';
contenu += ' <td>ID</td>';
for(let ii= 0; ii<nbcols; ii++)
{
contenu += ' <td> VALUE '+i+' '+ii+'</td>';
}
contenu += ' </tr>';
}
// Rejouter 2 lignes vides
for(let i=0; i<2; i++)
{
contenu += ' <tr>';
contenu += ' <td>&nbsp;</td>';
for(let ii= 0; ii<nbcols; ii++)
{
contenu += ' <td>&nbsp;</td>';
}
contenu += ' </tr>';
}
contenu += ' </body>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th>ID FOOT</th>';
for(let i= 0; i<nbcols; i++)
{
contenu += ' <th>FOOT'+i+'</th>';
}
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
init_modal();
nbCols = nbcols;
}
modal_hooks['random'] = function(parametres){
let paramSplit = parametres.split(',');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'idligne') {
let ligne = elemSplit[1];
let modal_header='Détail de la ligne '+ligne;
let modal_body='';
let modal_footer='<button>Enregistrer</button';
modal_body += '<table class="modal_table">';
for(i=0;i<nbCols; i++)
{
modal_body += '<tr>';
modal_body += '<td> PARAM '+i+'</td>';
modal_body += '<td> VALUE '+ligne+' '+i+'</td>';
modal_body += '</tr>';
}
modal_body += '</table>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
});
};
// --------------------------------------------------------------------------------------------
// ---- Tableau de hooks pour alimenter le datagrid
// --------------------------------------------------------------------------------------------
var datagrid_hooks = [];
datagrid_hooks['random'] = function(){
let element = document.querySelector('#datagrid');
let nblignes = 25 + Math.floor(Math.random() * 475); // Nbre entre ntre 25 et 500
setDatagridRandomValues(element, nbCols, nblignes)
};

+ 154
- 0
frontend/src/scripts/UI/modal.js Bestand weergeven

@ -0,0 +1,154 @@
class Modal {
// TODO : industrialiser en créant une classe
}
const modalDialog = document.getElementById('fiche');
var modal_hooks = [];
function disableScrolling(){
/*
document.body.style.position = 'fixed';
document.body.style.top = `-${window.scrollY}px`;
*/
/*
var x=window.scrollX;
var y=window.scrollY;
window.onscroll=function(){window.scrollTo(x, y);};
*/
// Ne marche pas :
// supprime la scrollbar (déplacement du body vers la droite)
// document.body.style.overflow='hidden';
// Ne marche pas :
// la modal ne propage pas le scroll
// modalDialog.scroll = function(e) {e.stopPropagation();}
}
function enableScrolling(){
/*
const scrollY = document.body.style.top;
document.body.style.position = '';
document.body.style.top = '';
window.scrollTo(0, parseInt(scrollY || '0') * -1);
*/
// Ne marche pas :
// au retour, certains élements de la page ne sont plus clickables
//document.body.style.overflow='scroll';
// window.onscroll=function(){};
}
function showDialog(){
modalDialog.showModal();
disableScrolling()
}
function show_modal(data_modal) {
showDialog();
if (typeof open_modal_hook === 'function') open_modal_hook(data_modal);
};
function close_modal()
{
modalDialog.close();
enableScrolling();
}
function init_modal()
{
let testElements = document.getElementsByClassName('js-open-modal-trigger');
let testDivs = Array.prototype.filter.call(testElements, function(testElement){
return true;
});
testDivs.forEach(function(item){
item.onclick = function(ev) {
show_modal(this.getAttribute("data-modal-info"));
};
});
testElements = document.getElementsByClassName('js-close-modal-trigger');
testDivs = Array.prototype.filter.call(testElements, function(testElement){
return true;
});
testDivs.forEach(function(item){
item.onclick = function(ev) {
close_modal(this.getAttribute("data-modal-info"));
};
});
return true;
}
function close_modal_hook()
{
console.log("close_modal_hook");
modalSetInnerHtml('modal_header', '');
modalSetInnerHtml('modal_body', '');
modalSetInnerHtml('modal_footer', '');
}
function modalSetInnerHtml(className, valeur)
{
var testElements = document.getElementsByClassName(className);
var testDivs = Array.prototype.filter.call(testElements, function(testElement){
return true;
});
testDivs.forEach(function(element){
element.scrollTop = 0;
element.innerHTML = valeur;
});
}
function modalSetChildren(className, children)
{
var testElements = document.getElementsByClassName(className);
var testDivs = Array.prototype.filter.call(testElements, function(testElement){
return true;
});
modalSetInnerHtml(className, '');
testDivs.forEach(function(element){
element.scrollTop = 0;
element.appendChild(children);
});
}
function modalSetHeader(valeur)
{
modalSetInnerHtml('modal_header', valeur);
}
function modalSetBody(valeur)
{
modalSetInnerHtml('modal_body', valeur);
}
function modalSetFooter(valeur)
{
modalSetInnerHtml('modal_footer', valeur);
}
/*
* Format du paramètre : methode:p1=v1,p2=v2
*/
function open_modal_hook(parametre)
{
console.log("open_modal_hook pour "+parametre);
let hook = null;
let paramSplit = parametre.split(':');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'type') {
hook = modal_hooks[elemSplit[1]];
}
});
if ((hook===null)||(hook===undefined)) hook = modal_hooks['ITEM'];
return hook(parametre);
}
init_modal();

+ 83
- 0
frontend/src/scripts/UI/planning.js Bestand weergeven

@ -0,0 +1,83 @@
datagrid_hooks['planning'] = function() {
let element = document.querySelector("#datagrid");
let filtre = getTrigrammeCollaborateur(getContexteValeur('intervenant'));
let contenu = "";
let nbLignes = 1;
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
let retour = 0;
/*
if (item_a['client'] < item_b['client']) retour = -1;
if (item_a['client'] > item_b['client']) retour = 1;
*/
if (retour == 0 ) {
retour = sort2ItemsByDates(item_a, item_b);
}
return retour;
});
setItemsVisibility();
contenu += "<table>";
contenu += " <thead>";
contenu += " <tr>";
contenu += ' <th style="width:50px;text-align:center">Client</td>';
contenu += ' <th style="width:50px;text-align:center">Intervenant</td>';
contenu += ' <th style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">Libellé</th>';
contenu += ' <th style="width:100px;text-align:center">Début</td>';
contenu += ' <th style="width:100px;text-align:center">fin</td>';
contenu += " </tr>";
contenu += " </thead>";
contenu += " <tbody>";
items.forEach((element) => {
let item = getItemFromElement(element);
let texte = getNonNullTextValeur(item.libelle);
let debut = formatLocaleDateFromStringDate(item.debut);
let heureDebut= formatTimeFromStringDate(item.debut);
let fin = formatLocaleDateFromStringDate(item.fin);
let heureFin= formatTimeFromStringDate(item.fin);
// On n'affiche pas la racine
if (item["idlignes"] == 1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item["visible"]) return true;
// On n'affiche que les feuilles
if (item.childs.length != 0) return true;
// On n'affiche que ce qui est plannifié
if((debut=='-')&&(fin=='-')) return true;
// Appliquer le filtre
if (filtre != 'ANO')
if (getTrigrammeCollaborateur(item['intervenant']) != filtre) return true;
if (item.status == 3) texte = "<strike>" + texte + "</strike>";
if (item.status == 2) texte = "<strike>" + texte + "</strike>";
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="type='+item.type+':id=' + getNonNullTextValeur(item.idlignes) + '">';
contenu += ' <td style="width:50px;text-align:center">' + getNonNullTextValeur(item.client) + "</td>";
contenu += ' <td style="width:50px;text-align:center">' + getTrigrammeCollaborateur(item['intervenant']) + "</td>";
contenu += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">'+ texte + "</td>";
contenu += ' <td style="width:100px;text-align:center">' + debut + "<br>" + heureDebut + "</td>";
contenu += ' <td style="width:100px;text-align:center">' + fin + "<br>" + heureFin + "</td>";
contenu += " </tr>";
nbLignes += 1;
});
contenu += " </tbody>";
contenu += " <tfoot>";
contenu += " <tr>";
contenu += ' <th colspan="5">'+setLevelPadding(2)+''+(nbLignes-1)+' tâches</th>';
contenu += " </tr>";
contenu += " </foot>";
contenu += "</table>";
element.innerHTML = contenu;
}

+ 74
- 0
frontend/src/scripts/UI/pomodoro.js Bestand weergeven

@ -0,0 +1,74 @@
function lancerPomodoroItem(id) {
let cur_type=null;
let modal_header='';
let modal_body='';
let modal_footer='';
items.filter(item => item.idlignes == id).forEach(resultat => {
let flagDisabled='disabled';
modal_header = getItemDialogHeader(resultat, cur_type);
modal_body += resultat.client+' > '+getTrigrammeCollaborateur(resultat.intervenant)+' : '+resultat.libelle+'<br>';
modal_body += '<textarea id="notes" data-aatribute="'+resultat.id+'" ';
modal_body += 'style="width: 100%;height: 100%;overflow: hidden;border: none;outline: none" placeholder="Saisir vos notes...">';
modal_body += '</textarea>';
modal_footer += '<div align="left" width="50%" style="float:left;padding-top:2vh">';
modal_footer += '<button onclick="todo()">Notes</button>';
modal_footer += '<button onclick="todo()">RIDA</button>';
modal_footer += '<button onclick="todo()">Documents</button>';
modal_footer += '<button onclick="todo()">Conversation</button>';
modal_footer += '</div>';
modal_footer += '<div align="right" width="50%" style="float:right;padding-top:2vh">';
modal_footer += '<button onclick="enregistrerNotes('+resultat.idlignes+')">Sauver</button>';
modal_footer += '<button onclick="arreterPomodoroItem('+resultat.idlignes+')">Fermer</button>';
modal_footer += '</div>';
});
modal_footer += '<div style="clear:both">';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
lireNotes(id);
}
function arreterPomodoroItem(id) {
// STOP le chrono
// enregistrer la saisie en cours
enregistrerNotes(id);
// Aficher les infos
itemInfo(id);
}
function enregistrerNotes(_id){
let _notes=document.getElementById('notes').value;
postData("../backend/notes.php", {id: _id, action: 'write', notes: _notes}).then((data) => {
console.log(data); // JSON data parsed by `data.json()` call
});
}
function lireNotes(_id){
postData("../backend/notes.php", {id: _id, action: 'read', notes: ''}).then((data) => {
document.getElementById('notes').value = data.notes;
});
}
/*
* Ajouter la prise en charge de "Ctrl + S" dans la textarea
*/
document.onkeydown = function(e) {
if (e.ctrlKey && e.key === 's') {
let notes = document.getElementById('notes');
if (notes) {
enregistrerNotes(notes.getAttribute('data-attribute'));
}
return false;
}
};

+ 163
- 0
frontend/src/scripts/UI/settings.js Bestand weergeven

@ -0,0 +1,163 @@
function settingsInitModal(){
let template = document.querySelector('#settings_header');
modalSetHeader('');
modalSetBody('');
modalSetFooter('');
template = document.querySelector('#settings_header');
if (template) {
let contenu = document.importNode(template.content, true);
if (contenu) modalSetChildren('modal_header',contenu);
}
}
modal_hooks['settings'] = function(parametres){
settingsSetModeInfo();
};
modal_hooks['login'] = function(parametres){
settingsSetModeLogin();
};
function settingsSetModeInfo()
{
let template = document.querySelector('#settings_body');
settingsInitModal();
if (template) {
let contenu = document.importNode(template.content, true);
if (contenu) modalSetChildren('modal_body',contenu);
}
modalSetFooter('');
}
function settingsSetModeLogin()
{
let intervenant=getContexteValeur('intervenant');
let profil=getContexteValeur('profil');
let profils=getContexteValeur('profils');
let modal_body='';
let modal_footer='';
let profil_selector=profil;
if (profils) {
let tableau=profils.split(',');
profil_selector='<select style="width: 100%;font-size: 1em">';
tableau.forEach(element => {
let s=(element == profil) ? 'selected' : '';
profil_selector+='<option '+s+'>'+element+'</option>';
});
profil_selector+='</select>';
}
settingsInitModal();
modalSetBody(modal_body);
modalSetFooter(modal_footer);
modal_body+='<div style="height:100%;background: url(\'images/LoginBanner.jpg\');background-size: cover;display: flex;justify-content: center;align-items: center;">';
modal_body+=' <div style="background-color: rgba(255, 255, 255, 0.4); border-radius: 5px;min-width: 25%;backdrop-filter: blur(3px);display: flex;flex-direction: column;justify-content: center;align-items: center;">';
if (intervenant=='Anonymous') {
modal_body+=' <input id="login_username" type="text" placeholder="Username" style="margin: 5px;font-size: 1em;width: 200px"></input>';
modal_body+=' <input id="login_password" type="password" style="margin: 5px;font-size: 1em;width: 200px"></input>';
modal_body+=' <button style="border:none;background-color: #2196F3;width: 200px;border-radius: 5px;margin: 5px;color: white; font-size: 1em; font-weight: bold; cursor: pointer" onclick="connectUser()">Log In</button>';
} else {
modal_body+=' <h2 style="width: 200px;display: flex;text-align : center;justify-content: center;align-items: center;margin: 2px;">'+intervenant+'</h2>';
modal_body+=' <h3 style="width: 200px;display: flex;text-align : center;justify-content: center;align-items: center;margin: 5px;">'+getTrigrammeCollaborateur(intervenant)+'<h3>';
modal_body+=' <div style=""width: 200px;display: flex;text-align : center;justify-content: center;align-items: center;margin: 5px;">'+profil_selector+'</div>';
modal_body+=' <button style="border:none;background-color: grey;width: 200px;border-radius: 5px;margin: 5px;color: white; font-size: 1em; font-weight: bold; cursor: pointer" onclick="deconnectUser()">Log Out</button>';
}
modal_body+=' </div>';
modal_body+='<div>';
modalSetBody(modal_body);
}
function connectUser()
{
let username = document.getElementById('login_username').value;
let password = document.getElementById('login_password').value;
// C'est un POC donc on n'a pas de base utilisateur
if ((username!='')&&(password==username))
{
setContexteValeur('intervenant', username);
setContexteValeur('profils', 'Utilisateur');
setContexteValeur('profil', 'Utilisateur');
if (username=='TME')
{
setContexteValeur('intervenant', 'Thibaud MEUNIER');
setContexteValeur('profils', 'Utilisateur,Admin');
setContexteValeur('profil', 'Utilisateur');
}
document.getElementById('username').innerHTML=username;
}
settingsSetModeLogin();
}
function deconnectUser()
{
setContexteValeur('intervenant', 'Anonymous');
settingsSetModeLogin();
document.getElementById('username').innerHTML='Log In';
}
function settingsSetModeFilter()
{
let modal_body='';
let modal_footer='';
settingsInitModal();
modalSetBody(modal_body);
modalSetFooter(modal_footer);
modal_body+='<div style="height:100%;display: flex;justify-content: center;align-items: center;flex-direction: column;">';
modal_body+='<h2>Mode Filter</h2>';
modal_body+='<div>';
modalSetBody(modal_body);
}
function settingsSetModeSetup()
{
let modal_body='';
let modal_footer='';
settingsInitModal();
modalSetBody(modal_body);
modalSetFooter(modal_footer);
modal_body+='<div style="height:100%;width:100%;display: flex;justify-content: center;align-items: center;flex-direction: column;">';
modal_body+=' <h2>Thèmes</h2>';
modal_body+=' <div style="display:flex;">';
modal_body+=' <div style="flex: 1;border: 1px solid black;text-align: center;cursor: pointer">';
modal_body+=' <a onclick="settingsSetTheme(\'default\')">Default</a>';
modal_body+=' </div>';
modal_body+=' <div style="flex:1;border: 1px solid black;text-align: center;cursor: pointer">';
modal_body+=' <a onclick="settingsSetTheme(\'red\')" style="color:#FA0000">Red</a>';
modal_body+=' </div>';
modal_body+=' <div style="flex:1;border: 1px solid black;text-align: center;cursor: pointer">';
modal_body+=' <a onclick="settingsSetTheme(\'blue\')" style="color:#0000FA">Blue</a>';
modal_body+=' </div>';
modal_body+=' </div>';
modal_body+='<div>';
modalSetBody(modal_body);
}
function settingsSetTheme(valeur)
{
switch(valeur){
case 'blue':
CSSsetClair(245,245,240);
CSSsetSombre(0,0,245);
break;
case 'red':
CSSsetClair(245,245,240);
CSSsetSombre(245,0,0);
break;
default:
CSSsetClair(245,245,240);
CSSsetSombre(0,0,0);
}
}

+ 77
- 0
frontend/src/scripts/api/clients.js Bestand weergeven

@ -0,0 +1,77 @@
var clients;
function setClients(data){
clients = data;
}
getEntities('client', setClients);
function initDatagridClients() {
setClients(null);
datagridLoading();
getEntities('client', __initDatagridClients);
}
function __initDatagridClients(data) {
let element = document.querySelector('#datagrid');
let contenu='';
setClients(data);
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>Id</th>';
contenu += ' <th>Code</th>';
contenu += ' <th>Client</th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
clients.forEach(client => {
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="client:id='+client.idclient+'">';
contenu += ' <td>'+client.idclient+'</td>';
contenu += ' <td>'+client.code+'</td>';
contenu += ' <td>'+client.nom+'</td>';
contenu += ' </tr>';
});
contenu += ' </body>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th colspan="3">&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
init_modal();
}
modal_hooks['client'] = function(parametres){
let paramSplit = parametres.split(',');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'id') {
let id = elemSplit[1];
let modal_header='Fiche client ['+id+']';
let modal_body='Client inconnu !';
let modal_footer='<button>Enregistrer</button';
clients.filter(client => client.idclient == id)
.forEach(resultat => {
modal_body = '<table class="modal_table">';
modal_body += '<tr><td style="width:30%">Id</td><td>'+resultat.idclient+'</td></tr>';
modal_body += '<tr><td style="width:30%">Code</td><td>'+resultat.code+'</td></tr>';
modal_body += '<tr><td style="width:30%">Nom</td><td>'+resultat.nom+'</td></tr>';
modal_body += '</table>';
});
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
});
};

+ 98
- 0
frontend/src/scripts/api/collaborateurs.js Bestand weergeven

@ -0,0 +1,98 @@
var collaborateurs = [];
function setCollaborateurs(data){
collaborateurs = data;
}
getEntities('collaborateur', setCollaborateurs);
function getTrigrammeCollaborateur(intervenant) {
let trigramme = intervenant;
collaborateurs.forEach((collaborateur) => {
if (collaborateur.nom == intervenant) trigramme = collaborateur.trigramme;
});
return trigramme;
}
async function addCollaborateurs(collaborateur) {
let url = '../backend/api.php?entity=collaborateur';
let response = await fetch(url, {
method: "POST",
body: JSON.stringify(collaborateur),
headers: {
"Content-Type": "application/json",
},
});
let data = await response.json(); //extract JSON from the http response
}
function initDatagridCollaborateurs() {
let element = document.querySelector('#datagrid');
element.innerHTML= '<center>Loading colaborateurs ...</center>'
setCollaborateurs(null);
getEntities('collaborateur', __initDatagridCollaborateurs);
}
function __initDatagridCollaborateurs(data) {
let element = document.querySelector('#datagrid');
let contenu='';
setCollaborateurs(data);
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>Id</th>';
contenu += ' <th>Nom</th>';
contenu += ' <th>Trigramme</th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
collaborateurs.forEach(collaborateur => {
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="collaborateur:id='+collaborateur.idcollaborateur+'">';
contenu += ' <td>'+collaborateur.idcollaborateur+'</td>';
contenu += ' <td>'+collaborateur.nom+'</td>';
contenu += ' <td>'+collaborateur.trigramme+'</td>';
contenu += ' </tr>';
});
contenu += ' </body>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th colspan="3">&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
init_modal();
}
modal_hooks['collaborateur'] = function(parametres){
let paramSplit = parametres.split(',');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'id') {
let id = elemSplit[1];
let modal_header='Fiche collaborateur ['+id+']';
let modal_body='Collaborateur inconnu !';
let modal_footer='<button>Enregistrer</button';
collaborateurs.filter(collaborateur => collaborateur.idcollaborateur == id)
.forEach(resultat => {
modal_body = '<table class="modal_table">';
modal_body += '<tr><td style="width:30%">Id</td><td>'+resultat.idcollaborateur+'</td></tr>';
modal_body += '<tr><td style="width:30%">Nom</td><td>'+resultat.nom+'</td></tr>';
modal_body += '<tr><td style="width:30%">Trigramme</td><td>'+resultat.trigramme+'</td></tr>';
modal_body += '</table>';
});
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
});
};

+ 5
- 0
frontend/src/scripts/api/entities.js Bestand weergeven

@ -0,0 +1,5 @@
function getEntities(entity, callback) {
return fetch('../backend/api.php?entity='+entity)
.then(response => response.json())
.then(data => callback(data));
}

+ 728
- 0
frontend/src/scripts/api/items.js Bestand weergeven

@ -0,0 +1,728 @@
var items = null;
var items_max_level = 0;
var padding_end_char = '0';
var padding_start_char = '0';
var padding_length = 8;
var useClone = true;
var itemFields = [];
var debug_item = -1;
function isDebugItem(item) {
return (item.idlignes == debug_item);
}
function getItemFromElement(element)
{
if (useClone) return (element?.clone ?? null);
return element;
}
function AddCloneToElement(element)
{
if (useClone) element.clone = Object.assign({}, element);
return useClone;
}
function setLevelPadding(level)
{
let retour = '';
if (level > 0)
for(i=0;i<level;i++) retour += '&nbsp;&nbsp;&nbsp;&nbsp;';
return retour;
}
function itemGetParentItem(item) {
return getItemFromElement(items.filter(ee => ee.idlignes == item.parent)[0]);
}
function setItems(data) {
items = data;
items_max_level = 0;
// Ajouter une copie de lui-même à chaque item
items.forEach(element => AddCloneToElement(element));
// Trouver le niveau de l'item et mettre à jour le niveau max
items.forEach(element => {
let item = getItemFromElement(element);
let parent = getItemFromElement(items.filter(ee => ee.idlignes == item.parent)[0]);
if (isDebugItem(item)){
myLog("ICI");
}
// gestion du rang vide
if (item['rank'] == '') item['rank'] = '0';
// Recherche du niveau, des ancêtres et des enfants
item['level']=0;
item['parents'] = [];
while(parent != null){
item['level'] += 1;
item['parents'].push(parent['idlignes']);
parent = getItemFromElement(items.filter(ee => ee.idlignes == parent.parent)[0]);
}
item['childs'] = [];
items.forEach(ee => {if (ee['parent'] == item['idlignes']) item['childs'].push(ee['idlignes']) });
if (items_max_level < item['level']) items_max_level = item['level']+1;
item['debut'] = item['debut']?.padEnd(12,'0') ?? '000000000000';
item['fin'] = item['fin']?.padEnd(12,'0') ?? '999999990000';
if (item['debut']=='000000000000') item['debut']=item['fin'];
item['visible'] = true;
// En mode feuille, seules les feuilles sont visibles
if (getParametreValeur(['mode_feuille']))
if (item['childs'].length != 0)
item['visible'] = false;
});
// Gestion de l'héritage des propriétés
// On en profite pour calculer le chemin de l'item
// Et pour calculer une valeur qui permette le tri dans l'affiche tree
// ie
let heritage = ['contrat','projet','intervenant','client'];
for(i=0;i<items_max_level+1;i++) {
items.forEach(element => {
let item = getItemFromElement(element);
if (item['level']==i) {
let parent = getItemFromElement(items.filter(ee => ee.idlignes == item.parent)[0]);
item['path'] = item['rank'].padStart(3,padding_start_char)+item['idlignes'].padStart(padding_length,padding_start_char);
item['tritree']=item['path'];
if (parent != null) {
item['tritree']=parent['tritree']+item['debut']+item['tritree'];
item['path'] = parent['path']+item['path'];
for(var field in parent)
if (heritage.indexOf(field) !== -1)
if ((item[field] == null)||(item[field]==''))
item[field] = parent[field];
}
}
});
}
// Gestion de la remontée des propriétés
for(i=items_max_level+1;i>=0;i--) {
items.forEach(element => {
let item = getItemFromElement(element);
if (item['level']==i) {
if (item.childs.length != 0) {
item.jours_commandes = 0.0;
item.jours_planifies = 0.0;
item.jours_realises = 0.0;
item.childs.forEach(child => {
let childElement = items.filter(ee => ee.idlignes == child)[0];
let enfant = getItemFromElement(childElement);
if (isDebugItem(item)){
myLog("ICI");
}
item.jours_commandes += customParseFloat(enfant.jours_commandes);
item.jours_planifies += customParseFloat(enfant.jours_planifies);
item.jours_realises += customParseFloat(enfant.jours_realises);
});
}
}
// L'element porte une commande, on annule le calcul
if (customParseFloat(element.jours_commandes) > 0) item.jours_commandes = element.jours_commandes;
});
}
}
// -----------------------------------------------------------------------------
// ---- Cette fonction détermine la visibilité des item
// -----------------------------------------------------------------------------
function setItemsVisibility(){
let mode_affichage=getContexteValeur('mode_affichage');
let termine=getContexteValeur('termine');
let client = getContexteValeur('client');
let level = parseInt(getContexteValeur('level'));
let idfiltre = stringDatePadDigits(parseInt(getContexteValeur('parent')),8);
/*
TODO : Faire la part des choses entre "contexte" et "filtre"
A priori :
Un filtre dépend des données exemples
- filtrer parmi les clients
- filtrer parmi les niveaux
Un contexte dépend de l'appli, exemples
- utilistaeur connecté
- mode d'affichage courant
*/
client = getFiltreValeur('client');
level = parseInt(getFiltreValeur('level'));
if (idfiltre != '00000000'){
let itemFiltre = getItemFromElement(items.filter(ee => ee.idlignes == parseInt(idfiltre))[0]);
if (itemFiltre) level += itemFiltre['level'];
}
// Gestion de la visibilité individuelle
// Que l'on va appeler 'filtre'
items.forEach(element => {
let item = getItemFromElement(element);
if (isDebugItem(item)){
myLog("ICI");
}
item['visible'] = true;
// Contrôle du statut
if ((item['status'] != 0)&&(item['status'] != 3)) item['visible'] = false;
// Contrôle du client courant
if ((client != '') && (client != item['client'])) item['visible'] = false;
// Contrôle du niveau courant
if (item['level'] > level) item['visible'] = false;
// Cas particulier
// ABS = Absences
// FER = Fériés
// REL = Releases de version
// RDV = Rendez-Vous
switch(mode_affichage){
case 'absences':
if (item['client'] != 'ABS') item['visible'] = false;
break;
case 'releases':
if (item['client'] != 'REL') item['visible'] = false;
break;
case 'feries':
if (item['client'] != 'FER') item['visible'] = false;
break;
case 'rdv':
if (item['client'] != 'RDV') item['visible'] = false;
break;
case 'planning':
case 'calendar_intervenants':
case 'calendar_clients':
break;
default:
//if (item['client'] == 'ABS') item['visible'] = false;
if (item['client'] == 'RDV') item['visible'] = false;
if (item['client'] == 'FER') item['visible'] = false;
if (item['client'] == 'REL') item['visible'] = false;
}
// Appliquer le filtre
if ((idfiltre != '00000000') && (!item['path'].includes(idfiltre))) item['visible'] = false;
if ((termine=='non')&&(item['status']!=0)) item['visible']=false;
// La racine est toujours visible
// if (item['idlignes'] == 1) item['visible'] = true;
});
// Gestion des statuts hérités
// Si un parent est terminé alors ses enfants aussi
for(i=0; i<items_max_level+1;i++) {
items.forEach(element => {
let item = getItemFromElement(element);
if (item['level']==i) {
let parent = itemGetParentItem(item);
if (parent != null)
if (parent['status'] != 0) {
item['visible'] = false;
}
}
});
}
// Gestion de la visibilité héritée
// Si un enfant est visible alors ses parents aussi
for(i=items_max_level+1;i>=0;i--) {
items.forEach(element => {
let item = getItemFromElement(element);
if (item['level']==i) {
if (item['visible']) {
let parent = itemGetParentItem(item);
if (parent != null)
parent['visible'] = true;
}
}
});
}
}
// -----------------------------------------------------------------------------
// ---- foncttons de tri des items
// -----------------------------------------------------------------------------
function sort2ItemsByField(item_a, item_b, field){
let retour = 0;
if (item_a[field] < item_b[field]) retour = -1;
if (item_a[field] > item_b[field]) retour = 1;
return retour;
}
function sort2ItemsByDates(item_a, item_b){
let retour = 0;
let maintenant = formatDatetoStringDateTime(new Date);
// Par défaut, on trie par date de début
let val_a = item_a['debut']?.padEnd(12,'0');
let val_b = item_b['debut']?.padEnd(12,'0');
// Sauf si l'item est en cours.
if ((item_a.debut < maintenant)&&(item_a.fin>=maintenant))
val_a = item_a['fin']?.padEnd(12,'0');
if ((item_b.debut < maintenant)&&(item_b.fin>=maintenant))
val_b = item_b['fin']?.padEnd(12,'0');
// Ce qui n'est pas planifié est plus tard que le reste
if (val_a == '') val_a = '999999999999';
if (val_b == '') val_b = '999999999999';
if (val_a < val_b) return -1;
if (val_a > val_b) return 1;
// retour = sort2ItemsByField(item_a, item_b, 'debut');
// if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'rank');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'idlignes');
if (retour != 0) return retour;
return retour;
}
function sort2ItemsByStartDates(item_a, item_b){
retour = sort2ItemsByField(item_a, item_b, 'debut');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'fin');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'idlignes');
if (retour != 0) return retour;
return 0;
}
function sort2ItemsByEndDates(item_a, item_b){
retour = sort2ItemsByField(item_a, item_b, 'fin');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'debut');
if (retour != 0) return retour;
retour = sort2ItemsByField(item_a, item_b, 'idlignes');
if (retour != 0) return retour;
return 0;
}
function sortItemsByDate(){
let maintenant = formatDatetoStringDateTime(new Date);
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
// Par défaut, on trie par date de début
let val_a = item_a['debut'];
let val_b = item_b['debut'];
// Sauf si l'item est en cours.
if ((item_a.debut < maintenant)&&(item_a.fin>=maintenant))
val_a = item_a['fin'];
if ((item_b.debut < maintenant)&&(item_b.fin>=maintenant))
val_b = item_b['fin'];
if (val_a < val_b) return -1;
if (val_a > val_b) return 1;
return sort2ItemsByStartDates(item_a, item_b);
});
}
function sortItemsByEndDate() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
return sort2ItemsByEndDates(item_a, item_b);
});
}
function sortItemsByStartDate() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
return sort2ItemsByStartDates(item_a, item_b);
});
}
/* TO DELETE
function sortItemsByPath() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
return sort2ItemsByField(item_a, item_b, 'path');
});
}
*/
function sortItemsByTriTreeValue() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
return sort2ItemsByField(item_a, item_b,'tritree');
});
}
function sortItemsByPathDates() {
items.sort((a, b) => {
let item_a = getItemFromElement(a);
let item_b = getItemFromElement(b);
let retour = 0;
// Les 2 items sont des feuilles du même parent
// On les trie par rang puis par dates
if ((item_a.childs.length == 0)&&(item_b.childs.length == 0)){
if (item_a.parent === item_b.parent){
retour = sort2ItemsByField(item_a, item_b,'rank');
if (retour == 0) retour = sort2ItemsByDates(item_a, item_b);
}
}
if (retour == 0) retour = sort2ItemsByField(item_a, item_b,'path');
return retour;
});
}
function sortItemsByClientParentDates() {
return sortItemsByTriTreeValue();
}
/* TO DELETE
function sortItemsModeTasks() {
sortItemsByPath();
}
*/
// -----------------------------------------------------------------------------
// ---- Cette fonction charge les items
// -----------------------------------------------------------------------------
function initDatagridItems() {
datagridLoading();
return getEntities(getContexteValeur('items_type'), __initDatagridItems);
}
function __initDatagridItems(data) {
setItems(data);
return afficherItems();
}
// -----------------------------------------------------------------------------
// ---- Placer un filtre
// -----------------------------------------------------------------------------
function filtrerItem(id){
items.filter(item => item.idlignes == id).forEach(element => {
let item=getItemFromElement(element);
setContexteValeur('parent',id);
setContexteValeur('client',item['client']);
setContexteValeur('parent_level',item['level']);
});
gotoTop();
afficherItems();
}
// -----------------------------------------------------------------------------
// ---- Cette fonction détermine l'entité à afficher en fonction du contexte
// -----------------------------------------------------------------------------
function clearElement(idElement){
let element = document.querySelector(idElement);
if (element) element.innerHTML = '';
}
function afficherItems() {
let callback_affichage = datagrid_hooks[getContexteValeur('mode_affichage')];
clearElement("#datagrid");
clearElement("#calendrier");
setItemsVisibility();
if (callback_affichage === null) callback_affichage = datagrid_hooks['items'];
callback_affichage();
init_modal();
}
// -------------------------------------------------------------------------------------------------
// ---- Édition générique des items
// -------------------------------------------------------------------------------------------------
var items_edit_hooks = [];
var item_save_hooks = [];
function editerItem(id,libelle){
let callback_edition=items_edit_hooks[getContexteValeur('type_courant')];
items.filter(item => item.idlignes == id).forEach(resultat => {
callback_edition = items_edit_hooks[resultat.type];
});
if ((callback_edition===null)||(callback_edition===undefined)) {
callback_edition = items_edit_hooks['ITEM'];
}
return callback_edition(id, libelle);
}
function itemAPI(idlignes, bodyJSON) {
let url = '../backend/api.php?entity=lignes';
if (idlignes != 1) // On ne sauve pas la racine
{
if (idlignes != -1) url += '&id='+idlignes;
fetch(url, {
method: 'POST',
body: bodyJSON, // string or object
headers: {
'Content-Type': 'application/json'
}
}).then((response) => response.json()).then((objet) => {
initDatagridItems()
.then(() => {
if (idlignes != -1) itemInfo(idlignes);
else close_modal();
});
});
}
}
function itemInfo(id){
let cur_type='ITEM';
items.filter(item => item.idlignes == id).forEach(resultat => {
cur_type=resultat.type;
});
return modal_hooks['ITEM']('type='+cur_type+':id='+id);
}
function itemSave(type, id){
return item_save_hooks[type](id);
}
function itemChangeAttribut(id, attribut, valeur) {
let bodyJSON = '{"idlignes":'+id+', "'+attribut+'": "'+valeur+'"}';
return itemAPI(id, bodyJSON, itemInfo);
}
function eventItemChangeType(id, event) {
return itemChangeAttribut(id, 'type',event.target.value);
}
function eventItemChangeStatus(id, event) {
return itemChangeAttribut(id, 'status',event.target.value);
}
// -------------------------------------------------------------------------------------------------
// ---- Gestion générique des items
// -------------------------------------------------------------------------------------------------
itemFields['ITEM'] = ['parent','type','client','intervenant','libelle'];
let last_path='';
let last_path_retour;
function explodePath(path, id)
{
let retour = '';
let start = 0;
const nb_numeros = 3;
if (!last_path.includes(path)) last_path=path;
if (last_path.length > nb_numeros*8) {
start = (last_path.length - (nb_numeros*11));
retour = '... > ';
}
for(let i=start;i<last_path.length;i+=11){
let split = parseInt(last_path.substring(i,i+11));
if (split != 1) {
if (id == split) split = '<b>'+split+'</b>';
if (i>start) retour += ' > ';
retour += '<span onclick="itemInfo('+split+')" style="cursor: pointer">'+split+'</span>';
}
else retour = '...';
}
return retour ;
}
datagrid_hooks['items'] = function(){
let element = document.querySelector("#datagrid");
let contenu = "";
sortItemsByTriTreeValue();
contenu += '<table width="100vw">';
contenu += " <thead>";
contenu += " <tr>";
contenu += ' <th style="width:50px"><span class="nouveau" onclick="editerItem(-1,\'\')">Nouveau</span></th>';
contenu += ' <th colspan="2">&nbsp;</th>';
contenu += ' <th><span class="filtrer">Filtre</span></th>';
contenu += " </tr>";
contenu += " <tr>";
contenu += ' <th style="width:50px">Client</th>';
contenu += " <th>Libelle</th>";
contenu += " <th><center>Type</center></th>";
contenu += " <th><center>État</center></th>";
contenu += " </tr>";
contenu += " </thead>";
contenu += " <tbody>";
items.forEach((element) => {
let item = getItemFromElement(element);
let texte = getNonNullTextValeur(item.libelle);
if (item.status == 3) texte = "<strike>" + texte + "</strike>";
// On n'affiche pas la racine
if (item["idlignes"] == 1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item["visible"]) return true;
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="'+item.type+':id=' + item.idlignes + '">';
contenu += ' <td style="width:50px">' + item.client + '</td>';
contenu += " <td>" + setLevelPadding(item["level"]) + texte + "</td>";
contenu += ' <td><center>' + item.type + "</center></td>";
contenu += " <td><center>" + getStatusLibelleFromId(item.status) + "</center></td>";
contenu += " </tr>";
});
contenu += " </body>";
contenu += " <tfoot>";
contenu += " <tr>";
contenu += ' <th colspan="4">&nbsp;</th>';
contenu += " </tr>";
contenu += " </foot>";
contenu += "</table>";
element.innerHTML = contenu;
}
function getItemDialogHeader(item){
let retour='';
let liste_select_types = ['TODO','TACHE','PRESTATION','ITEM'];
retour += '<select onchange="eventItemChangeType('+item.idlignes+',event)">';
liste_select_types.forEach((valeur)=>{
let selected = '';
if (valeur == item.type) selected='selected';
retour += '<option value="'+valeur+'" '+selected+'>'+valeur+'</opton>';
});
retour += '</select><br>';
retour += ' n°'+explodePath(item.clone.path,item.idlignes);
return retour;
}
modal_hooks['ITEM'] = function(parametres){
let cur_type=null;
let cur_id=null;
let modal_header='';
let modal_body='item inconnu !';
let modal_footer='';
let paramSplit = parametres.split(':');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0]==='type') cur_type=elemSplit[1];
if (elemSplit[0]==='id') cur_id=elemSplit[1];
});
if (itemFields[cur_type]===undefined) cur_type='ITEM';
items.filter(item => item.idlignes == cur_id).forEach(resultat => {
let liste_status = ['Planifié', 'Supprimé', 'Annulé', 'Terminé','Reporté'];
modal_header = getItemDialogHeader(resultat);
modal_body = '<table class="modal_table">';
itemFields[cur_type].forEach(attribut => {
let valeur = getNonNullTextValeur(resultat[attribut]);
if (attribut =='libelle') valeur = '<b>'+valeur+'</b>';
modal_body += '<tr class="tr1"><td>'+attribut+'</td><td>'+valeur+'</td></tr>';
});
modal_body += '</table>';
modal_footer += '<div align="left" width="50%" style="float:left;padding-top:2vh">';
modal_footer += '<button onclick="editerItem('+resultat.idlignes+',null)">Modifier</button>';
modal_footer += '<button onclick="filtrerItem('+resultat.idlignes+')">Filtrer</button> ';
modal_footer += '</div>';
modal_footer += '<div align="right" width="50%" style="float:right;padding-top:2vh">';
modal_footer += '<button onclick="lancerPomodoroItem('+resultat.idlignes+')">Lancer</button>';
modal_footer += '<select onchange="eventItemChangeStatus('+resultat.idlignes+',event)">';
liste_status.forEach((valeur,index)=>{
let selected = '';
if (index == resultat.status) selected='selected';
modal_footer += '<option value="'+index+'" '+selected+'>'+valeur+'</option>';
});
modal_footer += '</select><br>';
modal_footer += '</div>';
});
modal_footer += '<div style="clear:both">';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
items_edit_hooks['ITEM'] = function (id, libelle) {
let modal_header='';
let modal_body='Item inconnu !';
let modal_footer='<div align="right" width="100%" style="padding-top:2vh"><button onclick="itemSave('+id+')">Enregistrer</button></div>';
let local_values = [];
let local_placeholder = [];
local_values['parent']=getContexteValeur('parent');
local_values['type']=getContexteValeur('type_courant');
local_values['client']=getContexteValeur('client');
local_values['intervenant']=getContexteValeur('intervenant');
local_values['libelle']=libelle;
if (local_values['client']=='') local_values['client']=getTrigrammeCollaborateur(local_values['intervenant']);
items.filter(item => item.idlignes == id).forEach(resultat => {
local_values['type']=resultat['type'];
itemFields[local_values['type']].forEach(attribut => {
local_values[attribut]=resultat[attribut];
local_placeholder[attribut]=resultat.clone[attribut];
});
});
modal_header=local_values['type'];
if (id != -1) modal_header+=' n°<b>'+id+'</b>';
modal_body = '<table class="modal_table"><form id="formulaire_lignes">';
itemFields[local_values['type']].forEach(attribut => {
modal_body += '<tr><td>'+attribut+'</td><td>'+getInputLabel(attribut,local_values[attribut], local_placeholder[attribut])+'</td></tr>';
});
modal_body += '</form></table>';
modal_footer='<div align="left" width="100%" style="padding-top:2vh"><button onclick="itemSave(\''+local_values['type']+'\','+id+')">Enregistrer</button></div>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
if (!modalDialog.open) modalDialog.showModal();
}

+ 118
- 0
frontend/src/scripts/api/items/prestations.js Bestand weergeven

@ -0,0 +1,118 @@
itemFields['PRESTATION'] = ['libelle','parent','rank','client','intervenant','debut','fin','contrat','projet','jours_commandes','jours_planifies','jours_realises'];
datagrid_hooks['prestations'] = function() {
let element = document.querySelector("#datagrid");
let contenu = "";
let nbLignes = 1;
let parentLevel=getContexteValeur('parent_level');
let showPrestationsOnly=(getContexteValeur('prestation')=='oui');
if (parentLevel == 0) parentLevel=1;
sortItemsByClientParentDates();
contenu += "<table>";
contenu += " <thead>";
contenu += " <tr>";
contenu += ' <th colspan="6" onchange="updateValue(event)"><input id="newitem_input" type="text" placeholder="Nouvel item" style="width: 98%;outline: none"></th>';
contenu += " </tr>";
contenu += " <tr>";
// contenu += " <th><center>Id</center></th>";
contenu += ' <th style="width:50px;text-align:center"><span onclick="openFiltrePopup(\'client\')">Client</span></th>';
contenu += ' <th style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Libellé</span></th>';
contenu += ' <th style="max-width:150px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'contrat\')">Contrat</span></th>';
contenu += ' <th style="max-width:150px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Commandés</span></th>';
contenu += ' <th style="max-width:150px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Prévus</span></th>';
contenu += ' <th style="max-width:150px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Réalisés</span></th>';
// contenu += " <th><center>État</center></th>";
contenu += " </tr>";
contenu += " </thead>";
contenu += " <tbody>";
items.forEach((element) => {
let item = getItemFromElement(element);
let texte = getNonNullTextValeur(item.libelle);
let commandes = "-";
let planifies = "-";
let realises = "-";
// On n'affiche pas la racine
if (item["idlignes"] == 1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item["visible"]) return true;
if ((showPrestationsOnly)&&((item.jours_commandes + item.jours_realises+item.jours_planifies) == 0)) return true;
if (item.status == 3) texte = "<strike>" + texte + "</strike>";
if (item.status == 2) texte = "<strike>" + texte + "</strike>";
if (item.jours_commandes > 0)
commandes = convertJourHeure(getNonNullTextValeur(item.jours_commandes));
if (item.jours_realises > 0)
realises = convertJourHeure(getNonNullTextValeur(item.jours_realises));
if (item.jours_planifies > 0)
planifies = convertJourHeure(getNonNullTextValeur(item.jours_planifies));
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="type='+item.type+':id=' + getNonNullTextValeur(item.idlignes) + '">';
//contenu += " <td><center>" + getNonNullTextValeur(item.idlignes) + "</center></td>";
contenu += ' <td style="width:50px;text-align:center">' + getNonNullTextValeur(item.client) + '</td>';
contenu += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + setLevelPadding(item["level"]-parentLevel) + texte + '</td>';
contenu += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + getNonNullTextValeur(item.contrat) + '</td>';
contenu += ' <td style="width:50px;text-align:center">' + commandes + '</td>';
contenu += ' <td style="width:100px;text-align:center">' + planifies + '</td>';
contenu += ' <td style="width:100px;text-align:center">' + realises + '</td>';
//contenu += " <td>" + getStatusLibelleFromId(item.status) + '</td>';
contenu += " </tr>";
nbLignes += 1;
});
contenu += " </tbody>";
contenu += " <tfoot>";
contenu += " <tr>";
contenu += ' <th colspan="6">'+setLevelPadding(2)+''+(nbLignes-1)+' tâches</th>';
contenu += " </tr>";
contenu += " </foot>";
contenu += "</table>";
element.innerHTML = contenu;
// Ne marche pas , ça enlève le stick du header du tableau ...
// document.getElementById('newitem_input').focus({preventScroll: true});
}
function prestationSave(idlignes) {
let bodyJSON = JSON.stringify(getCurrentPRESTATION(idlignes));
return itemAPI(idlignes, bodyJSON, itemInfo);
}
item_save_hooks['PRESTATION'] = prestationSave;
function getCurrentPRESTATION(idlignes)
{
let result = new Object();
if (idlignes > 1) {
result['idlignes'] = idlignes;
} else {
result['type']=getContexteValeur('type_courant');
}
itemFields['PRESTATION'].forEach(attribut => {
result[attribut] = documentGetElementById('item_'+attribut);
});
if (result['parent']=='') result['parent']=1;
if (result['client']=='') result['client']==getTrigrammeCollaborateur(result['intervenant']);
if (result['libelle']=='') result['libelle']='xxxxxxxxxxxx';
if (result['intervevant']=='') result['intervenant']=getContexteValeur('intervenant');;
if (result['debut']=='') result['debut']=0;
if (result['fin']=='') result['fin']=0;
if (result['status']=='') result['status']=0;
return result;
}

+ 106
- 0
frontend/src/scripts/api/items/taches.js Bestand weergeven

@ -0,0 +1,106 @@
itemFields['TACHE'] = ['libelle','parent','rank','client','intervenant','debut','fin'];
datagrid_hooks['taches'] = function() {
let element = document.querySelector("#datagrid");
let contenu = "";
let nbLignes = 1;
let parentLevel=getContexteValeur('parent_level');
if (parentLevel == 0) parentLevel=1;
sortItemsByClientParentDates();
contenu += "<table>";
contenu += " <thead>";
contenu += " <tr>";
contenu += ' <th colspan="4" onchange="updateValue(event)"><input id="newitem_input" type="text" placeholder="Nouvel item" style="width: 98%;outline: none"></th>';
contenu += " </tr>";
contenu += " <tr>";
// contenu += " <th><center>Id</center></th>";
contenu += ' <th style="width:50px;text-align:center"><span onclick="openFiltrePopup(\'client\')">Client</span></th>';
contenu += ' <th style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis"><span onclick="openFiltrePopup(\'libelle\')">Libellé</span></th>';
contenu += ' <th style="width:100px;text-align:center"><span onclick="openFiltrePopup(\'debut\')">Début</span></th>';
contenu += ' <th style="width:100px;text-align:center"><span onclick="openFiltrePopup(\'fin\')">Fin</span></th>';
// contenu += " <th><center>État</center></th>";
contenu += " </tr>";
contenu += " </thead>";
contenu += " <tbody>";
items.forEach((element) => {
let item = getItemFromElement(element);
let texte = getNonNullTextValeur(item.libelle);
if (item.status == 3) texte = "<strike>" + texte + "</strike>";
if (item.status == 2) texte = "<strike>" + texte + "</strike>";
// On n'affiche pas la racine
if (item["idlignes"] == 1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item["visible"]) return true;
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="type='+item.type+':id=' + getNonNullTextValeur(item.idlignes) + '">';
//contenu += " <td><center>" + getNonNullTextValeur(item.idlignes) + "</center></td>";
contenu += ' <td style="width:50px;text-align:center">' + getNonNullTextValeur(item.client) + "</td>";
contenu += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + setLevelPadding(item["level"]-parentLevel) + texte + "</td>";
contenu += ' <td style="width:100px;text-align:center">' + formatLocaleDateFromStringDate(item.debut) + "</td>";
contenu += ' <td style="width:100px;text-align:center">' + formatLocaleDateFromStringDate(item.fin) + "</td>";
//contenu += " <td>" + getStatusLibelleFromId(item.status) + "</td>";
contenu += " </tr>";
nbLignes += 1;
});
contenu += " </tbody>";
contenu += " <tfoot>";
contenu += " <tr>";
contenu += ' <th colspan="4">'+setLevelPadding(2)+''+(nbLignes-1)+' tâches</th>';
contenu += " </tr>";
contenu += " </foot>";
contenu += "</table>";
element.innerHTML = contenu;
// Ne marche pas , ça enlève le stick du header du tableau ...
// document.getElementById('newitem_input').focus({preventScroll: true});
}
// on affiche ces éléments comme des tâches
datagrid_hooks['absences'] = datagrid_hooks['taches'];
datagrid_hooks['releases'] = datagrid_hooks['taches'];
datagrid_hooks['feries'] = datagrid_hooks['taches'];
datagrid_hooks['rdv'] = datagrid_hooks['taches'];
function taskSave(idlignes) {
let bodyJSON = JSON.stringify(getCurrentTASK(idlignes));
return itemAPI(idlignes, bodyJSON, itemInfo);
}
item_save_hooks['TACHE'] = taskSave;
function getCurrentTASK(idlignes)
{
let result = new Object();
if (idlignes > 1) {
result['idlignes'] = idlignes;
} else {
result['type']=getContexteValeur('type_courant');
}
itemFields['TACHE'].forEach(attribut => {
result[attribut] = documentGetElementById('item_'+attribut);
});
if (result['parent']=='') result['parent']=1;
if (result['client']=='') result['client']==getTrigrammeCollaborateur(result['intervenant']);
if (result['libelle']=='') result['libelle']='xxxxxxxxxxxx';
if (result['intervevant']=='') result['intervenant']=getContexteValeur('intervenant');;
if (result['debut']=='') result['debut']=0;
if (result['fin']=='') result['fin']=0;
if (result['status']=='') result['status']=0;
return result;
}

+ 525
- 0
frontend/src/scripts/api/items/todos.js Bestand weergeven

@ -0,0 +1,525 @@
itemFields['TODO'] = ['libelle','parent','client','intervenant','fin'];
function todoListLigne(item, style)
{
let retour = '';
let client = getNonNullTextValeur(item.client);
let intervenant = getTrigrammeCollaborateur(item.intervenant);
let texte = getNonNullTextValeur(item.libelle);
let date = item.fin;
let classe = 'class="js-open-modal-trigger" data-modal-info="type='+item.type+':id='+item.idlignes+'"';
let maintenant = formatDatetoStringDateTime(new Date);
let localStyle=style;
if (item.status == 3) localStyle = 'text-decoration: line-through';
// Si l'item n'est pas un jalon
// Si son début est dans le futur
// On affiche le début
if (item.type != 'TODO')
if (item.debut > maintenant)
date = item.debut;
// Ce qui est prévu pour aujourd'hui ou demain
// On affiche l'heure
if ((date.substring(0,8) == todayStringDate.substring(0,8))||(date.substring(0,8) == tomorrowStringDate.substring(0,8))) {
date = formatTimeFromStringDate(date)
} else {
date = formatLocaleDateFromStringDate(date);
}
if (intervenant != '')
if (intervenant != client)
texte = ' ['+intervenant+'] '+texte;
if (client != '') texte = '['+client+'] '+texte;
if (item.type == 'TODO')
texte = '[&diams;] '+texte;
else
texte = '[&curren;] '+texte;
retour += ' <tr '+classe+' style="'+localStyle+'">';
retour += ' <td style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-left:15px">'+texte+'</td>';
retour += ' <td style="width:100px;text-align:center">'+date+'</td>';
retour += ' </tr>';
return retour;
}
function todoListSection(section, style)
{
let retour = '';
retour += ' <tr style="'+style+'">';
retour += ' <td colspan="3" style="max-width:150px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-left:5px">'+section+'</td>';
retour += ' </tr>';
return retour;
}
function getNonNullTextValeur(valeur){
let val = valeur;
if ((val===null)||(val===undefined)) val = '';
return val;
}
function getNonNullDateValeur(valeur){
if (valeur === null) return '';
if (valeur == 0) return '';
return valeur;
}
function getInputLabel(nom, valeur, placeholder) {
return '<input style="width:99%;border:none" type="text" name="'+nom+'" id="item_'+nom+'" value="'+getNonNullTextValeur(valeur)+'" placeholder="'+getNonNullTextValeur(placeholder)+'"></input>';
}
function todoTermine(idlignes) {
myError('Fonction Obsolète : '+arguments.callee.name);
return itemTermine(idlignes,'TODO');
}
function todoSave(idlignes) {
let bodyJSON = JSON.stringify(getCurrentTODO(idlignes));
return itemAPI(idlignes, bodyJSON, itemInfo);
}
function getCurrentTODO(idlignes)
{
let result = new Object();
if (idlignes > 1) {
result['idlignes'] = idlignes;
} else {
result['type']=getContexteValeur('type_courant');
}
itemFields['TODO'].forEach(attribut => {
result[attribut] = documentGetElementById('item_'+attribut);
});
if (result['parent']=='') result['parent']=1;
if (result['client']=='') result['client']=getTrigrammeCollaborateur(result['intervenant']);
if (result['libelle']=='') result['libelle']='xxxxxxxxxxxx';
if (result['intervevant']=='') result['intervenant']=getContexteValeur('intervenant');;
if (result['fin']=='') result['fin']=0;
if (result['status']=='') result['status']=0;
return result;
}
datagrid_hooks['todos'] = function(){
let datagrid = document.querySelector('#datagrid');
let synthesis = document.querySelector('#synthesis_body');
let thisWeek = parseInt(stringdateGetWeekOfYear(todayStringDate));
let thisMonth = parseInt(todayStringDate.substring(0,6));
let thisYear = parseInt(todayStringDate.substring(0,4));
let client = getContexteValeur('client');
let termine = getContexteValeur('termine');
let nextWeek = thisWeek + 1;
let nextMonth = thisMonth + 1;
let nextYear = thisYear + 1;
let contenu='';
let synthese1='';
let synthese2='';
let nb_lignes=0;
let lignes_vides=0;
let liste_retard='';
let liste_today='';
let liste_tomorrow='';
let liste_thisWeek='';
let liste_nextWeek='';
let liste_thisMonth='';
let liste_nextMonth='';
let liste_thisYear='';
let liste_nextYear='';
let liste_noplanning = '';
let liste_before='';
let liste_finished='';
let liste_encours='';
let liste_todo='';
let tableau_before=[];
let tableau_finished=[];
let tableau_encours=[];
let tableau_todo=[];
let tableau_retard=[];
let tableau_today=[];
let tableau_tomorrow=[];
let tableau_thisWeek=[];
let tableau_nextWeek=[];
let tableau_thisMonth=[];
let tableau_nextMonth=[];
let tableau_thisYear=[];
let tableau_nextYear=[];
let tableau_noplanning=[];
let stats = 0;
// Gérer les fins d'année
if (nextWeek > parseInt(stringdateGetWeek(thisYear+'12310000'))) nextWeek = parseInt(nextYear+'01');
if (nextMonth > parseInt(thisYear+'12')) nextMonth = parseInt(nextYear+'01');
sortItemsByDate();
contenu += '<table>';
contenu += ' <thead>';
contenu += " <tr>";
contenu += ' <th colspan="2" onchange="updateValue(event)"><input id="newitem_input" type="text" placeholder="Nouvel item" style="width: 98%;outline: none"></th>';
contenu += " </tr>";
contenu += ' <tr>';
contenu += ' <th style="padding-left:5px"><span onclick="openFiltrePopup(\'libelle\')">Libellé</span></th>';
contenu += ' <th style="width:100px;text-align:center"><span onclick="openFiltrePopup(\'fin\')">Échéance</span></th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
liste = '';
items.forEach(element => {
let item = getItemFromElement(element);
let itemWeek = parseInt(stringdateGetWeekOfYear(item.fin.substring(0,8)));
let itemMonth = parseInt(item.fin.substring(0,6));
let itemYear = parseInt(item.fin.substring(0,4));
// On n'affiche pas la racine
if (item['idlignes']==1) return true;
// On n'affiche que ce qui est marqué comme visible
if (!item['visible']) return true;
// On n'affiche que les feuilles
if (item.childs.length>0) return true;
if (item.status == 1) return true;
if (item.status == 2) return true;
if (termine=='non')
if (item['status']==3) return true;
if (client!='')
if (item['client']!=client) return true;
// Ce qui est non planifié
if ((item.fin.substring(0,8) == '00000000')&&(item.status == 0)) {
tableau_noplanning.push(todoListLigne(item,'color:var(--nuance-sombre-06)'));
return true;
}
// Ce qui était pour avant cette année
if (item.fin.substring(0,8) < thisYear+'0101')
tableau_before.push(todoListLigne(item,''));
// Ce qui est terminé
if (item.status == 3)
tableau_finished.push(todoListLigne(item,''));
else
tableau_todo.push(todoListLigne(item,''));
// Ce qui est en retard
if ((item.status == 0)&&(item.fin < todayStringDate)) {
tableau_retard.push(todoListLigne(item,''));
return true;
}
// Ce qui est prévu pour aujourd'hui
if (((item.status == 0)||(item.status == 3))&&(item.fin.substr(0,8) == todayStringDate.substr(0,8))) {
tableau_today.push(todoListLigne(item,'font-weight:bold'));
return true;
}
// Ce qui est prévu pour demain
if (((item.status == 0)||(item.status == 3))&&(item.fin.substr(0,8) == tomorrowStringDate.substr(0,8))) {
tableau_tomorrow.push(todoListLigne(item,'font-weight:bold'));
return true;
}
// Ce qui est prévu cette semaine
if (item.fin.substring(0,8) > thisYear+'0101')
if (itemWeek == thisWeek) {
tableau_thisWeek.push(todoListLigne(item,'font-weight:bold'));
return true;
}
if (item.status != 0) return true;
// Les tâches qui ont commencé et qui ne sont pas finies
if (item.debut.substr(0,8) < todayStringDate.substr(0,8))
if (item.fin.substr(0,8) > todayStringDate.substr(0,8)) {
if (item.type != 'TODO') tableau_encours.push(todoListLigne(item,'font-weight:bold'));
return true;
}
// Ce qui est prévu la semaine prochaine
if (itemWeek == nextWeek) {
tableau_nextWeek.push(todoListLigne(item,'color:var(--nuance-sombre-09)'));
return true;
}
// Ce qui est prévu ce mois-ci
if (itemMonth == thisMonth) {
tableau_thisMonth.push(todoListLigne(item,'color:var(--nuance-sombre-09)'));
return true;
}
// Ce qui est prévu le mois prochain
if (itemMonth == nextMonth) {
tableau_nextMonth.push(todoListLigne(item,'color:var(--nuance-sombre-09)'));
return true;
}
// Ce qui est prévu cette année
if (itemYear == thisYear) {
tableau_thisYear.push(todoListLigne(item,'color:var(--nuance-sombre-09)'));
return true;
}
// Ce qui est prévu l'année prochaine
if (itemYear == nextYear) {
tableau_nextYear.push(todoListLigne(item,'color:var(--nuance-sombre-06)'));
return true;
}
return true;
});
if (tableau_before.length!=0){
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Avant<br>'+tableau_before.length+'</div>';
}
if (tableau_today.length!=0){
liste_today += tableau_today.join('');
nb_lignes += tableau_today.length;
}
stats=tableau_today.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox1">Aujourd\'hui<br>'+stats+'</div>';
if (tableau_tomorrow.length!=0){
liste_tomorrow += tableau_tomorrow.join('');
nb_lignes += tableau_tomorrow.length;
}
stats+=tableau_tomorrow.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox1">Demain<br>'+tableau_tomorrow.length+'</div>';
if (tableau_thisWeek.length!=0){
liste_thisWeek += tableau_thisWeek.join('');
nb_lignes += tableau_thisWeek.length;
}
stats+=tableau_thisWeek.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox1">Cette semaine<br>'+stats+'</div>';
if (tableau_nextWeek.length!=0){
liste_nextWeek += tableau_nextWeek.join('');
nb_lignes += tableau_nextWeek.length;
}
stats+=tableau_nextWeek.length;
if (tableau_thisMonth.length!=0){
liste_thisMonth += tableau_thisMonth.join('');
nb_lignes += tableau_thisMonth.length;
}
stats+=tableau_thisMonth.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Ce mois-ci<br>'+stats+'</div>';
if (tableau_nextMonth.length!=0){
liste_nextMonth += tableau_nextMonth.join('');
nb_lignes += tableau_nextMonth.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Mois Prochain<br>'+tableau_nextMonth.length+'</div>';
}
stats+=tableau_nextMonth.length;
if (tableau_thisYear.length!=0){
liste_thisYear += tableau_thisYear.join('');
nb_lignes += tableau_thisYear.length;
}
stats+=tableau_thisYear.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Cette année<br>'+stats+'</div>';
if (tableau_nextYear.length!=0){
liste_nextYear += tableau_nextYear.join('');
nb_lignes += tableau_nextYear.length;
if (synthese1=='') synthese1+='<div class="statrow">';
synthese1+='<div class="statbox2">Après<br>'+tableau_nextYear.length+'</div>';
}
if (tableau_finished.length != 0){
liste_finished += tableau_retard.join('');
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox1">Terminé<br>'+tableau_finished.length+'</div>';
}
if (tableau_retard.length != 0){
liste_retard += tableau_retard.join('');
nb_lignes += tableau_retard.length;
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox1">En retard<br>'+tableau_retard.length+'</div>';
}
if (tableau_encours.length != 0){
liste_encours += tableau_encours.join('');
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox1">En cours<br>'+tableau_encours.length+'</div>';
}
if (tableau_todo.length != 0){
liste_todo += tableau_todo.join('');
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox1">A faire<br>'+tableau_todo.length+'</div>';
}
if (tableau_noplanning.length !=0) {
liste_noplanning += tableau_noplanning.join('');
nb_lignes += tableau_noplanning.length;
if (synthese2=='') synthese2+='<div class="statrow" style="margin-top: 5px">';
synthese2+='<div class="statbox2">Non-Planifiés<br>'+tableau_noplanning.length+'</div>';
}
if (synthese1!='') synthese1+='</div>';
if (synthese2!='') synthese2+='</div>';
lignes_vides = nb_lignes;
if (liste_retard != '')
{
contenu += todoListSection('En retard', '');
contenu += liste_retard;
lignes_vides += 1;
}
if (liste_encours != '')
{
contenu += todoListSection('En cours', 'font-weight:bold');
contenu += liste_encours;
lignes_vides += 1;
}
if (liste_today != '')
{
contenu += todoListSection('Aujourd\'hui', 'font-weight:bold');
contenu += liste_today;
lignes_vides += 1;
}
if (liste_tomorrow != '')
{
contenu += todoListSection('Demain', 'font-weight:bold');
contenu += liste_tomorrow;
lignes_vides += 1;
}
if (liste_thisWeek != '')
{
contenu += todoListSection('Cette semaine', 'font-weight:bold');
contenu += liste_thisWeek;
lignes_vides += 1;
}
if (liste_nextWeek != '')
{
contenu += todoListSection('La semaine prochaine', 'color:var(--nuance-sombre-09)');
contenu += liste_nextWeek;
lignes_vides += 1;
}
if (liste_thisMonth != '')
{
contenu += todoListSection('Ce mois-ci', 'color:var(--nuance-sombre-09)');
contenu += liste_thisMonth;
lignes_vides += 1;
}
if (liste_nextMonth != '')
{
contenu += todoListSection('Le mois prochain', 'color:var(--nuance-sombre-09)');
contenu += liste_nextMonth;
lignes_vides += 1;
}
if (liste_thisYear != '')
{
contenu += todoListSection('Cette année', 'color:var(--nuance-sombre-09)');
contenu += liste_thisYear;
lignes_vides += 1;
}
if (liste_nextYear != '')
{
contenu += todoListSection('L\'année prochaine', 'color:var(--nuance-sombre-06)');
contenu += liste_nextYear;
lignes_vides += 1;
}
if (liste_noplanning != '')
{
// On ne place un titre de section que s'il existe des tâches planifiées ...
if (nb_lignes != lignes_vides)
contenu += todoListSection('Non planifié', 'color:var(--nuance-sombre-06)');
contenu += liste_noplanning;
lignes_vides += 1;
}
while(lignes_vides < 30)
{
contenu += ' <tr>';
contenu += ' <td colspan="3">&nbsp;</td>';
contenu += ' </tr>';
lignes_vides += 1;
}
contenu += ' </tbody>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th colspan="3">'+setLevelPadding(2)+''+(nb_lignes-1)+' tâches</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
synthesis.innerHTML = synthese1+synthese2;
datagrid.innerHTML = contenu;
// Ne marche pas , ça enlève le stick du header du tableau ...
// document.getElementById('newitem_input').focus({preventScroll: true});
}
item_save_hooks['TODO'] = todoSave;
items_edit_hooks['TODO_OLD'] = function (id, libelle) {
let modal_header='Todo n°<b>'+id+'</b>';
let modal_body='TODO inconnu !';
let modal_footer='<div align="right" width="100%" style="padding-top:2vh"><button onclick="todoSave('+id+')">Enregistrer</button></div>';
let local_values = [];
local_values['parent']=getContexteValeur('parent');
local_values['type']=getContexteValeur('type_courant');
local_values['intervenant']=getContexteValeur('intervenant');
local_values['client']=getTrigrammeCollaborateur(local_values['intervenant']);
local_values['libelle']=libelle;
items.filter(item => item.idlignes == id).forEach(resultat => {
local_values['type']=resultat['type'];
itemFields[local_values['type']].forEach(attribut => {
local_values[attribut]=resultat[attribut];
});
});
modal_body = '<table class="modal_table"><form id="formulaire_lignes">';
itemFields[local_values['type']].forEach(attribut => {
modal_body += '<tr><td>'+attribut+'</td><td>'+getInputLabel(attribut,local_values[attribut])+'</td></tr>';
});
modal_body += '</form></table>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
if (!modalDialog.open) modalDialog.showModal();
}

+ 79
- 0
frontend/src/scripts/api/status.js Bestand weergeven

@ -0,0 +1,79 @@
var allStatus;
function getStatusLibelleFromId(idstatus){
let filtre = allStatus.filter(status => status.idstatus == idstatus);
return (filtre[0]?.libelle ?? "Inconnu");
}
function setStatus(data){
allStatus = data;
}
getEntities('status', setStatus);
function initDatagridStatus() {
setStatus(null);
datagridLoading();
getEntities('status', __initDatagridStatus);
}
function __initDatagridStatus(data) {
let element = document.querySelector('#datagrid');
let contenu='';
setStatus(data);
contenu += '<table>';
contenu += ' <thead>';
contenu += ' <tr>';
contenu += ' <th>Id</th>';
contenu += ' <th>Status</th>';
contenu += ' </tr>';
contenu += ' </thead>';
contenu += ' <tbody>';
allStatus.forEach(status => {
contenu += ' <tr class="js-open-modal-trigger" data-modal-info="status:id='+status.idstatus+'">';
contenu += ' <td>'+status.idstatus+'</td>';
contenu += ' <td>'+status.libelle+'</td>';
contenu += ' </tr>';
});
contenu += ' </body>';
contenu += ' <tfoot>';
contenu += ' <tr>';
contenu += ' <th colspan="2">&nbsp;</th>';
contenu += ' </tr>';
contenu += ' </foot>';
contenu += '</table>';
element.innerHTML = contenu;
init_modal();
}
modal_hooks['status'] = function(parametres){
let paramSplit = parametres.split(',');
paramSplit.forEach(element => {
let elemSplit=element.split('=');
if (elemSplit[0] === 'id') {
let id = elemSplit[1];
let modal_header='Fiche status ['+id+']';
let modal_body='status inconnu !';
let modal_footer='<button>Enregistrer</button';
statuss.filter(status => status.idstatus == id)
.forEach(resultat => {
modal_body = '<table class="modal_table">';
modal_body += '<tr><td style="width:30%">Id</td><td>'+resultat.idstatus+'</td></tr>';
modal_body += '<tr><td style="width:30%">Code</td><td>'+resultat.libelle+'</td></tr>';
modal_body += '</table>';
});
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
}
});
};

+ 11
- 0
frontend/src/scripts/ariane.js Bestand weergeven

@ -0,0 +1,11 @@
function setFilAriane(ariane){
let contenant = document.querySelector('nav>#ariane>#fil');
if (contenant != null) {
let fil = '';
ariane.forEach(element => {
fil += ' <span><a onclick="activeMenu(this)">'+element+'</a></span> >';
});
contenant.innerHTML = fil.slice(0,-2);
}
return true;
}

+ 15
- 0
frontend/src/scripts/contexte.js Bestand weergeven

@ -0,0 +1,15 @@
// ----------------------------------------------------------------------
// ---- Le contexte contient un ensemble de paramétres
// ---- qui contextualisent globalement le coportment de la page
// ----------------------------------------------------------------------
var contexte = new Object();
function setContexteValeur(parametre, valeur)
{
contexte[parametre] = valeur;
}
function getContexteValeur(parametre)
{
return contexte[parametre];
}

+ 497
- 0
frontend/src/scripts/default.js Bestand weergeven

@ -0,0 +1,497 @@
window.addEventListener('load', function() {
window.scrollTo(0,0);
}, false);
/*
* Personnalisation
* Que se passe-t-il lorsque la bannière est invisible ?
*/
function setLogoVisiblity(visibilityFlag) {
let element = document.querySelector("nav>*>#settings");
let value = 'hidden';
if (visibilityFlag) value = "visible";
element.style.visibility = value;
}
function setNavbarStickOnTop(topFlag) {
let element = document.querySelector("#nav");
if (topFlag) element.style.setProperty('top', '0px');
else element.style.removeProperty('top');
}
function setDataGridFootSticky(stickyFlag) {
let element = null;
if (stickyFlag) {
//
// Mettre le tfoot sticky au bottom
//
element = document.querySelector("#datagrid>table>tfoot");
element.style.setProperty('position', 'sticky');
element.style.setProperty('bottom', '0px');
element.style.setProperty('z-index', '30');
} else {
element = document.querySelector("#datagrid>table>tfoot");
element.style.setProperty('position', 'relative');
element.style.setProperty('z-index', '10');
}
}
/*
* Personnalisation
* Que se passe-t-il lorsque la synthèse est invisible ?
*/
function setDatagridFirstColSticky(stickyFlag) {
let element = null;
if (stickyFlag) {
/*
* Mettre la première case sticky au top left
*/
element = document.querySelector("#datagrid>table>thead>tr>th:first-child");
element.style.setProperty('position', 'sticky');
element.style.setProperty('left', '0px');
element.style.setProperty('z-index', '30');
//
// Mettre la dernière case sticky au bottom left
//
element = document.querySelector("#datagrid>table>tfoot>tr>th:first-child");
element.style.setProperty('position', 'sticky');
element.style.setProperty('left', '0px');
element.style.setProperty('z-index', '30');
} else {
element = document.querySelector("#datagrid>table>thead>tr>th:first-child");
element.style.setProperty('position', 'sticky');
element.style.setProperty('left', '0px');
element.style.setProperty('z-index', '10');
element = document.querySelector("#datagrid>table>tfoot>tr>th:first-child");
element.style.setProperty('position', 'sticky');
element.style.setProperty('left', '0px');
element.style.setProperty('z-index', '10');
}
}
function setDatagridHeadSticky(stickyFlag) {
let element = document.querySelector("#datagrid>table>thead");
let navbar = document.querySelector("nav");
let offset = navbar.offsetHeight;
if (stickyFlag) {
/*
* Mettre le thead sticky au top
*/
//element = document.querySelector("#datagrid>table>thead");
element.style.setProperty('position', 'sticky');
element.style.setProperty('top', offset+'px');
element.style.setProperty('z-index', '30');
} else {
//element = document.querySelector("#datagrid>table>thead");
element.style.setProperty('position', 'relative');
element.style.setProperty('top', '0px');
element.style.setProperty('z-index', '10');
}
}
function smoothJump(hash) {
location.replace("#" + hash);
}
function documentGetElementById(id){
element = document.getElementById(id);
if (element === null ) return '';
return element.value;
}
function setElementHeight(elementSelector, elementHeight) {
let element = document.querySelector(elementSelector);
element.style.height = elementHeight;
}
function slideElement(elementSelector, elementHeight) {
let element = document.querySelector(elementSelector);
element.style.transition = "all 2s ease-in-out";
setElementHeight(elementSelector, elementHeight);
}
function scrollToElement(elementSelector) {
let element = document.querySelector(elementSelector);
element.scrollIntoView({ behavior: 'smooth' });
}
function gotoHelp() {
scrollToElement('#synthesis');
setTimeout(scrollToElement, 500, '#footer');
}
function gotoTop() {
let element = document.querySelector('header');
window.scrollTo(0, element.offsetHeight + 1);
}
function headerIsVisible(flagVisible) {
setLogoVisiblity(!flagVisible);
if (!flagVisible) gotoTop();
}
function synthesisTopIsNowVisible(entry) {
setDatagridHeadSticky(false);
setDataGridFootSticky(false);
/*
setDatagridFirstColSticky(true);
*/
myLog('Trigger synthesis is visible');
}
function synthesisTopIsNowInvisible(entry) {
setDatagridHeadSticky(true);
setDataGridFootSticky(true);
/*
setDatagridFirstColSticky(true);
*/
myLog('Trigger synthesis is invisible');
}
function initDatagrid()
{
let type = getContexteValeur('type');
switch(type){
case 'TODO':
initDatagridTodos();
break;
default:
initDatagridItems();
break;
}
}
function changeModeAffichage(valeur, texte)
{
let type='TODO';
switch(valeur){
case 'absences':
case 'releases':
case 'rdv':
case 'feries':
case 'taches':
type='TACHE';
break;
}
setContexteValeur('mode_affichage', valeur);
setContexteValeur('type_courant', type);
setFiltreValeur('type',type);
setFilAriane(['Home', 'List', texte]);
return afficherItems();
}
function changeModeAffichageEvent(e)
{
return changeModeAffichage(e.target.value, e.target.options[e.target.selectedIndex].text);
}
function changeAffichageItemsTermine(e)
{
setContexteValeur('termine', e.target.value);
setFiltreValeur('status',e.target.value);
afficherItems();
}
function changeAffichageItemsPrestations(e)
{
setContexteValeur('prestation', e.target.value);
afficherItems();
}
function changeFiltreClient(e)
{
let valeur = e.target.value;
if (valeur == 'ALL') valeur='';
setContexteValeur('client', valeur);
setFiltreValeur('client', valeur);
afficherItems();
}
function changeAffichageNiveauxEvent(e)
{
setContexteValeur('level', e.target.value);
setFiltreValeur('level', e.target.value);
afficherItems();
}
function changeCalendarEvent(e)
{
let valeur = todayStringDate;
switch(parseInt(e.target.value)) {
case 2 :
valeur = todayStringDate.substring(0,4)+'0101';
break;
}
setContexteValeur('debut',valeur);
setFiltreValeur('debut', valeur);
afficherItems();
}
function updateValue(e) {
if (e.target.value != '') editerItem(-1, e.target.value);
e.target.value = '';
}
function afficher_synthese(mode) {
let synthesis_body = document.querySelector('#synthesis_body');
if (synthesis_body) {
synthesis_body.innerHTML='';
let template = document.querySelector('#synthesis_body_' + mode);
if (template) {
let contenu = document.importNode(template.content, true);
if (contenu) synthesis_body.appendChild(contenu);
}
}
}
function afficher_footer(mode) {
let footer_body = document.querySelector('footer');
if (footer_body) {
footer_body.innerHTML='';
let template = document.querySelector('#footer_' + mode);
if (template) {
let contenu = document.importNode(template.content, true);
if (contenu) footer_body.appendChild(contenu);
}
}
}
function activeMenu(element) {
datagridEmptyLines(50);
activeMode(element.innerText);
gotoTop();
}
function modeToAffichage(mode)
{
let retour='taches';
switch (mode) {
case 'Releases':
retour='releases';
break;
case 'Hollidays':
retour='feries';
break;
case 'Rendez-Vous':
retour='rdv';
break;
case 'Rendez-Vous':
retour='rdv';
break;
case 'Items':
retour='items';
break;
case 'Project':
retour='prestations';
break;
default:
case 'Tasks':
retour='taches';
break;
}
return retour;
}
function activeMode(mode) {
setContexteValeur('type_courant', 'TODO');
setContexteValeur('items_type', 'items');
switch (mode) {
case 'Tree':
case 'TreeList' :
case 'List':
mode='Tasks';
case 'Tasks':
case 'Releases':
case 'Hollidays':
case 'Rendez-Vous':
case 'Items':
setContexteValeur('mode_feuille', false);
setContexteValeur('type_courant', 'TACHE');
setContexteValeur('mode_affichage', modeToAffichage(mode));
afficher_synthese('taches');
afficher_footer('taches');
setFilAriane(['Home', 'TreeList', mode]);
initDatagridItems();
break;
case 'Project':
setContexteValeur('mode_feuille', false);
setContexteValeur('termine', true);
setContexteValeur('prestation', true);
setContexteValeur('type_courant', 'PRESTATION');
setContexteValeur('mode_affichage', modeToAffichage(mode));
afficher_synthese('project');
afficher_footer('taches');
setFilAriane(['Home', 'Project']);
initDatagridItems();
break;
case 'Plan':
case 'Planning':
setFilAriane([mode]);
setContexteValeur('type_courant', 'TODO');
setContexteValeur('mode_feuille', true);
setContexteValeur('mode_affichage', 'planning');
setContexteValeur('termine', 'non');
afficher_synthese('planning');
afficher_footer('planning');
initDatagridItems();
break;
case 'Calendar':
setFilAriane(['Todo', mode]);
setContexteValeur('mode_feuille', true);
setContexteValeur('mode_affichage', 'calendar_intervenants');
setContexteValeur('debut', todayStringDate);
afficher_synthese('calendrier');
afficher_footer('calendrier');
initDatagridItems();
break;
case 'Administration':
setFilAriane(['Todo', mode]);
initAdministration();
break;
case 'Status':
setFilAriane(['Todo', 'Administration', mode]);
initDatagridStatus();
break;
case 'Clients':
setFilAriane(['Todo', 'Administration', mode]);
initDatagridClients();
break;
case 'Collaborateurs':
setFilAriane(['Todo', 'Administration', mode]);
initDatagridCollaborateurs();
break;
default:
case 'Home':
mode='Todo';
case 'Todo':
setFilAriane(['Home', mode]);
setDefaultContext();
setContexteValeur('type', 'TODO');
setContexteValeur('items_type', 'todos');
setContexteValeur('mode_affichage', 'todos');
setContexteValeur('mode_feuille', true);
setContexteValeur('parent', '1');
afficher_synthese('accueil');
afficher_footer('accueil');
initDatagridItems();
break;
}
}
function initAdministration() {
let element = document.querySelector('#synthesis_middle');
contenu = '<div style="padding:0px 10px;display: flex;flex-wrap: nowrap;justify-content: space-between;">';
contenu += '<a onclick="activeMenu(this)">Status</a>';
contenu += '<a onclick="activeMenu(this)">Clients</a>';
contenu += '<a onclick="activeMenu(this)">Collaborateurs</a>';
contenu += '</div>';
element.innerHTML = contenu;
}
function setDefaultContext()
{
// Contexte de départ
setContexteValeur('level', '9999');
setContexteValeur('parent', '1');
setContexteValeur('parent_level','0');
setContexteValeur('client', '');
setContexteValeur('termine', 'oui');
}
// UI
setLogoVisiblity(false);
// Contexte de départ
setContexteValeur('intervenant', 'Anonymous');
init_filtres(['type','client','debut','fin','level'])
// GO !
activeMode('Todo');
// Get the CSS root element
const rootCSS = document.querySelector(':root');
// Create a function for getting a variable value
function CSSgetSombre() {
let rs = getComputedStyle(rootCSS);
alert("The value of --couleur-sombre is: " + rs.getPropertyValue('--couleur-sombre'));
}
function CSSsetSombre(vr, vg, vb) {
// Couleur
rootCSS.style.setProperty('--r-sombre', vr);
rootCSS.style.setProperty('--g-sombre', vg);
rootCSS.style.setProperty('--b-sombre', vb);
// Logo
// let logo = document.querySelector('header>#logo>svg');
// if (logo) logo.style.fill = 'rgb(' + vr + ',' + vg + ',' + vb + ')';
}
function CSSsetClair(vr, vg, vb) {
// Couleur
rootCSS.style.setProperty('--r-clair', vr);
rootCSS.style.setProperty('--g-clair', vg);
rootCSS.style.setProperty('--b-clair', vb);
}
function CSSswitchCouleurTexte() {
let rs = getComputedStyle(rootCSS);
let actuel = rs.getPropertyValue('--couleur-texte');
if (actuel == 'black')
rootCSS.style.setProperty('--couleur-texte', 'var(--couleur-sombre)');
else
rootCSS.style.setProperty('--couleur-texte', 'black');
}

+ 71
- 0
frontend/src/scripts/filtres.js Bestand weergeven

@ -0,0 +1,71 @@
var filtres = [];
function setFiltreValeur(filtre, valeur)
{
myError('setFiltreValeur est obsolète ! ['+filtre+' , '+ valeur+'] ')
filtres[filtre] = valeur;
}
function getFiltreValeur(filtre)
{
myError('getFiltreValeur est obsolète ! ['+filtre+'] ');
return filtres[filtre];
}
function init_filtres(liste){
liste.forEach((element=>{
filtres[element]='';
}));
}
function addDefaultFiltre(index, valeur){
let retour = '';
retour += '<tr><td>';
retour += '<label for="filtre_'+index+'">'+index+'</label>';
retour += '</td><td>';
retour += '<input type="" id="filtre_'+index+'" name="filtre_'+index+'" value="'+valeur+'"></inputl>';
retour += '</td></tr>';
return retour;
}
function openFiltrePopup(filtre)
{
let modal_header='Filtrer les items';
let modal_body='';
let modal_footer='<div align="right" width="100%" style="padding-top:2vh"><button onclick="applyFiltre()">Enregistrer</button></div>';
modal_body += '<table>';
Object.entries(filtres).forEach(element=>{
const [index,valeur] = element;
switch(index) {
default:
modal_body += addDefaultFiltre(index, valeur);
}
});
modal_body += '</table>';
modalSetHeader(modal_header);
modalSetBody(modal_body);
modalSetFooter(modal_footer);
if (!modalDialog.open) modalDialog.showModal();
}
function applyFiltre(){
Object.entries(filtres).forEach(element=>{
const [index,valeur] = element;
let new_valeur=valeur;
switch(index) {
default:
let input_valeur = document.querySelector('#filtre_' + index);
if (input_valeur) new_valeur=input_valeur.value;
}
filtres[index] = new_valeur;
});
afficherItems();
}

+ 13
- 0
frontend/src/scripts/parametres.js Bestand weergeven

@ -0,0 +1,13 @@
// ----------------------------------------------------------------------
// ---- Obsolète !
// ---- A remplacer par la notion de contexte
// ----------------------------------------------------------------------
function setParametreValeur(parametre, valeur)
{
return setContexteValeur(parametre, valeur)
}
function getParametreValeur(parametre)
{
return getContexteValeur(parametre);
}

+ 128
- 0
frontend/src/scripts/tools/dates.js Bestand weergeven

@ -0,0 +1,128 @@
function stringDatePadDigits(num, digits) {
return num.toString().padStart(digits, '0');
}
function formatDatetoStringDateTime(uneDate){
let temp = '';
if (uneDate) {
temp += uneDate.getFullYear();
temp += ''+stringDatePadDigits(uneDate.getMonth()+1,2);
temp += ''+stringDatePadDigits(uneDate.getDate(),2);
temp += ''+stringDatePadDigits(uneDate.getHours(),2);
temp += ''+stringDatePadDigits(uneDate.getMinutes(),2);
}
temp += '000000000000';
return temp.substring(0,12);
}
function formatTimeFromStringDate(uneStringDate) {
let retour ='';
if ('0000' == uneStringDate.substring(8,12)) retour='-';
else retour = uneStringDate.substring(8,10)+':'+uneStringDate.substring(10,12);
return retour;
}
function formatDatetoStringDate(uneDate){
let temp = formatDatetoStringDateTime(uneDate);
return temp.substring(0,8);
return temp.substring(0,8)+'0000';
}
function formatLocaleDateFromStringDate(uneStringDate) {
if (uneStringDate.substring(0,8) == '00000000') return '-';
if (uneStringDate.substring(0,8) == '99999999') return '-';
return uneStringDate.substring(6,8) +'/'+uneStringDate.substring(4,6)+'/'+uneStringDate.substring(0,4);
}
function stringdateToDate(uneStringDate) {
let retour = new Date();
retour.setFullYear(parseInt(uneStringDate.substring(0,4)));
retour.setMonth(parseInt(uneStringDate.substring(4,6))-1);
retour.setDate(parseInt(uneStringDate.substring(6,8)));
retour = new Date(parseInt(uneStringDate.substring(0,4)), parseInt(uneStringDate.substring(4,6))-1, parseInt(uneStringDate.substring(6,8)))
return retour;
}
function stringdateGetDayOfYear(uneStringDate){
let currentYear = uneStringDate.substring(0,4);
let currentDate = stringdateToDate(uneStringDate);
let startDate = new Date(parseInt(currentYear), 0, 4);
return currentYear+stringDatePadDigits(Math.floor((currentDate - startDate) / (24 * 60 * 60 * 1000)),3);
}
function stringdateGetWeekOfYear(uneStringDate) {
let currentDayOfYear = dateGetPrevMonday(stringdateToDate(uneStringDate));
let startDayOfYear = dateGetPrevMonday(stringdateToDate(currentDayOfYear.getUTCFullYear()+'0104'));
let weekNo = Math.ceil(((currentDayOfYear-startDayOfYear) / 86400000 + 1) / 7);;
return startDayOfYear.getUTCFullYear() * 100 + weekNo;
}
function stringdateGetWeek(uneStringDate) {
myError('Fonction Obsolète : '+arguments.callee.name);
return stringdateGetWeekOfYear(uneStringDate);
}
function dateGetToday(){
let today = now.getDate();
today.setHours(0, 0, 0, 0);
return today;
}
function dateGetTomorrow(){
let now = new Date();
let today = now.getDate();
let tomorrow = new Date(now);
tomorrow.setDate(today + 1);
tomorrow.setHours(0, 0, 0, 0);
return tomorrow;
}
function dateGetLastDayOfWeek(uneDate, dayOfWeek){
let last = uneDate;
last.setHours(0, 0, 0, 0);
while(last.getDay() != dayOfWeek) {
last.setDate(last - 1)
}
return last;
}
function dateGetNextDayOfWeek(uneDate, dayOfWeek){
let next = uneDate;
next.setHours(0, 0, 0, 0);
while(next.getDay() != dayOfWeek) {
next.setDate(next - 1)
}
return next;
}
function dateGetPrevMonday(uneDate){
// return dateGetLastDayOfWeek(uneDate, 1);
let lastMonday = uneDate;
let daysDiff = uneDate.getDay() - 1;
lastMonday.setDate(uneDate.getDate() - (daysDiff > 0 ? daysDiff : (daysDiff * -6)));
lastMonday.setHours(0, 0, 0, 0);
return lastMonday;
}
function customParseFloat(valeur) {
let retour = valeur;
if (retour === null) retour = 0;
if (isNaN(retour)) retour = 0;
return parseFloat(retour);
}
function convertJourHeure(valeur) {
let retour = customParseFloat(valeur);
if (retour < 1.0) {
retour = (retour/0.125)+'H';
} else {
retour = retour+'J';
}
return retour;
}
const todayStringDate = formatDatetoStringDate(new Date());
const tomorrowStringDate = formatDatetoStringDate(dateGetTomorrow());

+ 27
- 0
frontend/src/scripts/tools/delai.js Bestand weergeven

@ -0,0 +1,27 @@
/*
* Fonction pour introduire une attente
* usage : await delai(1000);
*/
function delai(milliseconds){
return new Promise(resolve => {
setTimeout(resolve, milliseconds);
});
}
var waitLoop = (ms) => {
const start = Date.now();
let now = start;
while (now - start < ms) {
now = Date.now();
}
}
async function attendre1(milliseconds)
{
await delai(milliseconds);
}
function attendre(milliseconds)
{
waitLoop(milliseconds);
}

+ 10
- 0
frontend/src/scripts/tools/logs.js Bestand weergeven

@ -0,0 +1,10 @@
var useLog=false;
var useError=true;
function myLog(message) {
if (useLog)
console.log(message);
}
function myError(message) {
if (useError)
console.error(message);
}

+ 19
- 0
frontend/src/scripts/tools/postData.js Bestand weergeven

@ -0,0 +1,19 @@
// Example POST method implementation:
async function postData(url = "", data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "cors", // no-cors, *cors, same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: "follow", // manual, *follow, error
referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}

+ 10
- 0
frontend/src/scripts/tools/svg-inject.min.js Bestand weergeven

@ -0,0 +1,10 @@
!function(o,l){var r,a,s="createElement",g="getElementsByTagName",b="length",E="style",d="title",y="undefined",k="setAttribute",w="getAttribute",x=null,A="__svgInject",C="--inject-",S=new RegExp(C+"\\d+","g"),I="LOAD_FAIL",t="SVG_NOT_SUPPORTED",L="SVG_INVALID",v=["src","alt","onload","onerror"],j=l[s]("a"),G=typeof SVGRect!=y,f={useCache:!0,copyAttributes:!0,makeIdsUnique:!0},N={clipPath:["clip-path"],"color-profile":x,cursor:x,filter:x,linearGradient:["fill","stroke"],marker:["marker",
"marker-end","marker-mid","marker-start"],mask:x,pattern:["fill","stroke"],radialGradient:["fill","stroke"]},u=1,c=2,O=1;function T(e){return(r=r||new XMLSerializer).serializeToString(e)}function P(e,r){var t,n,i,o,a=C+O++,f=/url\("?#([a-zA-Z][\w:.-]*)"?\)/g,u=e.querySelectorAll("[id]"),c=r?[]:x,l={},s=[],d=!1;if(u[b]){for(i=0;i<u[b];i++)(n=u[i].localName)in N&&(l[n]=1);for(n in l)(N[n]||[n]).forEach(function(e){s.indexOf(e)<0&&s.push(e)});s[b]&&s.push(E);var v,p,m,h=e[g]("*"),y=e;for(i=-1;y!=x;
){if(y.localName==E)(m=(p=y.textContent)&&p.replace(f,function(e,r){return c&&(c[r]=1),"url(#"+r+a+")"}))!==p&&(y.textContent=m);else if(y.hasAttributes()){for(o=0;o<s[b];o++)v=s[o],(m=(p=y[w](v))&&p.replace(f,function(e,r){return c&&(c[r]=1),"url(#"+r+a+")"}))!==p&&y[k](v,m);["xlink:href","href"].forEach(function(e){var r=y[w](e);/^\s*#/.test(r)&&(r=r.trim(),y[k](e,r+a),c&&(c[r.substring(1)]=1))})}y=h[++i]}for(i=0;i<u[b];i++)t=u[i],c&&!c[t.id]||(t.id+=a,d=!0)}return d}function V(e,r,t,n){if(r){
r[k]("data-inject-url",t);var i=e.parentNode;if(i){n.copyAttributes&&function c(e,r){for(var t,n,i,o=e.attributes,a=0;a<o[b];a++)if(n=(t=o[a]).name,-1==v.indexOf(n))if(i=t.value,n==d){var f,u=r.firstElementChild;u&&u.localName.toLowerCase()==d?f=u:(f=l[s+"NS"]("http://www.w3.org/2000/svg",d),r.insertBefore(f,u)),f.textContent=i}else r[k](n,i)}(e,r);var o=n.beforeInject,a=o&&o(e,r)||r;i.replaceChild(a,e),e[A]=u,m(e);var f=n.afterInject;f&&f(e,a)}}else D(e,n)}function p(){for(var e={},r=arguments,
t=0;t<r[b];t++){var n=r[t];for(var i in n)n.hasOwnProperty(i)&&(e[i]=n[i])}return e}function _(e,r){if(r){var t;try{t=function i(e){return(a=a||new DOMParser).parseFromString(e,"text/xml")}(e)}catch(o){return x}return t[g]("parsererror")[b]?x:t.documentElement}var n=l.createElement("div");return n.innerHTML=e,n.firstElementChild}function m(e){e.removeAttribute("onload")}function n(e){console.error("SVGInject: "+e)}function i(e,r,t){e[A]=c,t.onFail?t.onFail(e,r):n(r)}function D(e,r){m(e),i(e,L,r)
}function F(e,r){m(e),i(e,t,r)}function M(e,r){i(e,I,r)}function q(e){e.onload=x,e.onerror=x}function R(e){n("no img element")}var e=function z(e,r){var t=p(f,r),h={};function n(a,f){f=p(t,f);var e=function(r){var e=function(){var e=f.onAllFinish;e&&e(),r&&r()};if(a&&typeof a[b]!=y){var t=0,n=a[b];if(0==n)e();else for(var i=function(){++t==n&&e()},o=0;o<n;o++)u(a[o],f,i)}else u(a,f,e)};return typeof Promise==y?e():new Promise(e)}function u(u,c,e){if(u){var r=u[A];if(r)Array.isArray(r)?r.push(e
):e();else{if(q(u),!G)return F(u,c),void e();var t=c.beforeLoad,n=t&&t(u)||u[w]("src");if(!n)return""===n&&M(u,c),void e();var i=[];u[A]=i;var l=function(){e(),i.forEach(function(e){e()})},s=function f(e){return j.href=e,j.href}(n),d=c.useCache,v=c.makeIdsUnique,p=function(r){d&&(h[s].forEach(function(e){e(r)}),h[s]=r)};if(d){var o,a=function(e){if(e===I)M(u,c);else if(e===L)D(u,c);else{var r,t=e[0],n=e[1],i=e[2];v&&(t===x?(t=P(r=_(n,!1),!1),e[0]=t,e[2]=t&&T(r)):t&&(n=function o(e){
return e.replace(S,C+O++)}(i))),r=r||_(n,!1),V(u,r,s,c)}l()};if(typeof(o=h[s])!=y)return void(o.isCallbackQueue?o.push(a):a(o));(o=[]).isCallbackQueue=!0,h[s]=o}!function m(e,r,t){if(e){var n=new XMLHttpRequest;n.onreadystatechange=function(){if(4==n.readyState){var e=n.status;200==e?r(n.responseXML,n.responseText.trim()):400<=e?t():0==e&&t()}},n.open("GET",e,!0),n.send()}}(s,function(e,r){var t=e instanceof Document?e.documentElement:_(r,!0),n=c.afterLoad;if(n){var i=n(t,r)||t;if(i){
var o="string"==typeof i;r=o?i:T(t),t=o?_(i,!0):i}}if(t instanceof SVGElement){var a=x;if(v&&(a=P(t,!1)),d){var f=a&&T(t);p([a,r,f])}V(u,t,s,c)}else D(u,c),p(L);l()},function(){M(u,c),p(I),l()})}}else R()}return G&&function i(e){var r=l[g]("head")[0];if(r){var t=l[s](E);t.type="text/css",t.appendChild(l.createTextNode(e)),r.appendChild(t)}}('img[onload^="'+e+'("]{visibility:hidden;}'),n.setOptions=function(e){t=p(t,e)},n.create=z,n.err=function(e,r){e?e[A]!=c&&(q(e),G?(m(e),M(e,t)):F(e,t),r&&(m(
e),e.src=r)):R()},o[e]=n}("SVGInject");"object"==typeof module&&"object"==typeof module.exports&&(module.exports=e)}(window,document);

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

Laden…
Annuleren
Opslaan