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.

182 lines
4.1 KiB

  1. <template lang='pug'>
  2. v-container(fluid, grid-list-lg)
  3. v-layout(row, wrap)
  4. v-flex(xs12)
  5. .admin-header
  6. img(src='/svg/icon-console.svg', alt='Developer Tools', style='width: 80px;')
  7. .admin-header-title
  8. .headline.primary--text Developer Tools
  9. .subheading.grey--text ¯\_()_/¯
  10. v-spacer
  11. v-card.radius-7
  12. v-card-text
  13. .caption Enables extra dev options and removes many safeguards.
  14. .caption.red--text Do not enable unless you know what you're doing!
  15. v-switch.mt-1(
  16. color='primary'
  17. hide-details
  18. label='Dev Mode'
  19. )
  20. v-card.mt-3.white.grey--text.text--darken-3
  21. v-tabs(
  22. v-model='selectedTab'
  23. color='grey darken-2'
  24. fixed-tabs
  25. slider-color='white'
  26. show-arrows
  27. dark
  28. @change='tabChanged'
  29. )
  30. v-tab(key='0') Graph API Playground
  31. v-tab(key='1') Graph API Map
  32. v-tabs-items(v-model='selectedTab')
  33. v-tab-item(key='0', :transition='false', :reverse-transition='false')
  34. #graphiql
  35. v-tab-item(key='1', :transition='false', :reverse-transition='false')
  36. #voyager
  37. </template>
  38. <script>
  39. import _ from 'lodash'
  40. import React from 'react'
  41. import ReactDOM from 'react-dom'
  42. import GraphiQL from 'graphiql'
  43. import { Voyager } from 'graphql-voyager'
  44. import 'graphiql/graphiql.css'
  45. import 'graphql-voyager/dist/voyager.css'
  46. const fetcher = (qry, respType) => {
  47. return fetch('/graphql', {
  48. method: 'post',
  49. headers: {
  50. 'Accept': 'application/json',
  51. 'Content-Type': 'application/json'
  52. },
  53. body: JSON.stringify(qry),
  54. credentials: 'include'
  55. }).then(response => {
  56. if (respType === 'json') {
  57. return response.json()
  58. } else {
  59. return response.text()
  60. }
  61. }).then(responseBody => {
  62. try {
  63. return JSON.parse(responseBody)
  64. } catch (error) {
  65. return responseBody
  66. }
  67. })
  68. }
  69. let graphiQLInstance
  70. export default {
  71. data() {
  72. return {
  73. selectedTab: 0
  74. }
  75. },
  76. mounted() {
  77. this.renderGraphiQL()
  78. },
  79. methods: {
  80. tabChanged (tabId) {
  81. switch (tabId) {
  82. case 1:
  83. this.renderVoyager()
  84. break
  85. }
  86. },
  87. renderGraphiQL() {
  88. ReactDOM.render(
  89. React.createElement(GraphiQL, {
  90. ref(el) { graphiQLInstance = el },
  91. async fetcher(qry) {
  92. let resp = await fetcher(qry, 'text')
  93. _.delay(() => {
  94. graphiQLInstance.resultComponent.viewer.refresh()
  95. }, 500)
  96. return resp
  97. },
  98. response: null,
  99. variables: '{}',
  100. operationName: null,
  101. websocketConnectionParams: null
  102. }),
  103. document.getElementById('graphiql')
  104. )
  105. graphiQLInstance.queryEditorComponent.editor.refresh()
  106. graphiQLInstance.variableEditorComponent.editor.refresh()
  107. graphiQLInstance.state.variableEditorOpen = true
  108. graphiQLInstance.state.docExplorerOpen = true
  109. },
  110. renderVoyager() {
  111. ReactDOM.render(
  112. React.createElement(Voyager, {
  113. introspection: qry => fetcher({ query: qry }, 'json'),
  114. workerURI: '/js/voyager.worker.js'
  115. }),
  116. document.getElementById('voyager')
  117. )
  118. }
  119. }
  120. }
  121. </script>
  122. <style lang='scss'>
  123. #graphiql {
  124. height: calc(100vh - 270px);
  125. .topBar {
  126. background-color: mc('grey', '200');
  127. background-image: none;
  128. padding: 1.5rem 0;
  129. > .title {
  130. display: none;
  131. }
  132. }
  133. .toolbar {
  134. background-color: initial;
  135. box-shadow: initial;
  136. }
  137. .doc-explorer-title-bar, .history-title-bar {
  138. height: auto;
  139. }
  140. }
  141. #voyager {
  142. height: calc(100vh - 270px);
  143. .title-area {
  144. display: none;
  145. }
  146. .type-doc {
  147. margin-top: 5px;
  148. }
  149. .doc-navigation {
  150. > span {
  151. overflow-y: hidden;
  152. display: block;
  153. }
  154. min-height: 40px;
  155. }
  156. .contents {
  157. padding-bottom: 0;
  158. color: #666;
  159. }
  160. .type-info-popover {
  161. display: none;
  162. }
  163. }
  164. </style>