From 57bd753207db26ebc08277aab2cf33ec48b0878e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 1 Aug 2022 15:32:35 +0200 Subject: [PATCH 01/12] installer-database should reset its install state button --- .../src/installer/installer-database.element.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts b/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts index ff2846f684..ef468b57df 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts @@ -4,11 +4,7 @@ import { customElement, property, query, state } from 'lit/decorators.js'; import { Subscription } from 'rxjs'; import { UmbContextConsumerMixin } from '../core/context'; -import { - ProblemDetails, - UmbracoInstallerDatabaseModel, - UmbracoPerformInstallDatabaseConfiguration, -} from '../core/models'; +import { ProblemDetails, UmbracoInstallerDatabaseModel, UmbracoPerformInstallDatabaseConfiguration } from '../core/models'; import { UmbInstallerContext } from './installer-context'; @customElement('umb-installer-database') @@ -184,6 +180,7 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { }; private _handleFulfilled() { this.dispatchEvent(new CustomEvent('next', { bubbles: true, composed: true })); + this._installButton.state = undefined; } private _handleRejected(error: ProblemDetails) { this._installButton.state = 'failed'; From 98bdf0a08e01c3971509c748038d4dc5def49526 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 1 Aug 2022 15:32:54 +0200 Subject: [PATCH 02/12] add each installer step as its own story with a mocked context --- .../src/installer/installer.stories.ts | 97 +++++++++++++++++++ .../src/stories/installer.stories.ts | 13 --- 2 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/stories/installer.stories.ts diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts new file mode 100644 index 0000000000..d2a8f6554c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts @@ -0,0 +1,97 @@ +import './installer.element'; + +import { Meta, Story } from '@storybook/web-components'; +import { css, CSSResult, LitElement } from 'lit'; +import { html } from 'lit-html'; +import { customElement } from 'lit/decorators.js'; +import { BehaviorSubject } from 'rxjs'; + +import { UmbInstallerUser } from '.'; +import { UmbContextProviderMixin } from '../core/context'; +import { PostInstallRequest, UmbracoInstaller } from '../core/models'; + +@customElement('mock-installer-context') +class UmbInstallerContext extends UmbContextProviderMixin(LitElement) { + static styles: CSSResult[] = [ + css` + :host { + display: block; + margin: 2rem 25%; + padding: 1rem; + border: 1px solid #ddd; + } + `, + ]; + + constructor() { + super(); + const data = new BehaviorSubject({ + telemetryLevel: 'Basic', + user: { + name: 'Umbraco', + email: 'test@umbraco.com', + password: 'test123456', + subscribeToNewsletter: false, + }, + }); + + this.provideContext('umbInstallerContext', { + data, + getData: () => data.value, + settings: new BehaviorSubject({ + user: { + consentLevels: [{ description: 'This is a consent text', level: 'Basic' }], + minCharLength: 2, + minNonAlphaNumericLength: 2, + }, + databases: [ + { + id: '123', + defaultDatabaseName: 'umbraco', + displayName: 'SQLite', + isConfigured: false, + providerName: 'Umbraco', + requiresConnectionTest: false, + requiresCredentials: false, + requiresServer: false, + serverPlaceholder: 'umbraco', + sortOrder: 0, + supportsIntegratedAuthentication: false, + }, + ], + }), + appendData: () => true, + requestInstall: () => Promise.resolve(), + } as Partial); + } + + render() { + return html``; + } +} + +export default { + title: 'Installer/Installer', + component: 'umb-installer', + id: 'installer', + decorators: [(story) => html`${story()}`], +} as Meta; + +export const Step1User: Story = () => html``; +Step1User.storyName = 'Step 1: User'; +Step1User.parameters = { + actions: { + handles: ['next'], + }, +}; + +export const Step2Database: Story = () => html``; +Step2Database.storyName = 'Step 2: Database'; +Step2Database.parameters = { + actions: { + handles: ['previous', 'next'], + }, +}; + +export const Step3Installing: Story = () => html``; +Step3Installing.storyName = 'Step 3: Installing'; diff --git a/src/Umbraco.Web.UI.Client/src/stories/installer.stories.ts b/src/Umbraco.Web.UI.Client/src/stories/installer.stories.ts deleted file mode 100644 index 4d85fcb820..0000000000 --- a/src/Umbraco.Web.UI.Client/src/stories/installer.stories.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Story, Meta } from '@storybook/web-components'; -import { html } from 'lit-html'; -import '../installer/installer.element'; - -export default { - title: 'Installer/Installer', - component: 'umb-installer', - id: 'installer', -} as Meta; - -const Template: Story = () => html``; - -export const Overview = Template.bind({}); From 6c1fc5c5e63867e4dfd4f93a25bbdd80d6c5fd1e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:59:59 +0200 Subject: [PATCH 03/12] add @storybook/a11y to storybook --- src/Umbraco.Web.UI.Client/.storybook/main.js | 2 +- src/Umbraco.Web.UI.Client/package-lock.json | 164 +++++++++++++++++++ src/Umbraco.Web.UI.Client/package.json | 1 + 3 files changed, 166 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/.storybook/main.js b/src/Umbraco.Web.UI.Client/.storybook/main.js index 283705d121..2dda838ca8 100644 --- a/src/Umbraco.Web.UI.Client/.storybook/main.js +++ b/src/Umbraco.Web.UI.Client/.storybook/main.js @@ -1,6 +1,6 @@ module.exports = { stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], - addons: ['@storybook/addon-links', '@storybook/addon-essentials'], + addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-a11y'], framework: '@storybook/web-components', core: { builder: '@storybook/builder-vite', diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 198be6d4b1..0452f4db11 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -19,6 +19,7 @@ "devDependencies": { "@babel/core": "^7.18.9", "@open-wc/testing": "^3.1.6", + "@storybook/addon-a11y": "^6.5.9", "@storybook/addon-actions": "^6.5.9", "@storybook/addon-essentials": "^6.5.9", "@storybook/addon-links": "^6.5.9", @@ -2818,6 +2819,46 @@ "node": ">= 8.0.0" } }, + "node_modules/@storybook/addon-a11y": { + "version": "6.5.9", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-6.5.9.tgz", + "integrity": "sha512-jRiuJ2xlN8quVq2lOqpxqyuwAj8xLcgVBPy+Mf220u7AZmmbS/0sONyHKROfEBjJoHQAQYqn2vSAeuQZuTWyVA==", + "dev": true, + "dependencies": { + "@storybook/addons": "6.5.9", + "@storybook/api": "6.5.9", + "@storybook/channels": "6.5.9", + "@storybook/client-logger": "6.5.9", + "@storybook/components": "6.5.9", + "@storybook/core-events": "6.5.9", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/theming": "6.5.9", + "axe-core": "^4.2.0", + "core-js": "^3.8.2", + "global": "^4.4.0", + "lodash": "^4.17.21", + "react-sizeme": "^3.0.1", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/@storybook/addon-actions": { "version": "6.5.9", "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.5.9.tgz", @@ -7970,6 +8011,12 @@ } ] }, + "node_modules/batch-processor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/batch-processor/-/batch-processor-1.0.0.tgz", + "integrity": "sha512-xoLQD8gmmR32MeuBHgH0Tzd5PuSZx71ZsbhVxOCRbgktZEPe4SQy7s9Z50uPp0F/f7iw2XmkHN2xkgbMfckMDA==", + "dev": true + }, "node_modules/better-opn": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-2.1.1.tgz", @@ -10810,6 +10857,15 @@ "resolved": "https://registry.npmjs.org/element-internals-polyfill/-/element-internals-polyfill-1.1.6.tgz", "integrity": "sha512-PW63CzI6GKewCYfX7hZ5gFJO5uib+oAy/AwELrOEfyBI3SlYOXFjVhDEIxlg0CV4kIa4ixjO+5XFhP/Cx1Lurw==" }, + "node_modules/element-resize-detector": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.4.tgz", + "integrity": "sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg==", + "dev": true, + "dependencies": { + "batch-processor": "1.0.0" + } + }, "node_modules/elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -14518,6 +14574,15 @@ "node": ">= 0.10" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/ip": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", @@ -19085,6 +19150,18 @@ "node": ">=0.10.0" } }, + "node_modules/react-sizeme": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-3.0.2.tgz", + "integrity": "sha512-xOIAOqqSSmKlKFJLO3inBQBdymzDuXx4iuwkNcJmC96jeiOg5ojByvL+g3MW9LPEsojLbC6pf68zOfobK8IPlw==", + "dev": true, + "dependencies": { + "element-resize-detector": "^1.2.2", + "invariant": "^2.2.4", + "shallowequal": "^1.1.0", + "throttle-debounce": "^3.0.1" + } + }, "node_modules/react-syntax-highlighter": { "version": "15.5.0", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", @@ -20478,6 +20555,12 @@ "node": ">=8" } }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "dev": true + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -22007,6 +22090,15 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/throttle-debounce": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", + "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -26442,6 +26534,30 @@ "picomatch": "^2.2.2" } }, + "@storybook/addon-a11y": { + "version": "6.5.9", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-6.5.9.tgz", + "integrity": "sha512-jRiuJ2xlN8quVq2lOqpxqyuwAj8xLcgVBPy+Mf220u7AZmmbS/0sONyHKROfEBjJoHQAQYqn2vSAeuQZuTWyVA==", + "dev": true, + "requires": { + "@storybook/addons": "6.5.9", + "@storybook/api": "6.5.9", + "@storybook/channels": "6.5.9", + "@storybook/client-logger": "6.5.9", + "@storybook/components": "6.5.9", + "@storybook/core-events": "6.5.9", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/theming": "6.5.9", + "axe-core": "^4.2.0", + "core-js": "^3.8.2", + "global": "^4.4.0", + "lodash": "^4.17.21", + "react-sizeme": "^3.0.1", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + } + }, "@storybook/addon-actions": { "version": "6.5.9", "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.5.9.tgz", @@ -30534,6 +30650,12 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, + "batch-processor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/batch-processor/-/batch-processor-1.0.0.tgz", + "integrity": "sha512-xoLQD8gmmR32MeuBHgH0Tzd5PuSZx71ZsbhVxOCRbgktZEPe4SQy7s9Z50uPp0F/f7iw2XmkHN2xkgbMfckMDA==", + "dev": true + }, "better-opn": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-2.1.1.tgz", @@ -32793,6 +32915,15 @@ "resolved": "https://registry.npmjs.org/element-internals-polyfill/-/element-internals-polyfill-1.1.6.tgz", "integrity": "sha512-PW63CzI6GKewCYfX7hZ5gFJO5uib+oAy/AwELrOEfyBI3SlYOXFjVhDEIxlg0CV4kIa4ixjO+5XFhP/Cx1Lurw==" }, + "element-resize-detector": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.4.tgz", + "integrity": "sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg==", + "dev": true, + "requires": { + "batch-processor": "1.0.0" + } + }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -35573,6 +35704,15 @@ "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "ip": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", @@ -39090,6 +39230,18 @@ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true }, + "react-sizeme": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-3.0.2.tgz", + "integrity": "sha512-xOIAOqqSSmKlKFJLO3inBQBdymzDuXx4iuwkNcJmC96jeiOg5ojByvL+g3MW9LPEsojLbC6pf68zOfobK8IPlw==", + "dev": true, + "requires": { + "element-resize-detector": "^1.2.2", + "invariant": "^2.2.4", + "shallowequal": "^1.1.0", + "throttle-debounce": "^3.0.1" + } + }, "react-syntax-highlighter": { "version": "15.5.0", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", @@ -40197,6 +40349,12 @@ "kind-of": "^6.0.2" } }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "dev": true + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -41408,6 +41566,12 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "throttle-debounce": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", + "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 4bda01037f..8604e717ab 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -44,6 +44,7 @@ "devDependencies": { "@babel/core": "^7.18.9", "@open-wc/testing": "^3.1.6", + "@storybook/addon-a11y": "^6.5.9", "@storybook/addon-actions": "^6.5.9", "@storybook/addon-essentials": "^6.5.9", "@storybook/addon-links": "^6.5.9", From b14f816cd20bc72716fe2433f7ecdc9c1e3cab71 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:14:10 +0200 Subject: [PATCH 04/12] add storybook-msw to storybook --- .../.storybook/preview.js | 16 +++++++++++++ src/Umbraco.Web.UI.Client/package-lock.json | 24 +++++++++++++++++++ src/Umbraco.Web.UI.Client/package.json | 1 + .../src/mocks/browser.ts | 19 ++++++++------- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/.storybook/preview.js b/src/Umbraco.Web.UI.Client/.storybook/preview.js index 6fac879af1..84d7f64230 100644 --- a/src/Umbraco.Web.UI.Client/.storybook/preview.js +++ b/src/Umbraco.Web.UI.Client/.storybook/preview.js @@ -1,6 +1,17 @@ import '@umbraco-ui/uui'; import '@umbraco-ui/uui-css/dist/uui-css.css'; +import { initialize, mswDecorator } from 'msw-storybook-addon'; + +import { onUnhandledRequest } from '../src/mocks/browser'; +import { handlers } from '../src/mocks/handlers'; + +// Initialize MSW +initialize({onUnhandledRequest}); + +// Provide the MSW addon decorator globally +export const decorators = [mswDecorator]; + export const parameters = { actions: { argTypesRegex: '^on.*' }, controls: { @@ -10,4 +21,9 @@ export const parameters = { date: /Date$/, }, }, + msw: { + handlers: { + global: handlers + } + } }; diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 0452f4db11..d9ff7cd76c 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -42,6 +42,7 @@ "eslint-plugin-storybook": "^0.6.1", "lit-html": "^2.2.7", "msw": "^0.44.2", + "msw-storybook-addon": "^1.6.3", "prettier": "2.7.1", "typescript": "^4.7.4", "vite": "^3.0.3" @@ -16998,6 +16999,19 @@ } } }, + "node_modules/msw-storybook-addon": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-1.6.3.tgz", + "integrity": "sha512-Ps80WdRmXsmenoTwfrgKMNpQD8INUUFyUFyZOecx8QjuqSlL++UYrLaGyACXN2goOn+/VS6rb0ZapbjrasPClg==", + "dev": true, + "dependencies": { + "@storybook/addons": "^6.0.0", + "is-node-process": "^1.0.1" + }, + "peerDependencies": { + "msw": ">=0.35.0 <1.0.0" + } + }, "node_modules/msw/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -37629,6 +37643,16 @@ } } }, + "msw-storybook-addon": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-1.6.3.tgz", + "integrity": "sha512-Ps80WdRmXsmenoTwfrgKMNpQD8INUUFyUFyZOecx8QjuqSlL++UYrLaGyACXN2goOn+/VS6rb0ZapbjrasPClg==", + "dev": true, + "requires": { + "@storybook/addons": "^6.0.0", + "is-node-process": "^1.0.1" + } + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 8604e717ab..eb0cfd0a86 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -67,6 +67,7 @@ "eslint-plugin-storybook": "^0.6.1", "lit-html": "^2.2.7", "msw": "^0.44.2", + "msw-storybook-addon": "^1.6.3", "prettier": "2.7.1", "typescript": "^4.7.4", "vite": "^3.0.3" diff --git a/src/Umbraco.Web.UI.Client/src/mocks/browser.ts b/src/Umbraco.Web.UI.Client/src/mocks/browser.ts index e296cc5fd0..bc470aaff6 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/browser.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/browser.ts @@ -1,15 +1,18 @@ -import { setupWorker } from 'msw'; +import { MockedRequest, setupWorker } from 'msw'; + import { handlers } from './handlers'; const worker = setupWorker(...handlers); +export const onUnhandledRequest = (req: MockedRequest) => { + if (req.url.pathname.startsWith('/node_modules/')) return; + if (req.url.pathname.startsWith('/src/')) return; + if (req.destination === 'image') return; + + console.warn('Found an unhandled %s request to %s', req.method, req.url.href); +}; + export const startMockServiceWorker = () => worker.start({ - onUnhandledRequest: (req) => { - if (req.url.pathname.startsWith('/node_modules/')) return; - if (req.url.pathname.startsWith('/src/')) return; - if (req.destination === 'image') return; - - console.warn('Found an unhandled %s request to %s', req.method, req.url.href); - }, + onUnhandledRequest, }); From e6e5f80bf7cecc177a9fc0fcc875bace99aeaf28 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:21:23 +0200 Subject: [PATCH 05/12] rename titles of stories to group them --- src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts | 2 +- src/Umbraco.Web.UI.Client/src/upgrader/upgrader.stories.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts index d2a8f6554c..92fe39723a 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts @@ -71,7 +71,7 @@ class UmbInstallerContext extends UmbContextProviderMixin(LitElement) { } export default { - title: 'Installer/Installer', + title: 'Components/Installer/Steps', component: 'umb-installer', id: 'installer', decorators: [(story) => html`${story()}`], diff --git a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.stories.ts b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.stories.ts index b8d14a2d0c..6c569b4b77 100644 --- a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.stories.ts @@ -6,7 +6,7 @@ import { html } from 'lit-html'; import { UmbUpgraderView } from './upgrader-view.element'; export default { - title: 'Upgrader/Upgrader', + title: 'Components/Upgrader/States', args: { errorMessage: '', upgrading: false, From c4de9c59c860d21e842de6bf61dab9fa01e38b19 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:35:03 +0200 Subject: [PATCH 06/12] update 'detailed' text to latest version --- src/Umbraco.Web.UI.Client/src/mocks/domains/install.handlers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/mocks/domains/install.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/domains/install.handlers.ts index af8c1fe18e..9651945019 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/domains/install.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/domains/install.handlers.ts @@ -23,7 +23,7 @@ export const handlers = [ { level: 'Detailed', description: - 'We will send:\n
- Anonymized site ID, umbraco version, and packages installed.\n
- Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, and Property Editors in use.\n
- System information: Webserver, server OS, server framework, server OS language, and database provider.\n
- Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, and if you are in debug mode.\n
\n
We might change what we send on the Detailed level in the future. If so, it will be listed above.\n
By choosing "Detailed" you agree to current and future anonymized information being collected.
', + 'We will send:
  • Anonymized site ID, umbraco version, and packages installed.
  • Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, and Property Editors in use.
  • System information: Webserver, server OS, server framework, server OS language, and database provider.
  • Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, and if you are in debug mode.
