Compare commits
1
Commits
8ab1322222
...
203c09a0e8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
203c09a0e8 |
@@ -58,6 +58,7 @@
|
||||
"@types/uuid": "^8.3.1",
|
||||
"ace-builds": "^1.11.2",
|
||||
"angular-gridster2": "^12.1.0",
|
||||
"apexcharts": "^6.10.0",
|
||||
"crypto-js": "^4.0.0",
|
||||
"dom-to-image": "^2.6.0",
|
||||
"howler": "^2.2.3",
|
||||
@@ -72,6 +73,7 @@
|
||||
"libphonenumber-js": "^1.9.22",
|
||||
"md5-typescript": "^1.0.5",
|
||||
"moment": "^2.29.1",
|
||||
"ng-apexcharts": "^3.0.0",
|
||||
"ng-packagr": "^12.0.0",
|
||||
"ngx-device-detector": "^2.1.1",
|
||||
"ngx-markdown": "^12.0.1",
|
||||
|
||||
@@ -2,14 +2,12 @@ import {
|
||||
Input,
|
||||
Inject,
|
||||
NgZone,
|
||||
Output,
|
||||
Component,
|
||||
Renderer2,
|
||||
ElementRef,
|
||||
Injectable,
|
||||
EventEmitter,
|
||||
ChangeDetectorRef,
|
||||
TemplateRef,
|
||||
ChangeDetectorRef,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
XStandardType,
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<!-- Component Template -->
|
||||
<ng-container *ngIf="getValue(wrapWithCard) | async; else componentsRef">
|
||||
<x-card
|
||||
class="x-card"
|
||||
[showActions]="true"
|
||||
[color]="getValue(cardColor) | async"
|
||||
[ngClass]="getValue(cssClass) | async"
|
||||
[isInPage]="getValue(isInPage) | async"
|
||||
[showHeader]="
|
||||
(notEmptyValue(cardTitle) | async) ||
|
||||
(notEmptyValue(cardSubTitle) | async)
|
||||
"
|
||||
[subTitle]="getResourceValue(cardSubTitle)"
|
||||
[title]="getResourceValue(cardTitle) | async"
|
||||
[showFooter]="getValue(cardShowFooter) | async"
|
||||
[showActions]="getValue(cardShowActions) | async"
|
||||
[foregroundColor]="getValue(cardForegroundColor) | async"
|
||||
>
|
||||
<!-- Content -->
|
||||
<ng-container *ngTemplateOutlet="componentsRef"></ng-container>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="x-actions" [ngClass]="getValue(cssClass) | async" actions>
|
||||
<ng-content select="[actions]"></ng-content>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div footer *ngIf="getValue(cardShowFooter) | async">
|
||||
<ng-content select="[footer]"></ng-content>
|
||||
</div>
|
||||
</x-card>
|
||||
</ng-container>
|
||||
|
||||
<!-- Component's itSelf Template -->
|
||||
<ng-template #componentsRef>
|
||||
<!-- Component Box ... -->
|
||||
<div
|
||||
class="x-chart x-wrapper"
|
||||
[class.mobile]="isMobileUi$ | async"
|
||||
[ngClass]="getValue(cssClass) | async"
|
||||
>
|
||||
<div #chartContainer class="x-chart-container"></div>
|
||||
</div>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,10 @@
|
||||
.x-chart-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 300px; // ارتفاع پیشفرض
|
||||
}
|
||||
|
||||
.x-chart-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
import {
|
||||
Component,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
ChangeDetectionStrategy,
|
||||
} from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { isNullOrUndefined, nameof } from 'x-framework-core';
|
||||
import ApexCharts, { ApexAxisChartSeries, ApexOptions } from 'apexcharts';
|
||||
import { XChartAction, XChartContainerComponent } from './x-chart.typings';
|
||||
|
||||
@Component({
|
||||
selector: 'x-chart',
|
||||
templateUrl: './x-chart.component.html',
|
||||
styleUrls: ['./x-chart.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class XChartComponent extends XChartContainerComponent {
|
||||
//
|
||||
//#region Props ...
|
||||
//
|
||||
@ViewChild('chartContainer', { static: true })
|
||||
chartContainer!: ElementRef;
|
||||
|
||||
//
|
||||
private chartInstance: ApexCharts | null = null;
|
||||
|
||||
//
|
||||
private ACTION_PROVIDER_SUBSCRIPTION: Subscription;
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region LifeCycles ...
|
||||
afterViewInit() {
|
||||
super.afterViewInit();
|
||||
|
||||
//
|
||||
this.initializeComponent();
|
||||
}
|
||||
|
||||
async onChange(changeKeys: string[]) {
|
||||
super.onChange(changeKeys);
|
||||
|
||||
//
|
||||
// Auto Update ...
|
||||
const isAutoUpdateChanged = changeKeys.includes(
|
||||
nameof<XChartComponent>('autoUpdate'),
|
||||
);
|
||||
if (isAutoUpdateChanged) {
|
||||
//
|
||||
if (isNullOrUndefined(this.autoUpdate)) {
|
||||
this.autoUpdate = this.propertyProvider.autoUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check Auto Update ...
|
||||
var autoUpdate = await this.getValueAsync(this.autoUpdate);
|
||||
if (!autoUpdate || isNullOrUndefined(this.chartInstance)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Options Changed ...
|
||||
const isOptionsChanged = changeKeys.includes(
|
||||
nameof<XChartComponent>('options'),
|
||||
);
|
||||
if (isOptionsChanged) {
|
||||
//
|
||||
if (isNullOrUndefined(this.options)) {
|
||||
this.options = this.propertyProvider.options;
|
||||
}
|
||||
|
||||
//
|
||||
const options = await this.getValueAsync(this.options);
|
||||
await this.chartInstance.updateOptions(options);
|
||||
}
|
||||
|
||||
//
|
||||
// Series Changed ...
|
||||
const isSeriesChanged = changeKeys.includes(
|
||||
nameof<XChartComponent>('series'),
|
||||
);
|
||||
if (isSeriesChanged) {
|
||||
//
|
||||
if (isNullOrUndefined(this.series)) {
|
||||
this.series = this.propertyProvider.series;
|
||||
}
|
||||
|
||||
//
|
||||
const series = await this.getValueAsync(this.series);
|
||||
await this.chartInstance.updateSeries(series);
|
||||
}
|
||||
|
||||
//
|
||||
// Action Provider Changed ...
|
||||
const isActionProviderChanged = changeKeys.includes(
|
||||
nameof<XChartComponent>('actionProvider'),
|
||||
);
|
||||
if (isActionProviderChanged) {
|
||||
this.registerActionProvider();
|
||||
}
|
||||
|
||||
//
|
||||
this.detectChanges();
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
//
|
||||
if (!isNullOrUndefined(this.chartInstance)) {
|
||||
//
|
||||
this.chartInstance.destroy();
|
||||
this.chartInstance = null;
|
||||
}
|
||||
|
||||
//
|
||||
this.unregisterActionProvider();
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Private ...
|
||||
private async initializeComponent() {
|
||||
//
|
||||
// Reading Requirement Properties ...
|
||||
const chartId = await this.getValueAsync(this.uuid);
|
||||
const series = await this.getValueAsync(this.series);
|
||||
const options = await this.getValueAsync(this.options);
|
||||
|
||||
//
|
||||
// Validate Options ...
|
||||
if (isNullOrUndefined(options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const computedStyle = getComputedStyle(document.documentElement);
|
||||
const primaryColor =
|
||||
computedStyle.getPropertyValue('--x-color-primary').trim() || '#008ffb';
|
||||
const textColor =
|
||||
computedStyle.getPropertyValue('--x-color-dark-contrast').trim() ||
|
||||
'#373d3f';
|
||||
const gridColor =
|
||||
computedStyle.getPropertyValue('--x-color-light-shade').trim() ||
|
||||
'#e0e0e0';
|
||||
const finalOptions: ApexOptions = {
|
||||
...options,
|
||||
series: series as any,
|
||||
chart: {
|
||||
...options.chart,
|
||||
id: chartId,
|
||||
type: options.chart?.type || 'line',
|
||||
foreColor: textColor,
|
||||
events: {
|
||||
...options.chart?.events,
|
||||
mounted: (chartContext, config) => {
|
||||
this.chartRendered.emit();
|
||||
options.chart?.events?.mounted?.(chartContext, config);
|
||||
},
|
||||
dataPointSelection: (event, chartContext, config) => {
|
||||
this.dataPointSelected.emit({ event, chartContext, config });
|
||||
options.chart?.events?.dataPointSelection?.(
|
||||
event,
|
||||
chartContext,
|
||||
config,
|
||||
);
|
||||
},
|
||||
zoomed: (chartContext, { xaxis, yaxis }) => {
|
||||
this.zoomed.emit({ xaxis, yaxis });
|
||||
options.chart?.events?.zoomed?.(chartContext, { xaxis, yaxis });
|
||||
},
|
||||
},
|
||||
},
|
||||
theme: {
|
||||
...options.theme,
|
||||
palette: options.theme?.palette || 'palette1',
|
||||
},
|
||||
colors: options.colors || [primaryColor],
|
||||
grid: {
|
||||
...options.grid,
|
||||
borderColor: gridColor,
|
||||
},
|
||||
xaxis: {
|
||||
...options.xaxis,
|
||||
labels: {
|
||||
...options.xaxis?.labels,
|
||||
style: { colors: textColor },
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
...options.yaxis,
|
||||
labels: {
|
||||
...(options.yaxis as any).labels,
|
||||
style: { colors: textColor },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
//
|
||||
this.chartInstance = new ApexCharts(
|
||||
this.chartContainer.nativeElement,
|
||||
finalOptions,
|
||||
);
|
||||
|
||||
//
|
||||
await this.chartInstance.render();
|
||||
}
|
||||
|
||||
private registerActionProvider() {
|
||||
//
|
||||
this.unregisterActionProvider();
|
||||
|
||||
//
|
||||
if (!this.actionProvider) {
|
||||
this.actionProvider = this.propertyProvider.actionProvider;
|
||||
}
|
||||
|
||||
//
|
||||
this.ACTION_PROVIDER_SUBSCRIPTION = this.actionProvider
|
||||
.asObservable()
|
||||
.subscribe(async (model) => {
|
||||
//
|
||||
switch (model.action) {
|
||||
//
|
||||
case XChartAction.Refresh:
|
||||
this.detectChanges();
|
||||
break;
|
||||
|
||||
//
|
||||
case XChartAction.Destroy:
|
||||
this.onDestroy();
|
||||
break;
|
||||
|
||||
//
|
||||
case XChartAction.UpdateSeries:
|
||||
//
|
||||
if (
|
||||
!isNullOrUndefined(model.payload) ||
|
||||
!isNullOrUndefined(this.chartInstance)
|
||||
) {
|
||||
//
|
||||
this.series = await this.getValueAsync(
|
||||
model.payload as ApexAxisChartSeries,
|
||||
);
|
||||
await this.chartInstance.updateSeries(this.series);
|
||||
this.detectChanges();
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
case XChartAction.UpdateOptions:
|
||||
//
|
||||
if (
|
||||
!isNullOrUndefined(model.payload) ||
|
||||
!isNullOrUndefined(this.chartInstance)
|
||||
) {
|
||||
//
|
||||
this.options = await this.getValueAsync(
|
||||
model.payload as ApexOptions,
|
||||
);
|
||||
await this.chartInstance.updateOptions(this.options);
|
||||
this.detectChanges();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private unregisterActionProvider() {
|
||||
//
|
||||
if (!this.ACTION_PROVIDER_SUBSCRIPTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
this.ACTION_PROVIDER_SUBSCRIPTION.unsubscribe();
|
||||
this.ACTION_PROVIDER_SUBSCRIPTION = null;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { XCardModule } from '../x-card/x-card.module';
|
||||
import { XIconModule } from '../x-icon/x-icon.module';
|
||||
import { XChartComponent } from './x-chart.component';
|
||||
import { XSlotterModule } from '../x-slotter/x-slotter.module';
|
||||
import { XBaseComponentModule } from '../modules/x-base-component.module';
|
||||
|
||||
@NgModule({
|
||||
providers: [],
|
||||
entryComponents: [],
|
||||
declarations: [XChartComponent],
|
||||
imports: [
|
||||
XCardModule,
|
||||
XIconModule,
|
||||
CommonModule,
|
||||
XSlotterModule,
|
||||
XBaseComponentModule,
|
||||
],
|
||||
exports: [
|
||||
XCardModule,
|
||||
XIconModule,
|
||||
CommonModule,
|
||||
XSlotterModule,
|
||||
XChartComponent,
|
||||
XBaseComponentModule,
|
||||
],
|
||||
})
|
||||
export class XChartModule {}
|
||||
@@ -0,0 +1,194 @@
|
||||
import {
|
||||
ApexOptions,
|
||||
ApexAxisChartSeries,
|
||||
ApexNonAxisChartSeries,
|
||||
} from 'apexcharts';
|
||||
import {
|
||||
Input,
|
||||
Inject,
|
||||
NgZone,
|
||||
Output,
|
||||
Component,
|
||||
Renderer2,
|
||||
ElementRef,
|
||||
Injectable,
|
||||
EventEmitter,
|
||||
ChangeDetectorRef,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
IXComponentCardContainer,
|
||||
XComponentCardContainer,
|
||||
XComponentCardContainerComponent,
|
||||
} from '../x-card/x-card.typings';
|
||||
import { concatMap, map } from 'rxjs/operators';
|
||||
import { forkJoin, Observable, Subject } from 'rxjs';
|
||||
import { ViewportRuler } from '@angular/cdk/overlay';
|
||||
import { XManagerService } from 'x-framework-services';
|
||||
import { XOneOrManyType, XStandardType } from 'x-framework-core';
|
||||
import { XBaseActionModel } from '../classes/x-base-action.model';
|
||||
import { X_FRAMEWORK_COMPONENTS_CONFIG } from '../tokens/x-injectable-tokens';
|
||||
import { XFrameworkComponentsConfig } from '../config/x-framework-components.config';
|
||||
|
||||
export enum XChartAction {
|
||||
Refresh = 'refresh',
|
||||
Destroy = 'destroy',
|
||||
UpdateSeries = 'update_series',
|
||||
UpdateOptions = 'update_options',
|
||||
}
|
||||
|
||||
export type XChartActionIdentifier = XChartAction | string;
|
||||
|
||||
export interface XChartActionModel extends XBaseActionModel<XChartActionIdentifier> {}
|
||||
|
||||
export interface IXChartContainer extends IXComponentCardContainer {
|
||||
//
|
||||
// Commons ...
|
||||
actionProvider: Subject<XChartActionModel>;
|
||||
cssClass: XStandardType<XOneOrManyType<string>>;
|
||||
|
||||
//
|
||||
// Chart Props ...
|
||||
autoUpdate: XStandardType<boolean>;
|
||||
options: XStandardType<ApexOptions>;
|
||||
series: XStandardType<ApexAxisChartSeries | ApexNonAxisChartSeries>;
|
||||
|
||||
//
|
||||
// Events ...
|
||||
chartRendered: EventEmitter<void>;
|
||||
dataPointSelected: EventEmitter<any>;
|
||||
zoomed: EventEmitter<any>;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class XChartContainer
|
||||
extends XComponentCardContainer
|
||||
implements Readonly<IXChartContainer>
|
||||
{
|
||||
//
|
||||
readonly chartId: XStandardType<string>;
|
||||
readonly options: XStandardType<ApexOptions>;
|
||||
readonly autoUpdate: XStandardType<boolean> = true;
|
||||
readonly cssClass: XStandardType<XOneOrManyType<string>>;
|
||||
readonly actionProvider = new Subject<XChartActionModel>();
|
||||
readonly series: XStandardType<ApexAxisChartSeries | ApexNonAxisChartSeries>;
|
||||
|
||||
//
|
||||
readonly zoomed = new EventEmitter<any>();
|
||||
readonly chartRendered = new EventEmitter<void>();
|
||||
readonly dataPointSelected = new EventEmitter<any>();
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@Component({ template: `` })
|
||||
export abstract class XChartContainerComponent
|
||||
extends XComponentCardContainerComponent
|
||||
implements IXChartContainer
|
||||
{
|
||||
//
|
||||
//#region Props ...
|
||||
@Input()
|
||||
actionProvider: Subject<XChartActionModel> =
|
||||
this.propertyProvider.actionProvider;
|
||||
|
||||
@Input()
|
||||
cssClass: XStandardType<XOneOrManyType<string>> =
|
||||
this.propertyProvider.cssClass;
|
||||
|
||||
@Input()
|
||||
options: XStandardType<ApexOptions> = this.propertyProvider.options;
|
||||
|
||||
@Input()
|
||||
series: XStandardType<ApexAxisChartSeries | ApexNonAxisChartSeries> =
|
||||
this.propertyProvider.series;
|
||||
|
||||
@Input()
|
||||
autoUpdate: XStandardType<boolean> = this.propertyProvider.autoUpdate;
|
||||
|
||||
//
|
||||
// Events ...
|
||||
@Output()
|
||||
chartRendered: EventEmitter<void> = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
dataPointSelected: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
zoomed: EventEmitter<any> = new EventEmitter();
|
||||
//#endregion
|
||||
|
||||
//
|
||||
//#region Constructor ...
|
||||
constructor(
|
||||
@Inject(X_FRAMEWORK_COMPONENTS_CONFIG)
|
||||
public config: XFrameworkComponentsConfig,
|
||||
public managerService: XManagerService,
|
||||
public element: ElementRef,
|
||||
public renderer: Renderer2,
|
||||
public ruler: ViewportRuler,
|
||||
public zone: NgZone,
|
||||
public changeDetector: ChangeDetectorRef,
|
||||
protected propertyProvider: XChartContainer,
|
||||
) {
|
||||
super(
|
||||
config,
|
||||
managerService,
|
||||
element,
|
||||
renderer,
|
||||
ruler,
|
||||
zone,
|
||||
changeDetector,
|
||||
propertyProvider,
|
||||
);
|
||||
}
|
||||
//#endregionّ
|
||||
|
||||
//
|
||||
//#region Abstract ...
|
||||
public extractProps(
|
||||
container?: IXChartContainer,
|
||||
): Observable<IXChartContainer> {
|
||||
return super
|
||||
.extractProps(container ? container : this)
|
||||
.pipe(
|
||||
concatMap((superData) => {
|
||||
return forkJoin({
|
||||
//
|
||||
cssClass: this.getArrayValue(
|
||||
container ? container.cssClass : this.cssClass,
|
||||
),
|
||||
|
||||
//
|
||||
options: this.getValue(
|
||||
container ? container.options : this.options,
|
||||
),
|
||||
series: this.getValue(container ? container.series : this.series),
|
||||
autoUpdate: this.getValue(
|
||||
container ? container.autoUpdate : this.autoUpdate,
|
||||
),
|
||||
}).pipe(
|
||||
map((data) => {
|
||||
return {
|
||||
superData,
|
||||
data,
|
||||
};
|
||||
}),
|
||||
);
|
||||
}),
|
||||
)
|
||||
.pipe(
|
||||
map((info) => ({
|
||||
...info.data,
|
||||
...info.superData,
|
||||
actionProvider: container
|
||||
? container.actionProvider
|
||||
: this.actionProvider,
|
||||
chartRendered: this.chartRendered,
|
||||
dataPointSelected: this.dataPointSelected,
|
||||
zoomed: this.zoomed,
|
||||
})),
|
||||
);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import { XTableModule } from './x-table/x-table.module';
|
||||
import { XFrameworkCoreModule } from 'x-framework-core';
|
||||
import { XThemeModule } from './x-theme/x-theme.module';
|
||||
import { XColorModule } from './x-color/x-color.module';
|
||||
import { XChartModule } from './x-chart/x-chart.module';
|
||||
import { XSliderModule } from './x-slider/x-slider.module';
|
||||
import { XButtonModule } from './x-button/x-button.module';
|
||||
import { XDialogsModule } from './dialogs/x-dialog.module';
|
||||
@@ -77,6 +78,7 @@ import { XDescriptionListModule } from './x-description-list/x-description-list.
|
||||
XListModule,
|
||||
XTabsModule,
|
||||
XGridModule,
|
||||
XChartModule,
|
||||
XFrameModule,
|
||||
XEmptyModule,
|
||||
XColorModule,
|
||||
@@ -136,6 +138,7 @@ import { XDescriptionListModule } from './x-description-list/x-description-list.
|
||||
XTabsModule,
|
||||
XGridModule,
|
||||
XEmptyModule,
|
||||
XChartModule,
|
||||
XFrameModule,
|
||||
XColorModule,
|
||||
XTableModule,
|
||||
|
||||
@@ -17,6 +17,7 @@ export * from './lib/x-grid/x-grid.module';
|
||||
export * from './lib/x-page/x-page.module';
|
||||
export * from './lib/x-tabs/x-tabs.module';
|
||||
export * from './lib/x-tree/x-tree.module';
|
||||
export * from './lib/x-chart/x-chart.module';
|
||||
export * from './lib/x-theme/x-theme.module';
|
||||
export * from './lib/x-table/x-table.module';
|
||||
export * from './lib/x-frame/x-frame.module';
|
||||
@@ -62,6 +63,7 @@ export * from './lib/x-grid/x-grid.component';
|
||||
export * from './lib/x-page/x-page.component';
|
||||
export * from './lib/x-tabs/x-tabs.component';
|
||||
export * from './lib/x-tree/x-tree.component';
|
||||
export * from './lib/x-chart/x-chart.component';
|
||||
export * from './lib/x-color/x-color.component';
|
||||
export * from './lib/x-empty/x-empty.component';
|
||||
export * from './lib/x-frame/x-frame.component';
|
||||
@@ -123,6 +125,7 @@ export * from './lib/x-tree/x-tree.typings';
|
||||
export * from './lib/x-empty/x-empty.typings';
|
||||
export * from './lib/x-frame/x-frame.typings';
|
||||
export * from './lib/x-page/x-page.container';
|
||||
export * from './lib/x-chart/x-chart.typings';
|
||||
export * from './lib/x-color/x-color.typings';
|
||||
export * from './lib/x-theme/x-theme-typings';
|
||||
export * from './lib/x-table/x-table.typings';
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": [
|
||||
|
||||
Reference in New Issue
Block a user