Merge branch 'storybook-v7-upgrade' into docs/add-draft-concept-docs
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
const tsconfigPaths = require('vite-tsconfig-paths').default;
|
||||
const { mergeConfig } = require('vite');
|
||||
|
||||
module.exports = {
|
||||
stories: ['../@(src|libs|apps)/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
|
||||
addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-a11y'],
|
||||
framework: '@storybook/web-components',
|
||||
features: {
|
||||
previewMdx2: true,
|
||||
storyStoreV7: true,
|
||||
},
|
||||
core: {
|
||||
builder: '@storybook/builder-vite',
|
||||
},
|
||||
staticDirs: ['../public-assets'],
|
||||
async viteFinal(config, { configType }) {
|
||||
return mergeConfig(config, {
|
||||
// customize the Vite config here
|
||||
plugins: [tsconfigPaths()],
|
||||
});
|
||||
},
|
||||
};
|
||||
21
src/Umbraco.Web.UI.Client/.storybook/main.ts
Normal file
21
src/Umbraco.Web.UI.Client/.storybook/main.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { StorybookConfig } from '@storybook/web-components-vite';
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ['../@(src|libs|apps)/**/*.stories.mdx', '../@(src|libs|apps)/**/*.stories.@(js|jsx|ts|tsx)'],
|
||||
addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-a11y'],
|
||||
framework: {
|
||||
name: '@storybook/web-components-vite',
|
||||
options: {}
|
||||
},
|
||||
features: {
|
||||
storyStoreV7: true
|
||||
},
|
||||
staticDirs: ['../public-assets'],
|
||||
typescript: {
|
||||
check: true,
|
||||
},
|
||||
docs: {
|
||||
autodocs: true
|
||||
}
|
||||
};
|
||||
export default config;
|
||||
84923
src/Umbraco.Web.UI.Client/package-lock.json
generated
84923
src/Umbraco.Web.UI.Client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,126 +1,129 @@
|
||||
{
|
||||
"name": "umbraco-cms-backoffice",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"main": "dist/main.js",
|
||||
"exports": {
|
||||
".": "./dist/main.js"
|
||||
},
|
||||
"types": "types/src/app.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"types"
|
||||
],
|
||||
"repository": {
|
||||
"url": "https://github.com/umbraco/Umbraco.CMS.Backoffice",
|
||||
"type": "git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/umbraco/Umbraco.CMS.Backoffice/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Umbraco A/S",
|
||||
"email": "backoffice@umbraco.com",
|
||||
"url": "https://umbraco.com"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build --mode staging",
|
||||
"build:for:static": "tsc && vite build",
|
||||
"build:for:cms": "tsc && vite build -c vite.cms.config.ts",
|
||||
"build:for:cms:watch": "npm run build:for:cms -- --watch",
|
||||
"preview": "vite preview --open",
|
||||
"test": "web-test-runner --coverage",
|
||||
"test:watch": "web-test-runner --watch",
|
||||
"auth:test:e2e": "npx playwright test --config apps/auth/",
|
||||
"backoffice:test:e2e": "npx playwright test",
|
||||
"test:e2e": "npm run auth:test:e2e && npm run backoffice:test:e2e",
|
||||
"lint": "eslint src apps libs e2e",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
"format": "prettier 'src/**/*.ts'",
|
||||
"format:fix": "npm run format -- --write",
|
||||
"generate:api": "openapi --input https://raw.githubusercontent.com/umbraco/Umbraco-CMS/v13/dev/src/Umbraco.Cms.Api.Management/OpenApi.json --output libs/backend-api/src --postfix Resource --useOptions",
|
||||
"generate:api-dev": "openapi --input http://localhost:11000/umbraco/swagger/v1/swagger.json --output libs/backend-api/src --postfix Resource --useOptions",
|
||||
"storybook": "npm run wc-analyze && start-storybook -p 6006",
|
||||
"storybook:build": "npm run wc-analyze && build-storybook",
|
||||
"build-storybook": "npm run wc-analyze && build-storybook",
|
||||
"generate:icons": "node ./devops/icons/index.js",
|
||||
"wc-analyze": "wca **/*.element.ts --outFile custom-elements.json",
|
||||
"new-extension": "plop --plopfile ./devops/plop/plop.js",
|
||||
"compile": "tsc",
|
||||
"check": "npm run lint && npm run compile && npm run build-storybook"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17",
|
||||
"npm": ">=8.0.0 < 9"
|
||||
},
|
||||
"dependencies": {
|
||||
"@umbraco-ui/uui": "^1.2.0-rc.0",
|
||||
"@umbraco-ui/uui-css": "^1.2.0-rc.0",
|
||||
"@umbraco-ui/uui-modal": "file:umbraco-ui-uui-modal-0.0.0.tgz",
|
||||
"@umbraco-ui/uui-modal-container": "file:umbraco-ui-uui-modal-container-0.0.0.tgz",
|
||||
"@umbraco-ui/uui-modal-dialog": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz",
|
||||
"@umbraco-ui/uui-modal-sidebar": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz",
|
||||
"element-internals-polyfill": "^1.1.19",
|
||||
"lit": "^2.6.1",
|
||||
"lodash-es": "4.17.21",
|
||||
"router-slot": "^1.5.5",
|
||||
"rxjs": "^7.8.0",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@mdx-js/react": "^2.2.1",
|
||||
"@open-wc/testing": "^3.1.7",
|
||||
"@playwright/test": "^1.30.0",
|
||||
"@storybook/addon-a11y": "^6.5.15",
|
||||
"@storybook/addon-actions": "^6.5.14",
|
||||
"@storybook/addon-essentials": "^6.5.15",
|
||||
"@storybook/addon-links": "^6.5.15",
|
||||
"@storybook/builder-vite": "^0.3.0",
|
||||
"@storybook/mdx2-csf": "^0.0.3",
|
||||
"@storybook/web-components": "^6.5.15",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/lodash-es": "^4.17.6",
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||
"@typescript-eslint/parser": "^5.50.0",
|
||||
"@web/dev-server-esbuild": "^0.3.3",
|
||||
"@web/dev-server-import-maps": "^0.0.7",
|
||||
"@web/dev-server-rollup": "^0.3.21",
|
||||
"@web/test-runner": "^0.15.0",
|
||||
"@web/test-runner-playwright": "^0.9.0",
|
||||
"babel-loader": "^9.1.2",
|
||||
"eslint": "^8.32.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.3",
|
||||
"eslint-plugin-import": "^2.27.4",
|
||||
"eslint-plugin-lit": "^1.8.2",
|
||||
"eslint-plugin-lit-a11y": "^2.3.0",
|
||||
"eslint-plugin-local-rules": "^1.3.2",
|
||||
"eslint-plugin-storybook": "^0.6.10",
|
||||
"eslint-plugin-wc": "^1.4.0",
|
||||
"lit-html": "^2.6.1",
|
||||
"msw": "^0.49.2",
|
||||
"msw-storybook-addon": "^1.7.0",
|
||||
"openapi-typescript-codegen": "^0.23.0",
|
||||
"playwright-msw": "^2.1.0",
|
||||
"plop": "^3.1.1",
|
||||
"prettier": "2.8.3",
|
||||
"rollup": "^3.10.0",
|
||||
"rollup-plugin-esbuild": "^5.0.0",
|
||||
"rollup-plugin-url": "^3.0.1",
|
||||
"tiny-glob": "^0.2.9",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^4.0.4",
|
||||
"vite-plugin-static-copy": "^0.13.0",
|
||||
"vite-tsconfig-paths": "^4.0.3",
|
||||
"web-component-analyzer": "^2.0.0-next.4"
|
||||
},
|
||||
"msw": {
|
||||
"workerDirectory": "public"
|
||||
}
|
||||
"name": "umbraco-cms-backoffice",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"main": "dist/main.js",
|
||||
"exports": {
|
||||
".": "./dist/main.js"
|
||||
},
|
||||
"types": "types/src/app.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"types"
|
||||
],
|
||||
"repository": {
|
||||
"url": "https://github.com/umbraco/Umbraco.CMS.Backoffice",
|
||||
"type": "git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/umbraco/Umbraco.CMS.Backoffice/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Umbraco A/S",
|
||||
"email": "backoffice@umbraco.com",
|
||||
"url": "https://umbraco.com"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build --mode staging",
|
||||
"build:for:static": "tsc && vite build",
|
||||
"build:for:cms": "tsc && vite build -c vite.cms.config.ts",
|
||||
"build:for:cms:watch": "npm run build:for:cms -- --watch",
|
||||
"preview": "vite preview --open",
|
||||
"test": "web-test-runner --coverage",
|
||||
"test:watch": "web-test-runner --watch",
|
||||
"auth:test:e2e": "npx playwright test --config apps/auth/",
|
||||
"backoffice:test:e2e": "npx playwright test",
|
||||
"test:e2e": "npm run auth:test:e2e && npm run backoffice:test:e2e",
|
||||
"lint": "eslint src apps libs e2e",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
"format": "prettier 'src/**/*.ts'",
|
||||
"format:fix": "npm run format -- --write",
|
||||
"generate:api": "openapi --input https://raw.githubusercontent.com/umbraco/Umbraco-CMS/v13/dev/src/Umbraco.Cms.Api.Management/OpenApi.json --output libs/backend-api/src --postfix Resource --useOptions",
|
||||
"generate:api-dev": "openapi --input http://localhost:11000/umbraco/swagger/v1/swagger.json --output libs/backend-api/src --postfix Resource --useOptions",
|
||||
"storybook": "npm run wc-analyze && storybook dev -p 6006",
|
||||
"storybook:build": "npm run wc-analyze && storybook build",
|
||||
"build-storybook": "npm run wc-analyze && storybook build",
|
||||
"generate:icons": "node ./devops/icons/index.js",
|
||||
"wc-analyze": "wca **/*.element.ts --outFile custom-elements.json",
|
||||
"new-extension": "plop --plopfile ./devops/plop/plop.js",
|
||||
"compile": "tsc",
|
||||
"check": "npm run lint && npm run compile && npm run build-storybook"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17",
|
||||
"npm": ">=8.0.0 < 9"
|
||||
},
|
||||
"dependencies": {
|
||||
"@umbraco-ui/uui": "^1.2.0-rc.0",
|
||||
"@umbraco-ui/uui-css": "^1.2.0-rc.0",
|
||||
"@umbraco-ui/uui-modal": "file:umbraco-ui-uui-modal-0.0.0.tgz",
|
||||
"@umbraco-ui/uui-modal-container": "file:umbraco-ui-uui-modal-container-0.0.0.tgz",
|
||||
"@umbraco-ui/uui-modal-dialog": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz",
|
||||
"@umbraco-ui/uui-modal-sidebar": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz",
|
||||
"element-internals-polyfill": "^1.1.19",
|
||||
"lit": "^2.6.1",
|
||||
"lodash-es": "4.17.21",
|
||||
"router-slot": "^1.5.5",
|
||||
"rxjs": "^7.8.0",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@mdx-js/react": "^2.2.1",
|
||||
"@open-wc/testing": "^3.1.7",
|
||||
"@playwright/test": "^1.30.0",
|
||||
"@storybook/addon-a11y": "^7.0.0-beta.53",
|
||||
"@storybook/addon-actions": "^7.0.0-beta.53",
|
||||
"@storybook/addon-essentials": "^7.0.0-beta.53",
|
||||
"@storybook/addon-links": "^7.0.0-beta.53",
|
||||
"@storybook/mdx2-csf": "^1.0.0-next.5",
|
||||
"@storybook/web-components": "^7.0.0-beta.53",
|
||||
"@storybook/web-components-vite": "^7.0.0-beta.53",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/lodash-es": "^4.17.6",
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||
"@typescript-eslint/parser": "^5.50.0",
|
||||
"@web/dev-server-esbuild": "^0.3.3",
|
||||
"@web/dev-server-import-maps": "^0.0.7",
|
||||
"@web/dev-server-rollup": "^0.3.21",
|
||||
"@web/test-runner": "^0.15.0",
|
||||
"@web/test-runner-playwright": "^0.9.0",
|
||||
"babel-loader": "^9.1.2",
|
||||
"eslint": "^8.32.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.3",
|
||||
"eslint-plugin-import": "^2.27.4",
|
||||
"eslint-plugin-lit": "^1.8.2",
|
||||
"eslint-plugin-lit-a11y": "^2.3.0",
|
||||
"eslint-plugin-local-rules": "^1.3.2",
|
||||
"eslint-plugin-storybook": "^0.6.11",
|
||||
"eslint-plugin-wc": "^1.4.0",
|
||||
"lit-html": "^2.6.1",
|
||||
"msw": "^0.49.2",
|
||||
"msw-storybook-addon": "^1.7.0",
|
||||
"openapi-typescript-codegen": "^0.23.0",
|
||||
"playwright-msw": "^2.1.0",
|
||||
"plop": "^3.1.1",
|
||||
"prettier": "2.8.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"rollup": "^3.10.0",
|
||||
"rollup-plugin-esbuild": "^5.0.0",
|
||||
"rollup-plugin-url": "^3.0.1",
|
||||
"storybook": "^7.0.0-beta.53",
|
||||
"tiny-glob": "^0.2.9",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^4.0.4",
|
||||
"vite-plugin-static-copy": "^0.13.0",
|
||||
"vite-tsconfig-paths": "^4.0.3",
|
||||
"web-component-analyzer": "^2.0.0-next.4"
|
||||
},
|
||||
"msw": {
|
||||
"workerDirectory": "public"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import type { UmbDashboardMembersWelcomeElement } from './dashboard-members-welc
|
||||
|
||||
export default {
|
||||
title: 'Dashboards/Welcome',
|
||||
component: 'umb-dashboard-welcome',
|
||||
id: 'umb-dashboard-welcome',
|
||||
component: 'dashboard-members-welcome',
|
||||
id: 'umb-dashboard-members-welcome',
|
||||
} as Meta;
|
||||
|
||||
export const AAAOverview: Story<UmbDashboardMembersWelcomeElement> = () =>
|
||||
|
||||
@@ -10,8 +10,8 @@ import type { UmbWorkspaceViewMemberGroupInfoElement } from './workspace-view-me
|
||||
|
||||
export default {
|
||||
title: 'Workspaces/Data Type/Views/Info',
|
||||
component: 'umb-workspace-view-data-type-info',
|
||||
id: 'umb-workspace-view-data-type-info',
|
||||
component: 'umb-workspace-view-member-group-info',
|
||||
id: 'umb-workspace-view-member-group-info',
|
||||
decorators: [
|
||||
(story) => {
|
||||
return html`TODO: make use of mocked workspace context??`;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Meta } from '@storybook/addon-docs';
|
||||
import { Meta } from '@storybook/blocks';
|
||||
|
||||
<Meta title="Guides/Context API" parameters={{ previewTabs: { canvas: { hidden: true } } }} />
|
||||
<Meta title="Guides/Context API" />
|
||||
|
||||
# Context API
|
||||
|
||||
@@ -9,36 +9,14 @@ This element can be used as the base of any Element.
|
||||
Do this if you need to Observe Data, Consume or Provide a Context API or use a Resource.
|
||||
The Element implements the Controller Host and provides a few shortcut methods for initializing some Controllers.
|
||||
|
||||
The methods are (*note this can be out of date, we need to look into how we can ensure this Doc originates from code.*)
|
||||
The methods are *note this can be out of date, we need to look into how we can ensure this Doc originates from code.*
|
||||
|
||||
### Consume a Context API.
|
||||
|
||||
From a Umbraco Element:
|
||||
````
|
||||
```typescript
|
||||
this.consumeContext('requestThisContextAlias', (context) => {
|
||||
// Notice this is a subscription, as context might change or a new one appears.
|
||||
console.log("I've got the context", context);
|
||||
});
|
||||
````
|
||||
|
||||
Or with a Controller using a Controller Host(Umbraco Element):
|
||||
|
||||
````
|
||||
new UmbContextConsumerController(hostElement, 'requestThisContextAlias', (context) => {
|
||||
// Notice this is a subscription, as context might change or a new one appears.
|
||||
console.log("I've got the context", context);
|
||||
});
|
||||
````
|
||||
|
||||
### Provide a Context API.
|
||||
|
||||
From a Umbraco Element:
|
||||
````
|
||||
this.provideContext('myContextAlias', new MyContextApi());
|
||||
````
|
||||
|
||||
Or with a Controller using a Controller Host(Umbraco Element):
|
||||
|
||||
````
|
||||
new UmbContextProviderController(hostElement, 'myContextAlias', new MyContextApi());
|
||||
````
|
||||
```
|
||||
@@ -1,31 +1,13 @@
|
||||
import { Meta } from '@storybook/addon-docs';
|
||||
import { Meta } from '@storybook/blocks';
|
||||
|
||||
<Meta title="Guides/Getting started" parameters={{ previewTabs: { canvas: { hidden: true } } }} />
|
||||
<Meta title="Guides/Getting Started" />
|
||||
|
||||
# Getting started
|
||||
|
||||
This section contains a set of guide which will ease the learning of the Umbraco CMS (Backoffice).
|
||||
In this document you will get a overview of the articles — Enabling you to get started with the parts that makes sense for you.
|
||||
|
||||
# Terminology
|
||||
There is a few words that covers certain concepts, which is good to learn to easilier decode the purpose of code.
|
||||
|
||||
- **Resource** A API enabling communication with a server. [Go to Resource Guide](/?path=/story/guides-resource--page)
|
||||
- **Store** A API representing data, generally coming from the server. Most stores would talk with one or more resources. [Go to Store Guide](/?path=/story/guides-store--page)
|
||||
|
||||
- **State** A reactive container holding data, when data is changed all its Observables will be notified.
|
||||
- **Observable** An observable is the hook for others to subscribe to the data or part of the data of a State.
|
||||
- **Observe** Observe is the term of what we do when subscriping to a Observable, We observe and observable.
|
||||
|
||||
- **Context-API** The name of the system used to serve APIs(instances/classes) that for a certain context in the DOM. An API that is served via the Context-API is called a Context [Go to Context API Guide](/?path=/story/guides-umbraco-element--page)
|
||||
- **Context Provider** One that provides a class instance as a Context API.
|
||||
- **Context Consumer** One that consumer/subscripes to a class instance as a Context API.
|
||||
|
||||
- **Controller** An abstract term for a things that hooks into the lifecycle of a element. Many things in our system is Controllers, As a example notice these controllers:
|
||||
- **Context Provider Controller** A Context Provider as a Controller, this make its easy to implement a Context Provider.
|
||||
- **Context Consumer Controller** A Context Consumer as a Controller, this make its easy to implement a Context Consumer.
|
||||
- **Observer Controller** A Controller for handling the observe subscription for a Observable.
|
||||
|
||||
- **Controller Host** The element that can host one or more controllers.
|
||||
- **Umbraco Element** The UmbLitElement or UmbElemenMixin is a implementation of the Controller Host as an element. Using this as your base element provides a few methods that makes life easier. [Go to Umbraco Element Guide](/?path=/story/guides-umbraco-element--page)
|
||||
|
||||
[Go to Resource Guide](/?path=/story/guides-resource--page)
|
||||
@@ -4,15 +4,13 @@ import { Meta } from '@storybook/addon-docs';
|
||||
|
||||
# Store
|
||||
|
||||
|
||||
A store is the link between a Resource and a data implementation. A store is mainly taken form as a Context, In other words we will have to Consume the Context(Store) to get the Store.
|
||||
Generally a Store will be holding one or more RxJS Subjects, each Subject is made available for Subscription via a RxJS Observable.
|
||||
|
||||
### A Simple Store:
|
||||
|
||||
````
|
||||
```typescript
|
||||
class MyProductStore {
|
||||
|
||||
#products = new ArrayState(<Array<MyProductType>>[], (product) => product.key);
|
||||
|
||||
public readonly products = this.#products.asObservable();
|
||||
@@ -24,18 +22,16 @@ class MyProductStore {
|
||||
// The Store provides it self as a Context-API.
|
||||
new UmbContextProviderController(_host, 'MyStoreContextAlias', this);
|
||||
}
|
||||
|
||||
}
|
||||
````
|
||||
```
|
||||
|
||||
In this example we created a ArrayState, A State which is specific to Arrays.
|
||||
This holds the data for one or more Observables to convey for outsiders.
|
||||
|
||||
This example shows how to use the store:
|
||||
|
||||
````
|
||||
```typescript
|
||||
class MyImplementation extends UmbLitElement {
|
||||
|
||||
private _myProductStore?: MyProductStore;
|
||||
|
||||
constructor() {
|
||||
@@ -49,27 +45,22 @@ class MyImplementation extends UmbLitElement {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private _observeAllProducts() {
|
||||
if (!this._myProductStore) return;
|
||||
|
||||
// Notice this callback will be triggered initially and each time the products change:
|
||||
this.observe(this._myProductStore.products, (products) => {
|
||||
console.log("The data of all products is:", products);
|
||||
console.log('The data of all products is:', products);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
````
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
### A bit more meaningful Store:
|
||||
|
||||
Here we added a method that returns an Observable that is specific to the requested product.
|
||||
|
||||
````
|
||||
```typescript
|
||||
class MyProductStore {
|
||||
|
||||
...
|
||||
@@ -89,14 +80,12 @@ class MyProductStore {
|
||||
);
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
```
|
||||
|
||||
An example using this method:
|
||||
|
||||
````
|
||||
```typescript
|
||||
class MyImplementation extends UmbLitElement {
|
||||
|
||||
private _myProductStore?: MyProductStore;
|
||||
|
||||
constructor() {
|
||||
@@ -115,14 +104,11 @@ class MyImplementation extends UmbLitElement {
|
||||
|
||||
// Notice this callback will be triggered initially and each time the specific product change:
|
||||
this.observe(this._myProductStore.getByKey('1234'), (product) => {
|
||||
console.log("The data of product `1234`` is:", product);
|
||||
console.log('The data of product `1234`` is:', product);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
````
|
||||
|
||||
|
||||
```
|
||||
|
||||
### Create many Observables:
|
||||
|
||||
@@ -130,37 +116,29 @@ A Store must hold different Observables some very general and others specific. A
|
||||
|
||||
This example give some inspiration to how fine grained this can become:
|
||||
|
||||
````
|
||||
```typescript
|
||||
class MyProductStore {
|
||||
#products = new ArrayState(<Array<MyProductType>>[]);
|
||||
|
||||
#products = new ArrayState(<Array<MyProductType>>[]);
|
||||
|
||||
public readonly products = this.#products.asObservable();
|
||||
public readonly amountOfProducts = this.#products.getObservablePart((products) => products.length);
|
||||
public readonly topTenRatedProducts = this.#products.getObservablePart((products) => products.sort((a, b) => b.rating - a.rating).slice(0, 10));
|
||||
|
||||
...
|
||||
public readonly products = this.#products.asObservable();
|
||||
public readonly amountOfProducts = this.#products.getObservablePart((products) => products.length);
|
||||
public readonly topTenRatedProducts = this.#products.getObservablePart((products) => products.sort((a, b) => b.rating - a.rating).slice(0, 10));
|
||||
|
||||
...
|
||||
}
|
||||
````
|
||||
```
|
||||
|
||||
An observer of an Observable will only be triggered if the specific part of that data has changed.
|
||||
With this we can make a high performant application, only triggering the parts that needs to update when data is changed.
|
||||
|
||||
|
||||
|
||||
|
||||
### Ensure unique data:
|
||||
|
||||
For incoming data to replace existing data, we need to clarify what makes a entry of the array unique.
|
||||
In the examples of this guide each product has a key, and we have clarified this to the State by giving it the little method `(product) => product.key` as part of the its creation:
|
||||
|
||||
````
|
||||
```typescript
|
||||
class MyProductStore {
|
||||
|
||||
#products = new ArrayState(<Array<MyProductType>>[], (product) => product.key);
|
||||
|
||||
...
|
||||
|
||||
#products = new ArrayState(<Array<MyProductType>>[], (product) => product.key);
|
||||
...
|
||||
}
|
||||
````
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user