We might change what we send on the Detailed level in the future. If so, it will be listed above.
By choosing "Detailed" you agree to current and future anonymized information being collected.
', }, ], }, From 0debb6a8fb4885c07698d264621587a2872f46ca Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:36:24 +0200 Subject: [PATCH 07/12] add a context-provider element to inject selected contexts in stories --- .../core/context/context-provider.element.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/core/context/context-provider.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/core/context/context-provider.element.ts b/src/Umbraco.Web.UI.Client/src/core/context/context-provider.element.ts new file mode 100644 index 0000000000..172c8aa476 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/context/context-provider.element.ts @@ -0,0 +1,36 @@ +import { html, LitElement } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; + +import { UmbContextProviderMixin } from './context-provider.mixin'; + +@customElement('umb-context-provider') +export class UmbContextProviderElement extends UmbContextProviderMixin(LitElement) { + /** + * The value to provide to the context. + * @required + */ + @property({ type: Object }) + value!: unknown; + + /** + * The key to provide to the context. + * @required + */ + @property({ type: String }) + key!: string; + + connectedCallback() { + super.connectedCallback(); + if (!this.key) { + throw new Error('The key property is required.'); + } + if (!this.value) { + throw new Error('The value property is required.'); + } + this.provideContext(this.key, this.value); + } + + render() { + return html``; + } +} From ec0f8e25be1ce875e3cbbba9fe8d88d5b5d6426c Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:36:37 +0200 Subject: [PATCH 08/12] add correct wording in installer-consent --- .../src/installer/installer-consent.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer-consent.element.ts b/src/Umbraco.Web.UI.Client/src/installer/installer-consent.element.ts index 1051ba540c..6e3c1aec6e 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer-consent.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer-consent.element.ts @@ -2,6 +2,7 @@ import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; import { Subscription } from 'rxjs'; + import { UmbContextConsumerMixin } from '../core/context'; import { TelemetryModel } from '../core/models'; import { UmbInstallerContext } from './installer-context'; @@ -125,7 +126,7 @@ export class UmbInstallerConsent extends UmbContextConsumerMixin(LitElement) { render() { return html`
-

