Skip to content

Commit

Permalink
feat(#578): add missing theme component helper (#580)
Browse files Browse the repository at this point in the history
* feat(#578): add DruxtDevelTemplate component

* feat(#578): update missing template message

* chore(#578): update template formatting

* chore(#578): fix broken test

* feat(#578): update missing template message

* chore: update entity mixin

* feat(#578): update missing default slot message

* chore(#578): validate path

* chore(#578): update test coverage

* chore(#578): add rate limiter

* chore: fix breaking test

* chore(#578): add test coverage for template tool

* chore(#578): update ci

* chore(#578): update slot message and description

* feat(#578): added support for devel template tool

* chore(#578): update template string validation

* chore(#578): add conditional defaults

* feat(#578): add template support to block region

* feat(#578): add support for template tool

* feat(#578): update debug value

* feat(#578): add support for template tool

* feat(#578): add support for the template tool

* feat(#547): add support for the template tool

* chore(#578): fix router slots
  • Loading branch information
Decipher authored Oct 28, 2022
1 parent 4180404 commit f6b4a66
Show file tree
Hide file tree
Showing 40 changed files with 536 additions and 44 deletions.
5 changes: 5 additions & 0 deletions .changeset/cyan-kings-wonder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt-views": minor
---

feat(#578): updated components to support the DruxtDevelTemplate tool.
5 changes: 5 additions & 0 deletions .changeset/lemon-oranges-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt": minor
---

feat(#578): added DruxtDevelTemplate component to simplify template creation in development mode.
5 changes: 5 additions & 0 deletions .changeset/long-bottles-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt-site": minor
---

feat(#578): updated component to support the DruxtDevelTemplate tool.
5 changes: 5 additions & 0 deletions .changeset/long-weeks-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt-entity": minor
---

feat(#578): updated missing schema/vue component message with DruxtDevelTemplate tool.
5 changes: 5 additions & 0 deletions .changeset/metal-clouds-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt-menu": minor
---

feat(#578): updated components to support the DruxtDevelTemplate tool.
5 changes: 5 additions & 0 deletions .changeset/rude-lizards-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt-router": minor
---

feat(#578): updated component to support the DruxtDevelTemplate tool.
5 changes: 5 additions & 0 deletions .changeset/selfish-scissors-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt": minor
---

feat(#578): updated missing default slot message with DruxtDevelTemplate tool.
5 changes: 5 additions & 0 deletions .changeset/sharp-glasses-ring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt-breadcrumb": minor
---

feat(#578): updated component to support the DruxtDevelTemplate tool.
5 changes: 5 additions & 0 deletions .changeset/slow-owls-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"druxt-blocks": minor
---

feat(#578): updated missing vue component message with DruxtDevelTemplate tool.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ jobs:

- run:
name: Run DruxtSite end-to-end tests
command: yarn start-server-and-test 'yarn example:druxt-site' http://localhost:3000 'npx cypress run --project examples/druxt-site/test --spec examples/druxt-site/test/cypress/e2e/umami-*.cy.js --record --tag examples-druxt-site'
command: yarn start-server-and-test 'yarn example:druxt-site' http://localhost:3000 'npx cypress run --project examples/druxt-site/test --spec "examples/druxt-site/test/cypress/e2e/nuxt/*.cy.js" --record --tag examples-druxt-site'
- run:
name: Run DruxtSite storybook end-to-end tests
command: yarn start-server-and-test 'yarn example:druxt-site:storybook --port 3000' http://localhost:3000 'npx cypress run --project examples/druxt-site/test --spec examples/druxt-site/test/cypress/e2e/storybook.cy.js --record --tag examples-druxt-site-storybook'
command: yarn start-server-and-test 'yarn example:druxt-site:storybook --port 3000' http://localhost:3000 'npx cypress run --project examples/druxt-site/test --spec "examples/druxt-site/test/cypress/e2e/storybook/*.cy.js" --record --tag examples-druxt-site-storybook'
- store_artifacts:
path: ./examples/druxt-site/test/cypress/screenshots
- store_artifacts:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* global cy, it */

it('DruxtDevelTemplate tool', () => {
// Given I visit the homepage.
cy.visit('/')

// Umami Search block.
const searchBlock = '[data-fetch-key^="DruxtBlock:dc9cc806-d5d5-4187-af7a-f9d5b13fea8b:0"]'

// I see a DruxtDebug component.
cy.get(searchBlock)
.find('details summary')
.first()
.should('contain.text', "[DruxtBlock] Missing Vue template for the 'umami_search' block")
.click()

// It has 5 theme component options.
cy.get(searchBlock)
.find('select option')
.should('have.length', 5)

// I create the DruxtBlockSearchFormBlock component
cy.get(searchBlock)
.find('select')
.select('DruxtBlockSearchFormBlock')
cy.get(searchBlock)
.find('button')
.click()

// cy.wait(5000)
// cy.get(searchBlock)
// .find('details summary')
// .first()
// .should('contain.text', "[DruxtBlockSearchFormBlock] Debug")
// .click()
})
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
"docs:test:open": "start-server-and-test docs:dev http://localhost:3000 'npx cypress open --project docs/nuxt/test'",
"example:druxt-site": "cd examples/druxt-site && yarn && yarn dev",
"example:druxt-site:storybook": "cd examples/druxt-site && yarn && yarn storybook",
"example:druxt-site:storybook:test": "start-server-and-test 'yarn example:druxt-site:storybook --port 3000' http://localhost:3000 'npx cypress run --project examples/druxt-site/test --spec examples/druxt-site/test/cypress/e2e/storybook.cy.js'",
"example:druxt-site:storybook:test": "start-server-and-test 'yarn example:druxt-site:storybook --port 3000' http://localhost:3000 'npx cypress run --project examples/druxt-site/test --spec \"examples/druxt-site/test/cypress/e2e/storybook/*.cy.js\"'",
"example:druxt-site:storybook:test:open": "start-server-and-test 'yarn example:druxt-site:storybook --port 3000' http://localhost:3000 'npx cypress open --project examples/druxt-site/test'",
"example:druxt-site:test": "start-server-and-test 'yarn example:druxt-site' http://localhost:3000 'npx cypress run --project examples/druxt-site/test --spec examples/druxt-site/test/cypress/e2e/umami-*.cy.js'",
"example:druxt-site:test": "start-server-and-test 'yarn example:druxt-site' http://localhost:3000 'npx cypress run --project examples/druxt-site/test --spec \"examples/druxt-site/test/cypress/e2e/nuxt/*.cy.j\"s'",
"example:druxt-site:test:open": "start-server-and-test 'yarn example:druxt-site' http://localhost:3000 'npx cypress open --project examples/druxt-site/test'",
"lint": "eslint --ext .js,.vue packages/*/src",
"lint:commit": "commitlint",
Expand Down
27 changes: 19 additions & 8 deletions packages/blocks/src/components/DruxtBlock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,15 @@ export default {
// Debug data.
/* @slot Debug information */
scopedSlots.default = () => {
let summary = `Placeholder for the '${((this.block || {}).attributes || {}).drupal_internal__id}' block.`
let description = [
h('p', 'DruxtBlocks knows that a block can be rendered, and has information provided by Drupal, but not enough to automatically determine the behaviour of the block.'),
h('p', 'To render this block manually, create a Nuxt component with one of the following component options.'),
]
let summary, description
if ((this.block || {}).attributes) {
summary = `Missing Vue template for the '${this.block.attributes.drupal_internal__id}' block`
description = [
h('p', `Create a Druxt theme component to render the "${this.block.attributes.settings.label}" block.`),
]
// Ensure an ID or UUID.
if (!this.id && !this.uuid) {
} else if (!this.id && !this.uuid) {
summary = "Missing required 'id' or 'uuid' prop."
description = [h('p', "The DruxtBlock component requires either the 'id' or 'uuid' prop to be set.")]
}
Expand All @@ -228,14 +229,24 @@ export default {
{ props: { summary } },
[
h('div', description),
!!this.component.options.length && h('label', ['Component options:', h('ul', this.component.options.map((s) => h('li', [s])))]),
((this.block || {}).attributes || {}).settings && h('label', ['Block settings:', h('pre', [JSON.stringify(this.block.attributes.settings, null, ' ')])])
!!this.component.options.length && h('DruxtDevelTemplate', { props: { options: this.component.options }}),
!!this.block && h('details', [h('summary', 'JSON:API resource'), h('pre', [h('code', [JSON.stringify(this.block, null, ' ')])])])
]
)
}
return scopedSlots
},
/**
* Druxt development template tool configuration.
*/
template: {
debug: 'block',
mixins: {
'DruxtBlocksBlockMixin': 'druxt-blocks'
}
}
},
}
Expand Down
12 changes: 11 additions & 1 deletion packages/blocks/src/components/DruxtBlockRegion.vue
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,17 @@ export default {
return scopedSlots
},
},
/**
* Druxt development template tool configuration.
*/
template: {
debug: '{ blocks, name, theme }',
mixins: {
'DruxtBlocksRegionMixin': 'druxt-blocks'
}
}
}
}
/**
Expand Down
2 changes: 2 additions & 0 deletions packages/blocks/test/components/DruxtBlock.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* global beforeEach, describe, expect, jest, test */

import 'regenerator-runtime/runtime'
import { createLocalVue, mount } from '@vue/test-utils'
import Vuex from 'vuex'
Expand Down
10 changes: 10 additions & 0 deletions packages/breadcrumb/src/components/DruxtBreadcrumb.vue
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,16 @@ export default {
return scopedSlots
},
/**
* Druxt development template tool configuration.
*/
template: {
debug: 'crumbs',
mixins: {
'DruxtBreadcrumbMixin': 'druxt-breadcrumb'
}
}
},
}
Expand Down
6 changes: 5 additions & 1 deletion packages/druxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
"require": "./dist/druxt.ssr.js",
"import": "./dist/druxt.esm.js"
},
"./components/*": "./dist/components/*"
"./components/*": "./dist/components/*",
"./server-middleware/*": "./dist/server-middleware/*",
"./dist/server-middleware/template.mjs": "./dist/server-middleware/template.mjs"
},
"main": "dist/druxt.ssr.js",
"module": "dist/druxt.esm.js",
Expand All @@ -42,6 +44,8 @@
"chalk": "^4.1.2",
"deepmerge": "^4.2.2",
"drupal-jsonapi-params": "^2.1.0",
"express-rate-limit": "^6.6.0",
"launch-editor": "^2.6.0",
"md5": "^2.3.0",
"querystring": "^0.2.1",
"scule": "^0.3.2"
Expand Down
29 changes: 28 additions & 1 deletion packages/druxt/src/components/DruxtDebug.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<template>
<details v-if="$nuxt.context.isDev">
<details
v-if="$nuxt.context.isDev"
title="Expand for details"
>
<summary v-text="title" />
<pre v-if="json"><!--
--><code>{{ JSON.stringify(json, null, ' ') }}</code><!--
--></pre>
<!-- @slot Debug content -->
<slot />
<small>Note: This message is only visible when development mode is enabled.</small>
</details>

<div v-else />
Expand Down Expand Up @@ -81,7 +85,30 @@ details {
padding: 1rem;
}
details > summary {
cursor: pointer;
font-weight: 600;
}
details > summary::after {
content: '(expand)';
font-size: 0.75rem;
color: blue;
vertical-align: super;
text-decoration: underline;
margin-left: 0.25rem;
}
details[open] > summary {
margin-bottom: 1rem;
}
details[open] > summary::after {
content: ''
}
details small:last-of-type {
display: block;
margin-top: 2rem;
}
</style>
51 changes: 51 additions & 0 deletions packages/druxt/src/components/DruxtDevelTemplate.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template>
<div>
<select v-model="option">
<option
v-for="(label, key) of options"
:key="key"
v-text="label"
/>
</select>
<button @click="onClick">
Create
</button>
</div>
</template>

<script>
export default {
data: () => ({
option: undefined,
}),
computed: {
module: ({ $parent }) => ($parent.component || {}).options
? $parent
: ($parent.$parent || {}).$parent || {},
options: ({ module }) => (module.component || {}).options || []
},
created() {
this.option = this.options[0]
},
methods: {
onClick() {
this.$axios({
url: '/_druxt/template/add',
baseURL: '/',
method: 'post',
data: {
path: this.option,
settings: {
component: this.module.$options._componentTag,
props: Object.entries(this.module.component.propsData || {}).map(([key, value]) => ({ key, type: typeof value })),
...((this.module.$options.druxt || {}).template || {}),
}
}
})
}
}
}
</script>
9 changes: 6 additions & 3 deletions packages/druxt/src/components/DruxtModule.vue
Original file line number Diff line number Diff line change
Expand Up @@ -384,12 +384,15 @@ export default {
// Provide debug data if Nuxt is running in dev mode.
if (!scopedSlots.default && this.$nuxt.context.isDev) {
if (!scopedSlots.debug) {
const summary = 'Missing default slot'
const description = [h('p', `The "${this.$options._componentTag}" component does not provide a default slot.`), h('p', 'Create a Druxt theme component to render the data as required.')]
scopedSlots.debug = () => h(
'DruxtDebug',
{ props: { summary: 'Missing default slot' } },
{ props: { summary } },
[
h('label', ['Component options:', h('ul', this.component.options.map((s) => h('li', [s])))]),
h('label', ['propsData:', h('pre', [h('code', [JSON.stringify(this.component.propsData, null, ' ')])])])
h('div', description),
this.component.is === 'DruxtWrapper' && !!this.component.options.length && h('DruxtDevelTemplate', { props: { options: this.component.options }}),
h('details', [h('summary', 'Data'), h('pre', [h('code', [JSON.stringify(this.component.propsData, null, ' ')])])])
]
)
}
Expand Down
9 changes: 9 additions & 0 deletions packages/druxt/src/nuxt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ const DruxtNuxtModule = async function (moduleOptions = {}) {
this.options.cli.badgeMessages.push(`${chalk.blue.bold('Druxt')} @ v${meta.version}`)
this.options.cli.badgeMessages.push(`${chalk.bold('API:')} ${chalk.blue.underline(options.baseUrl + options.endpoint)}`)

// Development mode features.
if (this.options.dev) {
// Add the template stubber server middleware.
this.addServerMiddleware({
path: '/_druxt/template',
handler: 'druxt/dist/server-middleware/template.mjs'
})
}

// Nuxt Storybook.
const self = this
this.nuxt.hook('storybook:config', async ({ stories }) => {
Expand Down
Loading

0 comments on commit f6b4a66

Please sign in to comment.