You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.2 KiB

  1. <template lang='pug'>
  2. div
  3. v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
  4. .headline.primary--text Developer Tools
  5. .subheading.grey--text ¯\_()_/¯
  6. v-tabs(
  7. v-model='selectedTab'
  8. :color='$vuetify.dark ? "primary" : "grey lighten-4"'
  9. fixed-tabs
  10. :slider-color='$vuetify.dark ? "white" : "primary"'
  11. show-arrows
  12. @input='tabChanged'
  13. )
  14. v-tab(key='0') Graph API Playground
  15. v-tab(key='1') Graph API Map
  16. v-tabs-items(v-model='selectedTab')
  17. v-tab-item(key='0', :transition='false', :reverse-transition='false')
  18. #graphiql
  19. v-tab-item(key='1', :transition='false', :reverse-transition='false')
  20. #voyager
  21. </template>
  22. <script>
  23. import _ from 'lodash'
  24. import React from 'react'
  25. import ReactDOM from 'react-dom'
  26. import GraphiQL from 'graphiql'
  27. import { Voyager } from 'graphql-voyager'
  28. import 'graphiql/graphiql.css'
  29. import 'graphql-voyager/dist/voyager.css'
  30. const fetcher = (qry, respType) => {
  31. return fetch('/graphql', {
  32. method: 'post',
  33. headers: {
  34. 'Accept': 'application/json',
  35. 'Content-Type': 'application/json'
  36. },
  37. body: JSON.stringify(qry),
  38. credentials: 'include'
  39. }).then(response => {
  40. if (respType === 'json') {
  41. return response.json()
  42. } else {
  43. return response.text()
  44. }
  45. }).then(responseBody => {
  46. try {
  47. return JSON.parse(responseBody)
  48. } catch (error) {
  49. return responseBody
  50. }
  51. })
  52. }
  53. let graphiQLInstance
  54. export default {
  55. data() {
  56. return {
  57. selectedTab: '0'
  58. }
  59. },
  60. mounted() {
  61. this.renderGraphiQL()
  62. },
  63. methods: {
  64. tabChanged (tabId) {
  65. switch (tabId) {
  66. case '1':
  67. this.renderVoyager()
  68. break
  69. }
  70. },
  71. renderGraphiQL() {
  72. ReactDOM.render(
  73. React.createElement(GraphiQL, {
  74. ref(el) { graphiQLInstance = el },
  75. async fetcher(qry) {
  76. let resp = await fetcher(qry, 'text')
  77. _.delay(() => {
  78. graphiQLInstance.resultComponent.viewer.refresh()
  79. }, 500)
  80. return resp
  81. },
  82. query: '',
  83. response: null,
  84. variables: null,
  85. operationName: null,
  86. websocketConnectionParams: null
  87. }),
  88. document.getElementById('graphiql')
  89. )
  90. graphiQLInstance.queryEditorComponent.editor.refresh()
  91. graphiQLInstance.variableEditorComponent.editor.refresh()
  92. graphiQLInstance.state.variableEditorOpen = true
  93. },
  94. renderVoyager() {
  95. ReactDOM.render(
  96. React.createElement(Voyager, {
  97. introspection: qry => fetcher({ query: qry }, 'json'),
  98. workerURI: '/js/voyager.worker.js'
  99. }),
  100. document.getElementById('voyager')
  101. )
  102. }
  103. }
  104. }
  105. </script>
  106. <style lang='scss'>
  107. #graphiql {
  108. height: calc(100vh - 230px);
  109. .topBar {
  110. background-color: mc('grey', '200');
  111. background-image: none;
  112. padding: 1.5rem 0;
  113. > .title {
  114. display: none;
  115. }
  116. }
  117. .toolbar {
  118. background-color: initial;
  119. box-shadow: initial;
  120. }
  121. }
  122. #voyager {
  123. height: calc(100vh - 250px);
  124. .title-area {
  125. display: none;
  126. }
  127. .type-doc {
  128. margin-top: 5px;
  129. }
  130. }
  131. </style>