From f6b4a664e4f6e22bede68f44c13e9cf133ce0822 Mon Sep 17 00:00:00 2001 From: Stuart Clark Date: Fri, 28 Oct 2022 11:40:14 +1100 Subject: [PATCH] feat(#578): add missing theme component helper (#580) * 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 --- .changeset/cyan-kings-wonder.md | 5 + .changeset/lemon-oranges-marry.md | 5 + .changeset/long-bottles-bake.md | 5 + .changeset/long-weeks-pay.md | 5 + .changeset/metal-clouds-collect.md | 5 + .changeset/rude-lizards-pretend.md | 5 + .changeset/selfish-scissors-wink.md | 5 + .changeset/sharp-glasses-ring.md | 5 + .changeset/slow-owls-burn.md | 5 + .circleci/config.yml | 4 +- .../e2e/nuxt/druxt-devel-template.cy.js | 36 ++++++ .../e2e/{ => nuxt}/umami-homepage.cy.js | 0 .../e2e/{ => storybook}/storybook.cy.js | 0 package.json | 4 +- packages/blocks/src/components/DruxtBlock.vue | 27 +++-- .../src/components/DruxtBlockRegion.vue | 12 +- .../blocks/test/components/DruxtBlock.test.js | 2 + .../src/components/DruxtBreadcrumb.vue | 10 ++ packages/druxt/package.json | 6 +- packages/druxt/src/components/DruxtDebug.vue | 29 ++++- .../src/components/DruxtDevelTemplate.vue | 51 ++++++++ packages/druxt/src/components/DruxtModule.vue | 9 +- packages/druxt/src/nuxt/index.js | 9 ++ .../druxt/src/server-middleware/template.js | 111 ++++++++++++++++++ packages/druxt/test/nuxt/index.test.js | 17 ++- .../entity/src/components/DruxtEntity.vue | 29 ++++- packages/entity/src/components/DruxtField.vue | 22 +++- packages/entity/src/mixins/entity.js | 8 +- .../test/components/DruxtEntity.test.js | 10 +- .../entity/test/components/DruxtField.test.js | 2 + .../__snapshots__/DruxtEntity.test.js.snap | 30 +++-- packages/menu/src/components/DruxtMenu.vue | 10 ++ .../router/src/components/DruxtRouter.vue | 10 ++ packages/site/src/components/DruxtSite.vue | 7 ++ packages/views/src/components/DruxtView.vue | 10 ++ .../views/src/components/DruxtViewsFilter.vue | 12 +- .../src/components/DruxtViewsFilters.vue | 10 ++ .../views/src/components/DruxtViewsPager.vue | 10 ++ .../views/src/components/DruxtViewsSorts.vue | 10 ++ yarn.lock | 28 +++++ 40 files changed, 536 insertions(+), 44 deletions(-) create mode 100644 .changeset/cyan-kings-wonder.md create mode 100644 .changeset/lemon-oranges-marry.md create mode 100644 .changeset/long-bottles-bake.md create mode 100644 .changeset/long-weeks-pay.md create mode 100644 .changeset/metal-clouds-collect.md create mode 100644 .changeset/rude-lizards-pretend.md create mode 100644 .changeset/selfish-scissors-wink.md create mode 100644 .changeset/sharp-glasses-ring.md create mode 100644 .changeset/slow-owls-burn.md create mode 100644 examples/druxt-site/test/cypress/e2e/nuxt/druxt-devel-template.cy.js rename examples/druxt-site/test/cypress/e2e/{ => nuxt}/umami-homepage.cy.js (100%) rename examples/druxt-site/test/cypress/e2e/{ => storybook}/storybook.cy.js (100%) create mode 100644 packages/druxt/src/components/DruxtDevelTemplate.vue create mode 100644 packages/druxt/src/server-middleware/template.js diff --git a/.changeset/cyan-kings-wonder.md b/.changeset/cyan-kings-wonder.md new file mode 100644 index 000000000..3b66482a4 --- /dev/null +++ b/.changeset/cyan-kings-wonder.md @@ -0,0 +1,5 @@ +--- +"druxt-views": minor +--- + +feat(#578): updated components to support the DruxtDevelTemplate tool. diff --git a/.changeset/lemon-oranges-marry.md b/.changeset/lemon-oranges-marry.md new file mode 100644 index 000000000..ac2cfec36 --- /dev/null +++ b/.changeset/lemon-oranges-marry.md @@ -0,0 +1,5 @@ +--- +"druxt": minor +--- + +feat(#578): added DruxtDevelTemplate component to simplify template creation in development mode. diff --git a/.changeset/long-bottles-bake.md b/.changeset/long-bottles-bake.md new file mode 100644 index 000000000..e85dab4c6 --- /dev/null +++ b/.changeset/long-bottles-bake.md @@ -0,0 +1,5 @@ +--- +"druxt-site": minor +--- + +feat(#578): updated component to support the DruxtDevelTemplate tool. diff --git a/.changeset/long-weeks-pay.md b/.changeset/long-weeks-pay.md new file mode 100644 index 000000000..7c1a349e5 --- /dev/null +++ b/.changeset/long-weeks-pay.md @@ -0,0 +1,5 @@ +--- +"druxt-entity": minor +--- + +feat(#578): updated missing schema/vue component message with DruxtDevelTemplate tool. diff --git a/.changeset/metal-clouds-collect.md b/.changeset/metal-clouds-collect.md new file mode 100644 index 000000000..53a8d6ff5 --- /dev/null +++ b/.changeset/metal-clouds-collect.md @@ -0,0 +1,5 @@ +--- +"druxt-menu": minor +--- + +feat(#578): updated components to support the DruxtDevelTemplate tool. diff --git a/.changeset/rude-lizards-pretend.md b/.changeset/rude-lizards-pretend.md new file mode 100644 index 000000000..c70c2b3f9 --- /dev/null +++ b/.changeset/rude-lizards-pretend.md @@ -0,0 +1,5 @@ +--- +"druxt-router": minor +--- + +feat(#578): updated component to support the DruxtDevelTemplate tool. diff --git a/.changeset/selfish-scissors-wink.md b/.changeset/selfish-scissors-wink.md new file mode 100644 index 000000000..a9bb8ba2e --- /dev/null +++ b/.changeset/selfish-scissors-wink.md @@ -0,0 +1,5 @@ +--- +"druxt": minor +--- + +feat(#578): updated missing default slot message with DruxtDevelTemplate tool. diff --git a/.changeset/sharp-glasses-ring.md b/.changeset/sharp-glasses-ring.md new file mode 100644 index 000000000..1069116be --- /dev/null +++ b/.changeset/sharp-glasses-ring.md @@ -0,0 +1,5 @@ +--- +"druxt-breadcrumb": minor +--- + +feat(#578): updated component to support the DruxtDevelTemplate tool. diff --git a/.changeset/slow-owls-burn.md b/.changeset/slow-owls-burn.md new file mode 100644 index 000000000..589910a71 --- /dev/null +++ b/.changeset/slow-owls-burn.md @@ -0,0 +1,5 @@ +--- +"druxt-blocks": minor +--- + +feat(#578): updated missing vue component message with DruxtDevelTemplate tool. diff --git a/.circleci/config.yml b/.circleci/config.yml index b67b6b7ef..0636ae7d6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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: diff --git a/examples/druxt-site/test/cypress/e2e/nuxt/druxt-devel-template.cy.js b/examples/druxt-site/test/cypress/e2e/nuxt/druxt-devel-template.cy.js new file mode 100644 index 000000000..5aae7b63c --- /dev/null +++ b/examples/druxt-site/test/cypress/e2e/nuxt/druxt-devel-template.cy.js @@ -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() +}) diff --git a/examples/druxt-site/test/cypress/e2e/umami-homepage.cy.js b/examples/druxt-site/test/cypress/e2e/nuxt/umami-homepage.cy.js similarity index 100% rename from examples/druxt-site/test/cypress/e2e/umami-homepage.cy.js rename to examples/druxt-site/test/cypress/e2e/nuxt/umami-homepage.cy.js diff --git a/examples/druxt-site/test/cypress/e2e/storybook.cy.js b/examples/druxt-site/test/cypress/e2e/storybook/storybook.cy.js similarity index 100% rename from examples/druxt-site/test/cypress/e2e/storybook.cy.js rename to examples/druxt-site/test/cypress/e2e/storybook/storybook.cy.js diff --git a/package.json b/package.json index cfd069877..de911d31b 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/packages/blocks/src/components/DruxtBlock.vue b/packages/blocks/src/components/DruxtBlock.vue index e256bda0a..703003687 100644 --- a/packages/blocks/src/components/DruxtBlock.vue +++ b/packages/blocks/src/components/DruxtBlock.vue @@ -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.")] } @@ -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' + } + } }, } diff --git a/packages/blocks/src/components/DruxtBlockRegion.vue b/packages/blocks/src/components/DruxtBlockRegion.vue index 28514aa37..e70d78349 100644 --- a/packages/blocks/src/components/DruxtBlockRegion.vue +++ b/packages/blocks/src/components/DruxtBlockRegion.vue @@ -231,7 +231,17 @@ export default { return scopedSlots }, - }, + + /** + * Druxt development template tool configuration. + */ + template: { + debug: '{ blocks, name, theme }', + mixins: { + 'DruxtBlocksRegionMixin': 'druxt-blocks' + } + } + } } /** diff --git a/packages/blocks/test/components/DruxtBlock.test.js b/packages/blocks/test/components/DruxtBlock.test.js index 6fd85f59e..5b3fa3567 100644 --- a/packages/blocks/test/components/DruxtBlock.test.js +++ b/packages/blocks/test/components/DruxtBlock.test.js @@ -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' diff --git a/packages/breadcrumb/src/components/DruxtBreadcrumb.vue b/packages/breadcrumb/src/components/DruxtBreadcrumb.vue index b18fcb470..92e83f2d9 100644 --- a/packages/breadcrumb/src/components/DruxtBreadcrumb.vue +++ b/packages/breadcrumb/src/components/DruxtBreadcrumb.vue @@ -224,6 +224,16 @@ export default { return scopedSlots }, + + /** + * Druxt development template tool configuration. + */ + template: { + debug: 'crumbs', + mixins: { + 'DruxtBreadcrumbMixin': 'druxt-breadcrumb' + } + } }, } diff --git a/packages/druxt/package.json b/packages/druxt/package.json index 80ddeb47d..4c5206689 100644 --- a/packages/druxt/package.json +++ b/packages/druxt/package.json @@ -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", @@ -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" diff --git a/packages/druxt/src/components/DruxtDebug.vue b/packages/druxt/src/components/DruxtDebug.vue index 122d23429..f606ee662 100644 --- a/packages/druxt/src/components/DruxtDebug.vue +++ b/packages/druxt/src/components/DruxtDebug.vue @@ -1,11 +1,15 @@