LinkGenerator.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <template>
  2. <v-layout justify-center align-center>
  3. <v-flex xs12 sm8>
  4. <!-- Link encoder -->
  5. <v-card>
  6. <v-container fluid fill-height>
  7. <v-layout column align-center>
  8. <v-card-title class="headline d-block text-md-center font-weight-bold">Link generator</v-card-title>
  9. <v-card-text>
  10. <v-form>
  11. <h2>*Host configuration</h2>
  12. <v-text-field
  13. v-model="encoder.webAppUrl"
  14. label="*Web application link"
  15. />
  16. <v-text-field
  17. v-model="encoder.hostConfig"
  18. label="*Server link"
  19. />
  20. <h2>User ID and experiment ID</h2>
  21. <v-layout row wrap>
  22. <v-flex xs4>
  23. <v-checkbox
  24. v-model="encoder.userId.activated"
  25. color="primary"
  26. label="User ID"
  27. />
  28. </v-flex>
  29. <v-spacer />
  30. <v-flex xs8>
  31. <v-text-field
  32. v-model="encoder.userId.value"
  33. label="User ID"
  34. type="text"
  35. :disabled="!encoder.userId.activated"
  36. />
  37. </v-flex>
  38. </v-layout>
  39. <v-layout row wrap>
  40. <v-flex xs4>
  41. <v-checkbox
  42. v-model="encoder.experimentId.activated"
  43. color="primary"
  44. label="Experiment ID"
  45. />
  46. </v-flex>
  47. <v-spacer />
  48. <v-flex xs8>
  49. <v-text-field
  50. v-model="encoder.experimentId.value"
  51. label="Experiment ID"
  52. type="text"
  53. :disabled="!encoder.experimentId.activated"
  54. />
  55. </v-flex>
  56. </v-layout>
  57. <h2>Experiment name and scene name</h2>
  58. <v-layout row wrap>
  59. <v-flex xs4>
  60. <v-checkbox
  61. v-model="encoder.experimentName.activated"
  62. color="primary"
  63. label="Experiment name"
  64. @click="encoder.sceneName.activated = false"
  65. />
  66. </v-flex>
  67. <v-flex xs8>
  68. <v-select
  69. v-model="encoder.experimentName.value"
  70. :items="encoder.experimentsSelectItems"
  71. item-text="text"
  72. item-value="value"
  73. label="Experiment name"
  74. :disabled="!encoder.experimentName.activated"
  75. />
  76. </v-flex>
  77. </v-layout>
  78. <v-layout row wrap>
  79. <v-flex xs4>
  80. <v-checkbox
  81. v-model="encoder.sceneName.activated"
  82. color="primary"
  83. label="Scene name"
  84. :disabled="!encoder.experimentName.activated || encoder.experimentName.value === ''"
  85. />
  86. </v-flex>
  87. <v-spacer />
  88. <v-flex xs8>
  89. <v-select
  90. v-model="encoder.sceneName.value"
  91. :items="encoder.scenesSelectItems"
  92. item-text="text"
  93. item-value="value"
  94. label="Scene name"
  95. :disabled="!encoder.sceneName.activated"
  96. />
  97. </v-flex>
  98. </v-layout>
  99. <v-btn color="primary" @click="generateLink">Generate link</v-btn>
  100. <div v-if="encoder.linkOutput && encoder.dataOutput">
  101. <h2 class="mt-5">Result</h2>
  102. <v-textarea
  103. :value="encoder.linkOutput"
  104. label="Your generated link"
  105. type="text"
  106. readonly
  107. />
  108. Data in the generated link:
  109. <pre>{{ encoder.dataOutput }}</pre>
  110. </div>
  111. <v-slide-y-transition mode="out-in">
  112. <v-alert v-if="encoder.alertMessage" :value="true" type="info" v-text="encoder.alertMessage" />
  113. </v-slide-y-transition>
  114. </v-form>
  115. </v-card-text>
  116. </v-layout>
  117. </v-container>
  118. </v-card>
  119. <!--/ Link encoder -->
  120. <!-- Link decoder -->
  121. <v-card class="mt-5">
  122. <v-container fluid fill-height>
  123. <v-layout column align-center>
  124. <v-card-title class="headline d-block text-md-center font-weight-bold">Link decoder</v-card-title>
  125. <v-card-text>
  126. <v-form>
  127. <v-text-field
  128. v-model="decoder.link"
  129. label="Link to decode"
  130. />
  131. <div v-if="decoder.dataOutput">
  132. Data in the provided link:
  133. <pre>{{ decoder.dataOutput }}</pre>
  134. </div>
  135. <v-slide-y-transition mode="out-in">
  136. <v-alert v-if="decoder.alertMessage" :value="true" type="info" v-text="decoder.alertMessage" />
  137. </v-slide-y-transition>
  138. </v-form>
  139. </v-card-text>
  140. </v-layout>
  141. </v-container>
  142. </v-card>
  143. <!--/ Link decoder -->
  144. </v-flex>
  145. </v-layout>
  146. </template>
  147. <script>
  148. import Experiments from '@/router/experiments'
  149. import { getExperimentSceneList } from '@/config.utils'
  150. export default {
  151. name: 'LinkGenerator',
  152. components: {
  153. },
  154. data() {
  155. return {
  156. encoder: {
  157. webAppUrl: 'https://diran.univ-littoral.fr',
  158. hostConfig: 'https://diran.univ-littoral.fr',
  159. userId: {
  160. activated: false,
  161. value: ''
  162. },
  163. experimentId: {
  164. activated: false,
  165. value: ''
  166. },
  167. experimentName: {
  168. activated: false,
  169. value: ''
  170. },
  171. sceneName: {
  172. activated: false,
  173. value: ''
  174. },
  175. experimentsSelectItems: null,
  176. scenesSelectItems: null,
  177. linkOutput: null,
  178. dataOutput: null,
  179. alertMessage: null
  180. },
  181. decoder: {
  182. link: '',
  183. dataOutput: null,
  184. alertMessage: null
  185. }
  186. }
  187. },
  188. watch: {
  189. 'encoder.experimentName.activated'(newValue) {
  190. // Reset available scenes if experiment changed
  191. if (!newValue) this.encoder.scenesSelectItems = null
  192. },
  193. 'encoder.experimentName.value'(newValue) {
  194. // Reset available scenes if experiment changed
  195. if (newValue !== '') this.encoder.scenesSelectItems = getExperimentSceneList(this.encoder.experimentName.value)
  196. },
  197. 'encoder.sceneName.activated'(newValue) {
  198. // Load available scenes when sceneName is activated
  199. if (newValue) this.encoder.scenesSelectItems = getExperimentSceneList(this.encoder.experimentName.value)
  200. else this.encoder.scenesSelectItems = null
  201. },
  202. 'decoder.link'(newValue) {
  203. this.decoder.alertMessage = null
  204. if (newValue) this.decode(newValue)
  205. else this.decoder.dataOutput = null
  206. }
  207. },
  208. mounted() {
  209. this.encoder.experimentsSelectItems = Experiments.map(expe => ({
  210. text: `${expe.name} - ${expe.meta.fullName}`,
  211. value: expe.name
  212. }))
  213. },
  214. methods: {
  215. generateLink() {
  216. this.alertMessage = null
  217. // Check host configuration is set
  218. if (this.encoder.webAppUrl === '' || this.encoder.hostConfig === '') {
  219. this.encoder.alertMessage = 'The host configuration is required.'
  220. this.encoder.linkOutput = null
  221. this.encoder.dataOutput = null
  222. return
  223. }
  224. // Generate the link
  225. let obj = {
  226. hostConfig: this.encoder.hostConfig
  227. }
  228. if (this.encoder.userId.activated && this.encoder.userId.value !== '') obj.userId = this.encoder.userId.value
  229. if (this.encoder.experimentId.activated && this.encoder.experimentId.value !== '') obj.experimentId = this.encoder.experimentId.value
  230. if (this.encoder.experimentName.activated && this.encoder.experimentName.value !== '') obj.experimentName = this.encoder.experimentName.value
  231. if (this.encoder.sceneName.activated && this.encoder.sceneName.value !== '') obj.sceneName = this.encoder.sceneName.value
  232. const q = btoa(JSON.stringify(obj)).replace(/[=]/g, '')
  233. this.encoder.linkOutput = `${this.encoder.webAppUrl}/#/?q=${q}`
  234. this.encoder.dataOutput = JSON.stringify(obj, null, 2)
  235. },
  236. decode(link) {
  237. try {
  238. const matched = link.match(/\?q=(.*)/)
  239. if (!matched || matched.length !== 2) throw new Error('The provided link is invalid.')
  240. let q = matched[1]
  241. try {
  242. q = atob(q)
  243. }
  244. catch {
  245. throw new Error('"q" is not a base64-encoded string.')
  246. }
  247. try {
  248. q = JSON.parse(q)
  249. }
  250. catch {
  251. throw new Error(`"q" encoded data is not JSON valid. Decoded base64 data: ${q}`)
  252. }
  253. this.decoder.dataOutput = JSON.stringify(q, null, 2)
  254. }
  255. catch (err) {
  256. this.decoder.alertMessage = err.message
  257. }
  258. }
  259. }
  260. }
  261. </script>