Skip to content

Commit

Permalink
feat(#583): add devtools integration (#584)
Browse files Browse the repository at this point in the history
* feat(#583): add dev tools integration

* chore(#583): fix validation

* chore(#583): add slots to templates

* chore(#583): disable template slots
  • Loading branch information
Decipher authored Nov 2, 2022
1 parent f6b4a66 commit 29905ff
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/wise-pots-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt": minor
---

feat(#583): add Vue devtools plugin
3 changes: 2 additions & 1 deletion packages/blocks/src/components/DruxtBlock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ export default {
debug: 'block',
mixins: {
'DruxtBlocksBlockMixin': 'druxt-blocks'
}
},
slots: false
}
},
}
Expand Down
2 changes: 2 additions & 0 deletions packages/druxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"import": "./dist/druxt.esm.js"
},
"./components/*": "./dist/components/*",
"./plugins/*": "./dist/plugins/*",
"./server-middleware/*": "./dist/server-middleware/*",
"./dist/server-middleware/template.mjs": "./dist/server-middleware/template.mjs"
},
Expand All @@ -41,6 +42,7 @@
"dependencies": {
"@nuxtjs/axios": "^5.13.6",
"@nuxtjs/proxy": "^2.1.0",
"@vue/devtools-api": "^6.4.5",
"chalk": "^4.1.2",
"deepmerge": "^4.2.2",
"drupal-jsonapi-params": "^2.1.0",
Expand Down
1 change: 1 addition & 0 deletions packages/druxt/src/components/DruxtDevelTemplate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default {
settings: {
component: this.module.$options._componentTag,
props: Object.entries(this.module.component.propsData || {}).map(([key, value]) => ({ key, type: typeof value })),
slots: this.module.component.slots,
...((this.module.$options.druxt || {}).template || {}),
}
}
Expand Down
6 changes: 6 additions & 0 deletions packages/druxt/src/nuxt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ const DruxtNuxtModule = async function (moduleOptions = {}) {
path: '/_druxt/template',
handler: 'druxt/dist/server-middleware/template.mjs'
})

// Add the Vue devtools plugin.
this.addPlugin({
src: resolve(__dirname, '../dist/plugins/devtools.mjs'),
fileName: 'druxt-devtools.js'
})
}

// Nuxt Storybook.
Expand Down
117 changes: 117 additions & 0 deletions packages/druxt/src/plugins/devtools.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import Vue from 'vue'
import { setupDevtoolsPlugin } from '@vue/devtools-api'

Vue.mixin({
beforeCreate() {
if (process.env.NODE_ENV === 'development') {
const createAction = (component, payload) => ({
icon: 'save',
tooltip: `Create ${component} and open in editor`,
action: () => payload.app.$axios({
url: '/_druxt/template/add',
baseURL: '/',
method: 'post',
data: {
path: component,
settings: {
component: payload.componentInstance.$options._componentTag,
props: Object.entries(payload.componentInstance.component.propsData || {}).map(([key, value]) => ({ key, type: typeof value })),
slots: payload.componentInstance.component.slots,
...((payload.componentInstance.$options.druxt || {}).template || {}),
}
}
})
})
const inspectorId = 'druxt'
const stateType = 'druxt'

setupDevtoolsPlugin({
id: 'druxt',
label: 'DruxtJS',
packageName: 'druxt',
homepage: 'https://druxtjs.org',
componentStateTypes: [stateType],
app: this
}, api => {
api.addInspector({
id: inspectorId,
label: 'DruxtJS',
icon: 'opacity',
})

api.on.inspectComponent((payload) => {
if (payload.instanceData.state && payload.componentInstance.component) {
payload.instanceData.state.push({
type: stateType,
key: '$theme',
value: {
_custom: {
type: null,
readOnly: true,
display: payload.componentInstance.component.is,
value: payload.componentInstance.component.options.map((option) => ({
_custom: {
type: null,
display: option,
actions: !payload.componentInstance.$nuxt.$options.components[option]
? [createAction(option, payload)]
: [],
}
})),
},
},
})
}
})

api.on.getInspectorTree((payload) => {
if (payload.inspectorId === inspectorId) {
payload.rootNodes = [
{
id: 'connect',
label: 'Connection details',
}
]
}
})

api.on.getInspectorState((payload) => {
if (payload.inspectorId === inspectorId) {
if (payload.nodeId === 'connect') {
const { baseUrl, endpoint } = payload.app.$druxt.settings
payload.state = {
settings: [
{
key: 'baseUrl',
value: baseUrl,
},
{
key: 'endpoint',
value: endpoint,
},
],
computed: [
{
key: 'jsonApi',
value: baseUrl + endpoint
}
]
}
}
}
})

api.on.visitComponentTree((payload) => {
const node = payload.treeNode
if (payload.componentInstance.$options.druxt) {
node.tags.push({
label: 'druxt',
textColor: 0xffffff,
backgroundColor: 0x3498dB
})
}
})
})
}
}
})
16 changes: 14 additions & 2 deletions packages/druxt/src/server-middleware/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,26 @@ app.use(limiter)
app.post('/add', async (req, res) => {
const { path, settings } = req.body
if (!path) throw new Error('Missing required path attribute.')
if (typeof path !== 'string' || !/^[a-zA-Z0-1]+$/.test(path)) throw new Error('Unsupported value provided for the path attribute.')
if (typeof path !== 'string' || !/^[a-zA-Z0-9]+$/.test(path)) throw new Error('Unsupported value provided for the path attribute.')

const prefix = kebabCase(settings.component).replace('-', '/') + '/'
const dest = 'components/' + path.replace(settings.component, prefix) + '.vue'
const dir = `components/${prefix}`

let imports = ''
let exports = []
let slots = ''

// Add slots.
if (Array.isArray(settings.slots)) {
const items = (settings.slots.length > 1
? settings.slots.filter((name) => name !== 'default')
: settings.slots).filter((name) => name !== 'debug')
slots = items.map((name) => `\r\n <slot name="${name}" />`).join('')
}
else if (typeof settings.slots === 'string') {
slots = `\r\n <slot name="${settings.slot}" />`
}

// Use mixin if provided by the module.
if (settings.mixins) {
Expand Down Expand Up @@ -85,7 +97,7 @@ app.post('/add', async (req, res) => {
const template = `<!-- Generated by the Druxt devel template server middleware. -->
<template>
<div>
<DruxtDebug :json="${settings.debug || 'model'}" />
<DruxtDebug :json="${settings.debug || 'model'}" />${slots}
</div>
</template>
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6401,6 +6401,13 @@ __metadata:
languageName: node
linkType: hard

"@vue/devtools-api@npm:^6.4.5":
version: 6.4.5
resolution: "@vue/devtools-api@npm:6.4.5"
checksum: 40c5adc8788cb283972ce09ba7ce105fa894f4decec9168829cc8e6211462763402442e6c31be76f9da62b0e74ae724971b924571367b4ac89b94dc6894e2d07
languageName: node
linkType: hard

"@vue/shared@npm:3.2.4":
version: 3.2.4
resolution: "@vue/shared@npm:3.2.4"
Expand Down Expand Up @@ -10485,6 +10492,7 @@ __metadata:
"@nuxtjs/axios": ^5.13.6
"@nuxtjs/proxy": ^2.1.0
"@storybook/addon-docs": ^6.5.10
"@vue/devtools-api": ^6.4.5
chalk: ^4.1.2
core-js: ^3.25.1
deepmerge: ^4.2.2
Expand Down

0 comments on commit 29905ff

Please sign in to comment.