Consent Level

+

Consent for telemetry data

${this._renderSlider()}
From 29d74ba666c6f7cc939a62915c701341ce62e3b2 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:37:21 +0200 Subject: [PATCH 09/12] add extra installer step for telemetry data --- .../src/installer/installer.stories.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts index 92fe39723a..8248944fd8 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts @@ -85,13 +85,21 @@ Step1User.parameters = { }, }; -export const Step2Database: Story = () => html``; -Step2Database.storyName = 'Step 2: Database'; -Step2Database.parameters = { +export const Step2Telemetry: Story = () => html``; +Step2Telemetry.storyName = 'Step 2: Telemetry data'; +Step2Telemetry.parameters = { actions: { handles: ['previous', 'next'], }, }; -export const Step3Installing: Story = () => html``; -Step3Installing.storyName = 'Step 3: Installing'; +export const Step3Database: Story = () => html``; +Step3Database.storyName = 'Step 3: Database'; +Step3Database.parameters = { + actions: { + handles: ['previous', 'next'], + }, +}; + +export const Step4Installing: Story = () => html``; +Step4Installing.storyName = 'Step 4: Installing'; From 320a7b66a28462c3f76843800af0b82dbf259c99 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:37:46 +0200 Subject: [PATCH 10/12] replace mocked decorator with umb-context-provider element with the real decorator --- .../src/installer/installer.stories.ts | 82 ++++--------------- 1 file changed, 15 insertions(+), 67 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts index 8248944fd8..8893d33acb 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts @@ -1,80 +1,28 @@ -import './installer.element'; +import '../core/context/context-provider.element'; +import './installer-consent.element'; +import './installer-database.element'; +import './installer-installing.element'; +import './installer-user.element'; import { Meta, Story } from '@storybook/web-components'; -import { css, CSSResult, LitElement } from 'lit'; import { html } from 'lit-html'; -import { customElement } from 'lit/decorators.js'; -import { BehaviorSubject } from 'rxjs'; import { UmbInstallerUser } from '.'; -import { UmbContextProviderMixin } from '../core/context'; -import { PostInstallRequest, UmbracoInstaller } from '../core/models'; - -@customElement('mock-installer-context') -class UmbInstallerContext extends UmbContextProviderMixin(LitElement) { - static styles: CSSResult[] = [ - css` - :host { - display: block; - margin: 2rem 25%; - padding: 1rem; - border: 1px solid #ddd; - } - `, - ]; - - constructor() { - super(); - const data = new BehaviorSubject({ - telemetryLevel: 'Basic', - user: { - name: 'Umbraco', - email: 'test@umbraco.com', - password: 'test123456', - subscribeToNewsletter: false, - }, - }); - - this.provideContext('umbInstallerContext', { - data, - getData: () => data.value, - settings: new BehaviorSubject({ - user: { - consentLevels: [{ description: 'This is a consent text', level: 'Basic' }], - minCharLength: 2, - minNonAlphaNumericLength: 2, - }, - databases: [ - { - id: '123', - defaultDatabaseName: 'umbraco', - displayName: 'SQLite', - isConfigured: false, - providerName: 'Umbraco', - requiresConnectionTest: false, - requiresCredentials: false, - requiresServer: false, - serverPlaceholder: 'umbraco', - sortOrder: 0, - supportsIntegratedAuthentication: false, - }, - ], - }), - appendData: () => true, - requestInstall: () => Promise.resolve(), - } as Partial); - } - - render() { - return html``; - } -} +import { UmbInstallerContext } from './installer-context'; export default { title: 'Components/Installer/Steps', component: 'umb-installer', id: 'installer', - decorators: [(story) => html`${story()}`], + decorators: [ + (story) => + html` + ${story()} + `, + ], } as Meta; export const Step1User: Story = () => html``; From effb185911ef8a5242d9a61cdb7e8af13c8fadc4 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 2 Aug 2022 13:53:19 +0200 Subject: [PATCH 11/12] add a step for preconfigured database with mocked response --- .../src/installer/installer.stories.ts | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts index 8893d33acb..6abe87e64f 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts @@ -6,8 +6,10 @@ import './installer-user.element'; import { Meta, Story } from '@storybook/web-components'; import { html } from 'lit-html'; +import { rest } from 'msw'; import { UmbInstallerUser } from '.'; +import { UmbracoInstaller } from '../core/models'; import { UmbInstallerContext } from './installer-context'; export default { @@ -49,5 +51,43 @@ Step3Database.parameters = { }, }; +export const Step3DatabasePreconfigured: Story = () => html``; +Step3DatabasePreconfigured.storyName = 'Step 3: Database (preconfigured)'; +Step3DatabasePreconfigured.parameters = { + actions: { + handles: ['previous', 'next'], + }, + msw: { + handlers: { + global: null, + others: [ + rest.get('/umbraco/backoffice/install/settings', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + user: { consentLevels: [], minCharLength: 2, minNonAlphaNumericLength: 2 }, + databases: [ + { + id: '1', + sortOrder: -1, + displayName: 'SQLite', + defaultDatabaseName: 'Umbraco', + providerName: 'Microsoft.Data.SQLite', + isConfigured: true, + requiresServer: false, + serverPlaceholder: null, + requiresCredentials: false, + supportsIntegratedAuthentication: false, + requiresConnectionTest: false, + }, + ], + }) + ); + }), + ], + }, + }, +}; + export const Step4Installing: Story = () => html``; Step4Installing.storyName = 'Step 4: Installing'; From 0cbdabd202a6132c2e08bd20c411fbe937596a0e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 3 Aug 2022 12:43:41 +0200 Subject: [PATCH 12/12] add installer as a page --- .../src/stories/installer-page.stories.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/stories/installer-page.stories.ts diff --git a/src/Umbraco.Web.UI.Client/src/stories/installer-page.stories.ts b/src/Umbraco.Web.UI.Client/src/stories/installer-page.stories.ts new file mode 100644 index 0000000000..28e68ff25a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/stories/installer-page.stories.ts @@ -0,0 +1,13 @@ +import '../core/context/context-provider.element'; +import '../installer/installer.element'; + +import { Meta } from '@storybook/web-components'; +import { html } from 'lit-html'; + +export default { + title: 'Pages/Installer', + component: 'umb-installer', + id: 'installer-page', +} as Meta; + +export const Installer = () => html``;