Skip to content

Commit

Permalink
chore: add reuse-tab
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk committed Jan 18, 2024
1 parent 3bd6d1e commit 06cb9d2
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 90 deletions.
10 changes: 8 additions & 2 deletions packages/abc/reuse-tab/provide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import { RouteReuseStrategy } from '@angular/router';
import { REUSE_TAB_CACHED_MANAGER, ReuseTabCachedManagerFactory } from './reuse-tab.cache';
import { ReuseTabMatchMode, ReuseTabRouteParamMatchMode } from './reuse-tab.interfaces';
import { ReuseTabService } from './reuse-tab.service';
import { REUSE_TAB_STORAGE_KEY, REUSE_TAB_STORAGE_STATE, ReuseTabLocalStorageState } from './reuse-tab.state';
import {
REUSE_TAB_STORAGE_KEY,
REUSE_TAB_STORAGE_KEY_DEFAULT,
REUSE_TAB_STORAGE_STATE,
ReuseTabLocalStorageState
} from './reuse-tab.state';
import { ReuseTabStrategy } from './reuse-tab.strategy';

export enum ReuseTabFeatureKind {
Expand Down Expand Up @@ -47,9 +52,10 @@ export function provideReuseTabConfig(options?: {
store?: ReuseTabFeature<ReuseTabFeatureKind.Store>;
}): EnvironmentProviders {
const providers: Provider[] = [
ReuseTabService,
{
provide: REUSE_TAB_STORAGE_KEY,
useValue: options?.storeKey ?? '_reuse-tab-state'
useValue: options?.storeKey ?? REUSE_TAB_STORAGE_KEY_DEFAULT
},
(options?.cacheManager ?? withCacheManager()).ɵproviders,
(options?.store ?? withLocalStorage()).ɵproviders,
Expand Down
5 changes: 4 additions & 1 deletion packages/abc/reuse-tab/reuse-tab.cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { ReuseTabCached, ReuseTitle } from './reuse-tab.interfaces';
/**
* Storage manager that can change rules by implementing `get`, `set` accessors
*/
export const REUSE_TAB_CACHED_MANAGER = new InjectionToken<ReuseTabCachedManager>('REUSE_TAB_CACHED_MANAGER');
export const REUSE_TAB_CACHED_MANAGER = new InjectionToken<ReuseTabCachedManager>('REUSE_TAB_CACHED_MANAGER', {
providedIn: 'root',
factory: () => new ReuseTabCachedManagerFactory()

Check warning on line 10 in packages/abc/reuse-tab/reuse-tab.cache.ts

View check run for this annotation

Codecov / codecov/patch

packages/abc/reuse-tab/reuse-tab.cache.ts#L10

Added line #L10 was not covered by tests
});

export interface ReuseTabCachedManager {
list: ReuseTabCached[];
Expand Down
2 changes: 1 addition & 1 deletion packages/abc/reuse-tab/reuse-tab.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
} from './reuse-tab.interfaces';
import { REUSE_TAB_STORAGE_KEY, REUSE_TAB_STORAGE_STATE } from './reuse-tab.state';

@Injectable({ providedIn: 'root' })
@Injectable()
export class ReuseTabService implements OnDestroy {
private readonly injector = inject(Injector);
private readonly menuService = inject(MenuService);
Expand Down
13 changes: 10 additions & 3 deletions packages/abc/reuse-tab/reuse-tab.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ import { InjectionToken } from '@angular/core';

import type { ReuseItem } from './reuse-tab.interfaces';

export const REUSE_TAB_STORAGE_KEY = new InjectionToken<string>('REUSE_TAB_STORAGE_KEY');

export const REUSE_TAB_STORAGE_STATE = new InjectionToken<ReuseTabStorageState>('REUSE_TAB_STORAGE_STATE');
export const REUSE_TAB_STORAGE_KEY_DEFAULT = '_reuse-tab-state';
export const REUSE_TAB_STORAGE_KEY = new InjectionToken<string>('REUSE_TAB_STORAGE_KEY', {
providedIn: 'root',
factory: () => REUSE_TAB_STORAGE_KEY_DEFAULT

Check warning on line 8 in packages/abc/reuse-tab/reuse-tab.state.ts

View check run for this annotation

Codecov / codecov/patch

packages/abc/reuse-tab/reuse-tab.state.ts#L8

Added line #L8 was not covered by tests
});

export const REUSE_TAB_STORAGE_STATE = new InjectionToken<ReuseTabStorageState>('REUSE_TAB_STORAGE_STATE', {
providedIn: 'root',
factory: () => new ReuseTabLocalStorageState()

Check warning on line 13 in packages/abc/reuse-tab/reuse-tab.state.ts

View check run for this annotation

Codecov / codecov/patch

packages/abc/reuse-tab/reuse-tab.state.ts#L13

Added line #L13 was not covered by tests
});

export interface ReuseTabStorageState {
get(key: string): ReuseItem[];
Expand Down
46 changes: 16 additions & 30 deletions packages/abc/se/se-container.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ import {
ChangeDetectionStrategy,
Component,
ElementRef,
Host,
Input,
OnInit,
Optional,
Renderer2,
TemplateRef,
ViewEncapsulation
ViewEncapsulation,
booleanAttribute,
inject
} from '@angular/core';
import { BehaviorSubject, Observable, filter } from 'rxjs';

import type { REP_TYPE } from '@delon/theme';
import { AlainConfigService } from '@delon/util/config';
import { BooleanInput, InputBoolean, InputNumber, NumberInput, toNumber } from '@delon/util/decorator';
import { toNumber } from '@delon/util/decorator';
import { NzStringTemplateOutletDirective } from 'ng-zorro-antd/core/outlet';
import type { NzSafeAny } from 'ng-zorro-antd/core/types';

Expand All @@ -33,23 +33,18 @@ import { SEErrorRefresh, SELayout } from './se.types';
standalone: true
})
export class SETitleComponent implements OnInit {
private el: HTMLElement;
constructor(
@Host()
@Optional()
private parent: SEContainerComponent,
el: ElementRef,
private ren: Renderer2
) {
private readonly parent = inject(SEContainerComponent, { host: true, optional: true });
private readonly el: HTMLElement = inject(ElementRef).nativeElement;
private readonly ren = inject(Renderer2);
constructor() {
if (parent == null) {
throw new Error(`[se-title] must include 'se-container' component`);
}
this.el = el.nativeElement;
}

private setClass(): void {
const { el } = this;
const gutter = this.parent.gutter as number;
const gutter = this.parent!.gutter as number;
this.ren.setStyle(el, 'padding-left', `${gutter / 2}px`);
this.ren.setStyle(el, 'padding-right', `${gutter / 2}px`);
}
Expand Down Expand Up @@ -87,20 +82,11 @@ export class SETitleComponent implements OnInit {
imports: [SETitleComponent, NzStringTemplateOutletDirective]
})
export class SEContainerComponent {
static ngAcceptInputType_gutter: NumberInput;
static ngAcceptInputType_col: NumberInput;
static ngAcceptInputType_colInCon: NumberInput;
static ngAcceptInputType_labelWidth: NumberInput;
static ngAcceptInputType_firstVisual: BooleanInput;
static ngAcceptInputType_ingoreDirty: BooleanInput;
static ngAcceptInputType_line: BooleanInput;
static ngAcceptInputType_noColon: BooleanInput;

private errorNotify$ = new BehaviorSubject<SEErrorRefresh>(null as NzSafeAny);
@Input('se-container') @InputNumber(null) colInCon?: REP_TYPE;
@Input() @InputNumber(null) col!: REP_TYPE;
@Input() @InputNumber(null) labelWidth!: number;
@Input() @InputBoolean() noColon = false;
@Input({ alias: 'se-container', transform: (v: NzSafeAny) => toNumber(v, null) }) colInCon?: REP_TYPE;
@Input({ transform: (v: NzSafeAny) => toNumber(v, null) }) col!: REP_TYPE;
@Input({ transform: (v: NzSafeAny) => toNumber(v, null) }) labelWidth!: number;
@Input({ transform: booleanAttribute }) noColon = false;
@Input() title?: string | TemplateRef<void> | null;

@Input()
Expand All @@ -125,9 +111,9 @@ export class SEContainerComponent {
private _nzLayout!: SELayout;

@Input() size!: 'default' | 'compact';
@Input() @InputBoolean() firstVisual!: boolean;
@Input() @InputBoolean() ingoreDirty!: boolean;
@Input() @InputBoolean() line = false;
@Input({ transform: booleanAttribute }) firstVisual!: boolean;
@Input({ transform: booleanAttribute }) ingoreDirty!: boolean;
@Input({ transform: booleanAttribute }) line = false;
@Input()
set errors(val: SEErrorRefresh[]) {
this.setErrors(val);
Expand Down
50 changes: 20 additions & 30 deletions packages/abc/se/se.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import {
ContentChild,
DestroyRef,
ElementRef,
Host,
Input,
OnChanges,
Optional,
Renderer2,
TemplateRef,
ViewChild,
ViewEncapsulation,
booleanAttribute,
inject
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
Expand All @@ -25,7 +24,7 @@ import { filter } from 'rxjs';

import { ResponsiveService } from '@delon/theme';
import { isEmpty } from '@delon/util/browser';
import { BooleanInput, InputBoolean, InputNumber, NumberInput } from '@delon/util/decorator';
import { toBoolean, toNumber } from '@delon/util/decorator';
import { helpMotion } from 'ng-zorro-antd/core/animation';
import { NzFormStatusService } from 'ng-zorro-antd/core/form';
import { NzStringTemplateOutletDirective } from 'ng-zorro-antd/core/outlet';
Expand Down Expand Up @@ -59,15 +58,14 @@ let nextUniqueId = 0;
imports: [NgClass, NzStringTemplateOutletDirective, NzTooltipDirective, NzIconDirective, CdkObserveContent]
})
export class SEComponent implements OnChanges, AfterContentInit, AfterViewInit {
static ngAcceptInputType_col: NumberInput;
static ngAcceptInputType_required: BooleanInput;
static ngAcceptInputType_line: BooleanInput;
static ngAcceptInputType_labelWidth: NumberInput;
static ngAcceptInputType_noColon: BooleanInput;
static ngAcceptInputType_hideLabel: BooleanInput;

private el: HTMLElement;
private destroy$ = inject(DestroyRef);
private readonly parent = inject(SEContainerComponent, { host: true, optional: true })!;
private readonly el: HTMLElement = inject(ElementRef).nativeElement;
private readonly rep = inject(ResponsiveService);
private readonly ren = inject(Renderer2);
private readonly cdr = inject(ChangeDetectorRef);
private readonly statusSrv = inject(NzFormStatusService);
private readonly destroy$ = inject(DestroyRef);

@ContentChild(NgModel, { static: true }) private readonly ngModel?: NgModel;
@ContentChild(FormControlName, { static: true })
private readonly formControlName?: FormControlName;
Expand All @@ -93,13 +91,13 @@ export class SEComponent implements OnChanges, AfterContentInit, AfterViewInit {
}
@Input() extra?: string | TemplateRef<void> | null;
@Input() label?: string | TemplateRef<void> | null;
@Input() @InputNumber(null) col?: number | null;
@Input() @InputBoolean() required = false;
@Input({ transform: (v: NzSafeAny) => toNumber(v, null) }) col?: number | null;
@Input({ transform: booleanAttribute }) required = false;
@Input() controlClass?: string | null = '';
@Input() @InputBoolean(null) line?: boolean | null;
@Input() @InputNumber(null) labelWidth?: number | null;
@Input() @InputBoolean(null) noColon?: boolean | null;
@Input() @InputBoolean() hideLabel = false;
@Input({ transform: (v: NzSafeAny) => toBoolean(v, null) }) line?: boolean | null;
@Input({ transform: (v: NzSafeAny) => toNumber(v, null) }) labelWidth?: number | null;
@Input({ transform: (v: NzSafeAny) => toBoolean(v, null) }) noColon?: boolean | null;
@Input({ transform: booleanAttribute }) hideLabel = false;

@Input()
set id(value: string) {
Expand Down Expand Up @@ -128,21 +126,13 @@ export class SEComponent implements OnChanges, AfterContentInit, AfterViewInit {
return this.ngModel || this.formControlName;
}

constructor(
el: ElementRef,
@Optional() @Host() private parent: SEContainerComponent,
private statusSrv: NzFormStatusService,
private rep: ResponsiveService,
private ren: Renderer2,
private cdr: ChangeDetectorRef
) {
if (parent == null) {
constructor() {
if (this.parent == null) {
throw new Error(`[se] must include 'se-container' component`);
}
this.el = el.nativeElement;
parent.errorNotify
this.parent.errorNotify
.pipe(
takeUntilDestroyed(this.destroy$),
takeUntilDestroyed(),
filter(w => this.inited && this.ngControl != null && this.ngControl.name === w.name)
)
.subscribe(item => {
Expand Down
15 changes: 6 additions & 9 deletions packages/abc/sg/sg-container.component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation } from '@angular/core';
import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation, numberAttribute } from '@angular/core';

import type { REP_TYPE } from '@delon/theme';
import { AlainConfigService } from '@delon/util/config';
import { InputNumber, NumberInput } from '@delon/util/decorator';
import { toNumber } from '@delon/util/decorator';
import { NzSafeAny } from 'ng-zorro-antd/core/types';

@Component({
selector: 'sg-container, [sg-container]',
Expand All @@ -20,13 +21,9 @@ import { InputNumber, NumberInput } from '@delon/util/decorator';
standalone: true
})
export class SGContainerComponent {
static ngAcceptInputType_gutter: NumberInput;
static ngAcceptInputType_colInCon: NumberInput;
static ngAcceptInputType_col: NumberInput;

@Input() @InputNumber() gutter!: number;
@Input('sg-container') @InputNumber(null) colInCon?: REP_TYPE;
@Input() @InputNumber(null) col!: REP_TYPE;
@Input({ transform: numberAttribute }) gutter!: number;
@Input({ alias: 'sg-container', transform: (v: NzSafeAny) => toNumber(v, null) }) colInCon?: REP_TYPE;
@Input({ transform: (v: NzSafeAny) => toNumber(v, null) }) col!: REP_TYPE;

get marginValue(): number {
return -(this.gutter / 2);
Expand Down
24 changes: 10 additions & 14 deletions packages/abc/sg/sg.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import {
ChangeDetectionStrategy,
Component,
ElementRef,
Host,
Input,
OnChanges,
Optional,
Renderer2,
ViewEncapsulation
ViewEncapsulation,
inject
} from '@angular/core';

import { ResponsiveService } from '@delon/theme';
import { InputNumber, NumberInput } from '@delon/util/decorator';
import { toNumber } from '@delon/util/decorator';
import type { NzSafeAny } from 'ng-zorro-antd/core/types';

import { SGContainerComponent } from './sg-container.component';

Expand All @@ -32,28 +32,24 @@ const prefixCls = `sg`;
standalone: true
})
export class SGComponent implements OnChanges, AfterViewInit {
static ngAcceptInputType_col: NumberInput;
private readonly el: HTMLElement = inject(ElementRef).nativeElement;
private readonly ren = inject(Renderer2);
private readonly rep = inject(ResponsiveService);
private readonly parent = inject(SGContainerComponent, { host: true, optional: true })!;

private el: HTMLElement;
private clsMap: string[] = [];
private inited = false;

@Input() @InputNumber(null) col: number | null = null;
@Input({ transform: (v: NzSafeAny) => toNumber(v, null) }) col: number | null = null;

get paddingValue(): number {
return this.parent.gutter / 2;
}

constructor(
el: ElementRef,
private ren: Renderer2,
@Optional() @Host() private parent: SGContainerComponent,
private rep: ResponsiveService
) {
constructor() {
if (parent == null) {
throw new Error(`[sg] must include 'sg-container' component`);
}
this.el = el.nativeElement;
}

private setClass(): this {
Expand Down

0 comments on commit 06cb9d2

Please sign in to comment.