feat: admin dev pages modularity + storage state json fix
This commit is contained in:
		| @@ -79,9 +79,22 @@ | ||||
|             v-list-tile(to='/utilities', v-if='hasPermission(`manage:system`)', disabled) | ||||
|               v-list-tile-avatar: v-icon(color='grey lighten-2') build | ||||
|               v-list-tile-title {{ $t('admin:utilities.title') }} | ||||
|             v-list-tile(to='/dev', v-if='hasPermission([`manage:system`, `manage:api`])') | ||||
|               v-list-tile-avatar: v-icon weekend | ||||
|               v-list-tile-title {{ $t('admin:dev.title') }} | ||||
|             v-list-group( | ||||
|               prepend-icon='weekend' | ||||
|               value='true' | ||||
|               to='/dev' | ||||
|               no-action | ||||
|               v-if='hasPermission([`manage:system`, `manage:api`])' | ||||
|               ) | ||||
|               v-list-tile(slot='activator') | ||||
|                 v-list-tile-title {{ $t('admin:dev.title') }} | ||||
|  | ||||
|               v-list-tile(to='/dev-flags') | ||||
|                 v-list-tile-title {{ $t('admin:dev.flags.title') }} | ||||
|               v-list-tile(to='/dev-graphiql') | ||||
|                 v-list-tile-title {{ $t('admin:dev.graphiql.title') }} | ||||
|               v-list-tile(to='/dev-voyager') | ||||
|                 v-list-tile-title {{ $t('admin:dev.voyager.title') }} | ||||
|             v-divider.my-2 | ||||
|           v-list-tile(to='/contribute') | ||||
|             v-list-tile-avatar: v-icon favorite | ||||
| @@ -132,7 +145,9 @@ const router = new VueRouter({ | ||||
|     { path: '/mail', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-mail.vue') }, | ||||
|     { path: '/system', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-system.vue') }, | ||||
|     { path: '/utilities', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-utilities.vue') }, | ||||
|     { path: '/dev', component: () => import(/* webpackChunkName: "admin-dev" */ './admin/admin-dev.vue') }, | ||||
|     { path: '/dev-flags', component: () => import(/* webpackChunkName: "admin-dev" */ './admin/admin-dev-flags.vue') }, | ||||
|     { path: '/dev-graphiql', component: () => import(/* webpackChunkName: "admin-dev" */ './admin/admin-dev-graphiql.vue') }, | ||||
|     { path: '/dev-voyager', component: () => import(/* webpackChunkName: "admin-dev" */ './admin/admin-dev-voyager.vue') }, | ||||
|     { path: '/contribute', component: () => import(/* webpackChunkName: "admin" */ './admin/admin-contribute.vue') } | ||||
|   ] | ||||
| }) | ||||
|   | ||||
							
								
								
									
										59
									
								
								client/components/admin/admin-dev-flags.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								client/components/admin/admin-dev-flags.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| <template lang='pug'> | ||||
|   v-container(fluid, grid-list-lg) | ||||
|     v-layout(row, wrap) | ||||
|       v-flex(xs12) | ||||
|         .admin-header | ||||
|           img(src='/svg/icon-console.svg', alt='Developer Tools', style='width: 80px;') | ||||
|           .admin-header-title | ||||
|             .headline.primary--text Developer Tools | ||||
|             .subheading.grey--text Flags | ||||
|           v-spacer | ||||
|           v-btn(color='success', depressed, @click='save', large) | ||||
|             v-icon(left) check | ||||
|             span {{$t('common:actions.apply')}} | ||||
|  | ||||
|         v-card.mt-3.white.grey--text.text--darken-3 | ||||
|           v-alert(color='red', value='true', icon='warning') | ||||
|             span Do NOT enable these flags unless you know what you're doing! | ||||
|             .caption Doing so may result in data loss or broken installation! | ||||
|           v-card-text | ||||
|             v-switch.mt-3( | ||||
|               color='red' | ||||
|               hint='Log all queries made to the database to console.' | ||||
|               persistent-hint | ||||
|               label='SQL Query Logging' | ||||
|               v-model='flags.sqllog' | ||||
|             ) | ||||
|             //- v-divider.mt-3 | ||||
|             //- v-switch.mt-3( | ||||
|             //-   color='primary' | ||||
|             //-   hint='Log all queries made to the database to console.' | ||||
|             //-   persistent-hint | ||||
|             //-   label='SQL Query Log' | ||||
|             //-   v-model='flags.sqllog' | ||||
|             //- ) | ||||
|  | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import _ from 'lodash' | ||||
|  | ||||
| export default { | ||||
|   data() { | ||||
|     return { | ||||
|       flags: { | ||||
|         sqllog: false | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     save() { | ||||
|  | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang='scss'> | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										101
									
								
								client/components/admin/admin-dev-graphiql.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								client/components/admin/admin-dev-graphiql.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| <template lang='pug'> | ||||
|   v-container(fluid, grid-list-lg) | ||||
|     v-layout(row, wrap) | ||||
|       v-flex(xs12) | ||||
|         .admin-header | ||||
|           img(src='/svg/icon-console.svg', alt='Developer Tools', style='width: 80px;') | ||||
|           .admin-header-title | ||||
|             .headline.primary--text Developer Tools | ||||
|             .subheading.grey--text GraphiQL | ||||
|  | ||||
|         v-card.mt-3.white.grey--text.text--darken-3 | ||||
|           #graphiql | ||||
|  | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import _ from 'lodash' | ||||
| import React from 'react' | ||||
| import ReactDOM from 'react-dom' | ||||
| import GraphiQL from 'graphiql' | ||||
| import 'graphiql/graphiql.css' | ||||
|  | ||||
| const fetcher = (qry, respType) => { | ||||
|   return fetch('/graphql', { | ||||
|     method: 'post', | ||||
|     headers: { | ||||
|       'Accept': 'application/json', | ||||
|       'Content-Type': 'application/json' | ||||
|     }, | ||||
|     body: JSON.stringify(qry), | ||||
|     credentials: 'include' | ||||
|   }).then(response => { | ||||
|     if (respType === 'json') { | ||||
|       return response.json() | ||||
|     } else { | ||||
|       return response.text() | ||||
|     } | ||||
|   }).then(responseBody => { | ||||
|     try { | ||||
|       return JSON.parse(responseBody) | ||||
|     } catch (error) { | ||||
|       return responseBody | ||||
|     } | ||||
|   }) | ||||
| } | ||||
|  | ||||
| export default { | ||||
|   data() { | ||||
|     return { } | ||||
|   }, | ||||
|   mounted() { | ||||
|     let graphiQLInstance | ||||
|     ReactDOM.render( | ||||
|       React.createElement(GraphiQL, { | ||||
|         ref(el) { graphiQLInstance = el }, | ||||
|         async fetcher(qry) { | ||||
|           let resp = await fetcher(qry, 'text') | ||||
|           _.delay(() => { | ||||
|             graphiQLInstance.resultComponent.viewer.refresh() | ||||
|           }, 500) | ||||
|           return resp | ||||
|         }, | ||||
|         response: null, | ||||
|         variables: '{}', | ||||
|         operationName: null, | ||||
|         websocketConnectionParams: null | ||||
|       }), | ||||
|       document.getElementById('graphiql') | ||||
|     ) | ||||
|     graphiQLInstance.queryEditorComponent.editor.refresh() | ||||
|     graphiQLInstance.variableEditorComponent.editor.refresh() | ||||
|     graphiQLInstance.state.variableEditorOpen = true | ||||
|     graphiQLInstance.state.docExplorerOpen = true | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang='scss'> | ||||
| #graphiql { | ||||
|   height: calc(100vh - 270px); | ||||
|  | ||||
|   .topBar { | ||||
|     background-color: mc('grey', '200'); | ||||
|     background-image: none; | ||||
|     padding: 1.5rem 0; | ||||
|  | ||||
|     > .title { | ||||
|       display: none; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .toolbar { | ||||
|     background-color: initial; | ||||
|     box-shadow: initial; | ||||
|   } | ||||
|  | ||||
|   .doc-explorer-title-bar, .history-title-bar { | ||||
|     height: auto; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										93
									
								
								client/components/admin/admin-dev-voyager.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								client/components/admin/admin-dev-voyager.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| <template lang='pug'> | ||||
|   v-container(fluid, grid-list-lg) | ||||
|     v-layout(row, wrap) | ||||
|       v-flex(xs12) | ||||
|         .admin-header | ||||
|           img(src='/svg/icon-console.svg', alt='Developer Tools', style='width: 80px;') | ||||
|           .admin-header-title | ||||
|             .headline.primary--text Developer Tools | ||||
|             .subheading.grey--text Voyager | ||||
|  | ||||
|         v-card.mt-3.white.grey--text.text--darken-3 | ||||
|           #voyager | ||||
|  | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import _ from 'lodash' | ||||
| import React from 'react' | ||||
| import ReactDOM from 'react-dom' | ||||
| import { Voyager } from 'graphql-voyager' | ||||
| import 'graphql-voyager/dist/voyager.css' | ||||
|  | ||||
| const fetcher = (qry, respType) => { | ||||
|   return fetch('/graphql', { | ||||
|     method: 'post', | ||||
|     headers: { | ||||
|       'Accept': 'application/json', | ||||
|       'Content-Type': 'application/json' | ||||
|     }, | ||||
|     body: JSON.stringify(qry), | ||||
|     credentials: 'include' | ||||
|   }).then(response => { | ||||
|     if (respType === 'json') { | ||||
|       return response.json() | ||||
|     } else { | ||||
|       return response.text() | ||||
|     } | ||||
|   }).then(responseBody => { | ||||
|     try { | ||||
|       return JSON.parse(responseBody) | ||||
|     } catch (error) { | ||||
|       return responseBody | ||||
|     } | ||||
|   }) | ||||
| } | ||||
|  | ||||
| export default { | ||||
|   data() { | ||||
|     return {} | ||||
|   }, | ||||
|   mounted() { | ||||
|     _.delay(() => { | ||||
|       ReactDOM.render( | ||||
|         React.createElement(Voyager, { | ||||
|           introspection: qry => fetcher({ query: qry }, 'json'), | ||||
|           workerURI: '/js/voyager.worker.js' | ||||
|         }), | ||||
|         document.getElementById('voyager') | ||||
|       ) | ||||
|     }, 500) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang='scss'> | ||||
| #voyager { | ||||
|   height: calc(100vh - 270px); | ||||
|  | ||||
|   .title-area { | ||||
|     display: none; | ||||
|   } | ||||
|   .type-doc { | ||||
|     margin-top: 5px; | ||||
|   } | ||||
|  | ||||
|   .doc-navigation { | ||||
|     > span { | ||||
|       overflow-y: hidden; | ||||
|       display: block; | ||||
|     } | ||||
|     min-height: 40px; | ||||
|   } | ||||
|  | ||||
|   .contents { | ||||
|     padding-bottom: 0; | ||||
|     color: #666; | ||||
|   } | ||||
|  | ||||
|   .type-info-popover { | ||||
|     display: none; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -1,182 +0,0 @@ | ||||
| <template lang='pug'> | ||||
|   v-container(fluid, grid-list-lg) | ||||
|     v-layout(row, wrap) | ||||
|       v-flex(xs12) | ||||
|         .admin-header | ||||
|           img(src='/svg/icon-console.svg', alt='Developer Tools', style='width: 80px;') | ||||
|           .admin-header-title | ||||
|             .headline.primary--text Developer Tools | ||||
|             .subheading.grey--text ¯\_(ツ)_/¯ | ||||
|           v-spacer | ||||
|           v-card.radius-7 | ||||
|             v-card-text | ||||
|               .caption Enables extra dev options and removes many safeguards. | ||||
|               .caption.red--text Do not enable unless you know what you're doing! | ||||
|               v-switch.mt-1( | ||||
|                 color='primary' | ||||
|                 hide-details | ||||
|                 label='Dev Mode' | ||||
|               ) | ||||
|  | ||||
|         v-card.mt-3.white.grey--text.text--darken-3 | ||||
|           v-tabs( | ||||
|             v-model='selectedTab' | ||||
|             color='grey darken-2' | ||||
|             fixed-tabs | ||||
|             slider-color='white' | ||||
|             show-arrows | ||||
|             dark | ||||
|             @change='tabChanged' | ||||
|             ) | ||||
|             v-tab(key='0') Graph API Playground | ||||
|             v-tab(key='1') Graph API Map | ||||
|           v-tabs-items(v-model='selectedTab') | ||||
|             v-tab-item(key='0', :transition='false', :reverse-transition='false') | ||||
|               #graphiql | ||||
|  | ||||
|             v-tab-item(key='1', :transition='false', :reverse-transition='false') | ||||
|               #voyager | ||||
|  | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import _ from 'lodash' | ||||
| import React from 'react' | ||||
| import ReactDOM from 'react-dom' | ||||
| import GraphiQL from 'graphiql' | ||||
| import { Voyager } from 'graphql-voyager' | ||||
| import 'graphiql/graphiql.css' | ||||
| import 'graphql-voyager/dist/voyager.css' | ||||
|  | ||||
| const fetcher = (qry, respType) => { | ||||
|   return fetch('/graphql', { | ||||
|     method: 'post', | ||||
|     headers: { | ||||
|       'Accept': 'application/json', | ||||
|       'Content-Type': 'application/json' | ||||
|     }, | ||||
|     body: JSON.stringify(qry), | ||||
|     credentials: 'include' | ||||
|   }).then(response => { | ||||
|     if (respType === 'json') { | ||||
|       return response.json() | ||||
|     } else { | ||||
|       return response.text() | ||||
|     } | ||||
|   }).then(responseBody => { | ||||
|     try { | ||||
|       return JSON.parse(responseBody) | ||||
|     } catch (error) { | ||||
|       return responseBody | ||||
|     } | ||||
|   }) | ||||
| } | ||||
|  | ||||
| let graphiQLInstance | ||||
|  | ||||
| export default { | ||||
|   data() { | ||||
|     return { | ||||
|       selectedTab: 0 | ||||
|     } | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.renderGraphiQL() | ||||
|   }, | ||||
|   methods: { | ||||
|     tabChanged (tabId) { | ||||
|       switch (tabId) { | ||||
|         case 1: | ||||
|           this.renderVoyager() | ||||
|           break | ||||
|       } | ||||
|     }, | ||||
|     renderGraphiQL() { | ||||
|       ReactDOM.render( | ||||
|         React.createElement(GraphiQL, { | ||||
|           ref(el) { graphiQLInstance = el }, | ||||
|           async fetcher(qry) { | ||||
|             let resp = await fetcher(qry, 'text') | ||||
|             _.delay(() => { | ||||
|               graphiQLInstance.resultComponent.viewer.refresh() | ||||
|             }, 500) | ||||
|             return resp | ||||
|           }, | ||||
|           response: null, | ||||
|           variables: '{}', | ||||
|           operationName: null, | ||||
|           websocketConnectionParams: null | ||||
|         }), | ||||
|         document.getElementById('graphiql') | ||||
|       ) | ||||
|       graphiQLInstance.queryEditorComponent.editor.refresh() | ||||
|       graphiQLInstance.variableEditorComponent.editor.refresh() | ||||
|       graphiQLInstance.state.variableEditorOpen = true | ||||
|       graphiQLInstance.state.docExplorerOpen = true | ||||
|     }, | ||||
|     renderVoyager() { | ||||
|       ReactDOM.render( | ||||
|         React.createElement(Voyager, { | ||||
|           introspection: qry => fetcher({ query: qry }, 'json'), | ||||
|           workerURI: '/js/voyager.worker.js' | ||||
|         }), | ||||
|         document.getElementById('voyager') | ||||
|       ) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang='scss'> | ||||
|  | ||||
| #graphiql { | ||||
|   height: calc(100vh - 270px); | ||||
|  | ||||
|   .topBar { | ||||
|     background-color: mc('grey', '200'); | ||||
|     background-image: none; | ||||
|     padding: 1.5rem 0; | ||||
|  | ||||
|     > .title { | ||||
|       display: none; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .toolbar { | ||||
|     background-color: initial; | ||||
|     box-shadow: initial; | ||||
|   } | ||||
|  | ||||
|   .doc-explorer-title-bar, .history-title-bar { | ||||
|     height: auto; | ||||
|   } | ||||
| } | ||||
|  | ||||
| #voyager { | ||||
|   height: calc(100vh - 270px); | ||||
|  | ||||
|   .title-area { | ||||
|     display: none; | ||||
|   } | ||||
|   .type-doc { | ||||
|     margin-top: 5px; | ||||
|   } | ||||
|  | ||||
|   .doc-navigation { | ||||
|     > span { | ||||
|       overflow-y: hidden; | ||||
|       display: block; | ||||
|     } | ||||
|     min-height: 40px; | ||||
|   } | ||||
|  | ||||
|   .contents { | ||||
|     padding-bottom: 0; | ||||
|     color: #666; | ||||
|   } | ||||
|  | ||||
|   .type-info-popover { | ||||
|     display: none; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user