Skip to content

Commit

Permalink
feat(abc:onboarding): add key (#1652)
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk authored Oct 17, 2023
1 parent 6b3c711 commit 5edaa97
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 19 deletions.
49 changes: 38 additions & 11 deletions packages/abc/onboarding/demo/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ Simplest of usage.

```ts
import { Component } from '@angular/core';
import { OnboardingService } from '@delon/abc/onboarding';

import { OnboardingConfig, OnboardingService } from '@delon/abc/onboarding';
import { _HttpClient } from '@delon/theme';
import { NzMessageService } from 'ng-zorro-antd/message';

Expand All @@ -28,27 +29,49 @@ import { NzMessageService } from 'ng-zorro-antd/message';
<button class="test1-3" nz-button nzType="dashed">Third Button</button>
</div>
<button nz-button (click)="start()">Start</button>
<button nz-button (click)="startOnce()">Start Once (Set 'key')</button>
<button nz-button (click)="viaHttp()">Start Via Http</button>
<a href="https://github.com/ng-alain/delon/blob/master/src/assets/schema/onboarding.json" target="_blank" class="ml-md">
<a
href="https://github.com/ng-alain/delon/blob/master/src/assets/schema/onboarding.json"
target="_blank"
class="ml-md"
>
onboarding.json
</a>
`,
`
})
export class DemoComponent {
constructor(private srv: OnboardingService, private msg: NzMessageService, private http: _HttpClient) {}
private def: OnboardingConfig = {
items: [
{
selectors: '.test1-1',
content: 'The user guidance is to help users better understand and use the product',
width: 300
},
{
selectors: '.test1-2',
title: 'Test2',
content: 'The user guidance is to help users better understand and use the product'
},
{
selectors: '.test1-3',
title: 'Test3',
content: 'The user guidance is to help users better understand and use the product'
}
]
};
constructor(
private srv: OnboardingService,
private msg: NzMessageService,
private http: _HttpClient
) {}

handleClick(): void {
this.msg.info(`click`);
}

start(): void {
this.srv.start({
items: [
{ selectors: '.test1-1', content: 'The user guidance is to help users better understand and use the product', width: 300 },
{ selectors: '.test1-2', title: 'Test2', content: 'The user guidance is to help users better understand and use the product' },
{ selectors: '.test1-3', title: 'Test3', content: 'The user guidance is to help users better understand and use the product' },
],
});
this.srv.start({ ...this.def });
}

viaHttp(): void {
Expand All @@ -57,5 +80,9 @@ export class DemoComponent {
this.srv.start(res);
});
}

startOnce(): void {
this.srv.start({ ...this.def, key: 'obs-once' });
}
}
```
2 changes: 2 additions & 0 deletions packages/abc/onboarding/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ The components only support the use of `OnboardingService` service to build.

| Property | Description | Type | Default |
|----------|-------------|------|---------|
| `[key]` | Storage identification Key, The default is `localStorage` local storage, allowing the use of `ONBOARDING_STORE_TOKEN` to change the storage method | `string` | - |
| `[keyVersion]` | Current version | `unknown` | - |
| `[items]` | Onboarding items | `OnboardingItem[]` | `[]` |
| `[mask]` | Whether to show mask or not | `boolean` | `true` |
| `[maskClosable]` | Clicking on the mask (area outside the onboarding) to close the onboarding or not | `boolean` | `true` |
Expand Down
2 changes: 2 additions & 0 deletions packages/abc/onboarding/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ module: import { OnboardingModule } from '@delon/abc/onboarding';

| 成员 | 说明 | 类型 | 默认值 |
|----|----|----|-----|
| `[key]` | 存储标识Key;默认 `localStorage` 本地存储,允许使用 `ONBOARDING_STORE_TOKEN` 变更存储方式 | `string` | - |
| `[keyVersion]` | 当前版本 | `unknown` | - |
| `[items]` | 引导项列表 | `OnboardingItem[]` | `[]` |
| `[mask]` | 是否展示遮罩 | `boolean` | `true` |
| `[maskClosable]` | 点击蒙层是否允许关闭 | `boolean` | `true` |
Expand Down
28 changes: 20 additions & 8 deletions packages/abc/onboarding/onboarding.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ import { AlainConfigService } from '@delon/util/config';
import type { NzSafeAny } from 'ng-zorro-antd/core/types';

import { OnboardingComponent } from './onboarding.component';
import { ONBOARDING_STORE_TOKEN, OnBoardingKeyStore } from './onboarding.storage';
import { OnboardingConfig, OnboardingItem, OnboardingOpType } from './onboarding.types';

@Injectable()
export class OnboardingService implements OnDestroy {
private compRef!: ComponentRef<OnboardingComponent>;
private op$!: Subscription;
private config!: OnboardingConfig;
private config?: OnboardingConfig;
private active = 0;
private running$: Subscription | null = null;
private _running = false;
Expand All @@ -49,6 +50,7 @@ export class OnboardingService implements OnDestroy {
private router: Router,
@Inject(DOCUMENT) private doc: NzSafeAny,
private configSrv: AlainConfigService,
@Inject(ONBOARDING_STORE_TOKEN) private keyStoreSrv: OnBoardingKeyStore,
@Optional() private directionality: Directionality
) {}

Expand Down Expand Up @@ -96,6 +98,10 @@ export class OnboardingService implements OnDestroy {
}

private destroy(): void {
const storeKey = this.config?.key;
if (storeKey != null) {
this.keyStoreSrv.set(storeKey, this.config?.keyVersion);
}
this.cancelRunning();
if (this.compRef) {
this.appRef.detachView(this.compRef.hostView);
Expand All @@ -105,7 +111,7 @@ export class OnboardingService implements OnDestroy {
}

private showItem(isStart: boolean = false): void {
const items = this.config.items!;
const items = this.config?.items!;
const item = {
position: 'bottomLeft',
before: of(true),
Expand Down Expand Up @@ -142,17 +148,23 @@ export class OnboardingService implements OnDestroy {
* 开启新的用户引导流程
*/
start(config: OnboardingConfig): void {
if (this.running) {
return;
}
this.destroy();
this.config = {
const cog: OnboardingConfig = {
keyVersion: '',
items: [],
mask: true,
maskClosable: true,
showTotal: false,
...config
};
const storeKey = cog?.key;
if (storeKey != null && this.keyStoreSrv.get(storeKey) === cog.keyVersion) {
return;
}
if (this.running) {
return;
}
this.destroy();
this.config = cog;
this.active = 0;
this.type = null;
this.attach();
Expand All @@ -165,7 +177,7 @@ export class OnboardingService implements OnDestroy {
* 下一步
*/
next(): void {
if (this._running || this.active + 1 >= this.config.items!.length) {
if (this._running || this.active + 1 >= this.config!.items!.length) {
this.done();
return;
}
Expand Down
15 changes: 15 additions & 0 deletions packages/abc/onboarding/onboarding.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { NzSafeAny } from 'ng-zorro-antd/core/types';

import { OnboardingModule } from './onboarding.module';
import { OnboardingService } from './onboarding.service';
import { ONBOARDING_STORE_TOKEN } from './onboarding.storage';
import { OnboardingConfig, OnboardingOpType } from './onboarding.types';

describe('abc: onboarding', () => {
Expand Down Expand Up @@ -42,6 +43,20 @@ describe('abc: onboarding', () => {
page.start().checkActive().click('next').checkDone(false).click('done').checkDone();
}));

it('#key', fakeAsync(() => {
const storeSrv = TestBed.inject(ONBOARDING_STORE_TOKEN);
let storeKeyVersion: unknown = '';
spyOn(storeSrv, 'get').and.callFake(() => {
return storeKeyVersion;
});
spyOn(storeSrv, 'set').and.callFake((_, value) => {
storeKeyVersion = value;
});
page.start({ key: 'a', keyVersion: '1' }).checkActive().click('next').checkDone(false).click('done').checkDone();
page.start({ key: 'a', keyVersion: '1' });
expect(page.el == null);
}));

it('#skip', fakeAsync(() => {
page.start().checkActive().click('skip').checkDone();
}));
Expand Down
26 changes: 26 additions & 0 deletions packages/abc/onboarding/onboarding.storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { InjectionToken } from '@angular/core';

export interface OnBoardingKeyStore {
get(key: string): unknown;

set(key: string, version: unknown): void;
}

export const ONBOARDING_STORE_TOKEN = new InjectionToken<OnBoardingKeyStore>('ONBOARDING_STORE_TOKEN', {
providedIn: 'root',
factory: ONBOARDING_STORE_TOKEN_FACTORY
});

export function ONBOARDING_STORE_TOKEN_FACTORY(): OnBoardingKeyStore {
return new LocalStorageStore();
}

export class LocalStorageStore implements OnBoardingKeyStore {
get(key: string): unknown {
return localStorage.getItem(key);
}

set(key: string, version: unknown): void {
localStorage.setItem(key, `${version}`);
}
}
8 changes: 8 additions & 0 deletions packages/abc/onboarding/onboarding.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ import type { NzSafeAny } from 'ng-zorro-antd/core/types';
export type OnboardingOpType = 'next' | 'prev' | 'skip' | 'done';

export interface OnboardingConfig {
/**
* Storage identification Key, The default is `localStorage` local storage, allowing the use of `ONBOARDING_STORE_TOKEN` to change the storage method
*/
key?: string;
/**
* Current version
*/
keyVersion?: unknown;
/**
* Onboarding items
*/
Expand Down
1 change: 1 addition & 0 deletions packages/abc/onboarding/public_api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './onboarding.service';
export * from './onboarding.types';
export * from './onboarding.component';
export * from './onboarding.storage';

export * from './onboarding.module';

0 comments on commit 5edaa97

Please sign in to comment.