132 changed files with 4933 additions and 3051 deletions
@ -0,0 +1,71 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2025 The Thingsboard Authors |
||||
|
|
||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
you may not use this file except in compliance with the License. |
||||
|
You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
||||
|
|
||||
|
--> |
||||
|
<div [formGroup]="limitForm" class="tb-form-table-row overflow-hidden items-start"> |
||||
|
<div class="flex-shrink capitalize" [class]="isPanelView ? 'basis-10' : 'basis-1/5'"> |
||||
|
{{ labelKey | translate}} |
||||
|
</div> |
||||
|
<div class="flex-grow flex-shrink flex flex-col gap-2 gt-sm:flex-row gt-sm:gap-3" [class]="isPanelView ? 'basis-1/2' : 'basis-40%'"> |
||||
|
<mat-form-field class="tb-inline-field flex-1" appearance="outline" subscriptSizing="dynamic"> |
||||
|
<mat-select formControlName="type"> |
||||
|
<mat-option *ngFor="let type of ValueSourceTypes" [value]="type"> |
||||
|
{{ ValueSourceTypeTranslation.get(type) | translate }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<tb-entity-alias-input |
||||
|
required |
||||
|
class="flex-1" |
||||
|
*ngIf="limitForm.get('type').value === ValueSourceType.entity" |
||||
|
[aliasController]="aliasController" |
||||
|
formControlName="entityAlias"> |
||||
|
</tb-entity-alias-input> |
||||
|
</div> |
||||
|
<div class="flex-grow flex-shrink max-w-5/12" [class]="isPanelView ? 'basis-1/2' : 'basis-40%'"> |
||||
|
<mat-form-field *ngIf="limitForm.get('type').value === ValueSourceType.constant" |
||||
|
appearance="outline" class="tb-inline-field !w-full number" subscriptSizing="dynamic" |
||||
|
[class.tb-suffix-absolute]="!limitForm.get('value').value"> |
||||
|
<input matInput formControlName="value" type="number" placeholder="{{ 'widgets.chart.chart-axis.scale-auto' | translate }}"> |
||||
|
</mat-form-field> |
||||
|
<tb-data-key-input |
||||
|
required |
||||
|
*ngIf="limitForm.get('type').value === ValueSourceType.latestKey" |
||||
|
requiredText="widgets.chart.chart-axis.key-required" |
||||
|
[datasourceType]="datasource?.type" |
||||
|
[entityAliasId]="datasource?.entityAliasId" |
||||
|
[deviceId]="datasource?.deviceId" |
||||
|
[aliasController]="aliasController" |
||||
|
[dataKeyType]="datasource?.type === DatasourceType.function ? DataKeyType.function : null" |
||||
|
[dataKeyTypes]="[DataKeyType.attribute, DataKeyType.timeseries]" |
||||
|
[callbacks]="callbacks" |
||||
|
[editable]="false" |
||||
|
[formControl]="latestKeyFormControl"> |
||||
|
</tb-data-key-input> |
||||
|
<tb-data-key-input |
||||
|
required |
||||
|
*ngIf="limitForm.get('type').value === ValueSourceType.entity" |
||||
|
requiredText="widgets.chart.chart-axis.entity-key-required" |
||||
|
[datasourceType]="DatasourceType.entity" |
||||
|
[aliasController]="aliasController" |
||||
|
[entityAlias]="limitForm.get('entityAlias').value" |
||||
|
[dataKeyTypes]="[DataKeyType.attribute, DataKeyType.timeseries]" |
||||
|
[callbacks]="callbacks" |
||||
|
[editable]="false" |
||||
|
[formControl]="entityKeyFormControl"> |
||||
|
</tb-data-key-input> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,209 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2025 The Thingsboard Authors
|
||||
|
///
|
||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
/// you may not use this file except in compliance with the License.
|
||||
|
/// You may obtain a copy of the License at
|
||||
|
///
|
||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
///
|
||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
/// See the License for the specific language governing permissions and
|
||||
|
/// limitations under the License.
|
||||
|
///
|
||||
|
|
||||
|
import { Component, DestroyRef, forwardRef, Input, OnInit } from '@angular/core'; |
||||
|
import { |
||||
|
ControlValueAccessor, NG_VALIDATORS, |
||||
|
NG_VALUE_ACCESSOR, |
||||
|
UntypedFormBuilder, UntypedFormControl, |
||||
|
UntypedFormGroup, ValidationErrors, Validator, |
||||
|
Validators, |
||||
|
} from '@angular/forms'; |
||||
|
import { |
||||
|
ValueSourceConfig, |
||||
|
ValueSourceType, |
||||
|
ValueSourceTypes, |
||||
|
ValueSourceTypeTranslation |
||||
|
} from '@shared/models/widget-settings.models'; |
||||
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; |
||||
|
import { DataKey, Datasource, DatasourceType, } from '@shared/models/widget.models'; |
||||
|
import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; |
||||
|
import { IAliasController } from '@core/api/widget-api.models'; |
||||
|
import { DataKeysCallbacks } from '@home/components/widget/lib/settings/common/key/data-keys.component.models'; |
||||
|
import { merge } from 'rxjs'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-axis-scale-row', |
||||
|
templateUrl: './axis-scale-row.component.html', |
||||
|
providers: [ |
||||
|
{ |
||||
|
provide: NG_VALUE_ACCESSOR, |
||||
|
useExisting: forwardRef(() => AxisScaleRowComponent), |
||||
|
multi: true |
||||
|
}, |
||||
|
{ |
||||
|
provide: NG_VALIDATORS, |
||||
|
useExisting: forwardRef(() => AxisScaleRowComponent), |
||||
|
multi: true |
||||
|
}, |
||||
|
] |
||||
|
}) |
||||
|
export class AxisScaleRowComponent implements ControlValueAccessor, OnInit, Validator { |
||||
|
|
||||
|
@Input() |
||||
|
isPanelView = false; |
||||
|
|
||||
|
@Input() |
||||
|
aliasController: IAliasController; |
||||
|
|
||||
|
@Input() |
||||
|
callbacks: DataKeysCallbacks; |
||||
|
|
||||
|
@Input() |
||||
|
datasource: Datasource; |
||||
|
|
||||
|
@Input() |
||||
|
labelKey: string; |
||||
|
|
||||
|
ValueSourceType = ValueSourceType; |
||||
|
|
||||
|
DataKeyType = DataKeyType; |
||||
|
|
||||
|
DatasourceType = DatasourceType; |
||||
|
|
||||
|
ValueSourceTypeTranslation = ValueSourceTypeTranslation; |
||||
|
|
||||
|
ValueSourceTypes = ValueSourceTypes; |
||||
|
|
||||
|
limitForm: UntypedFormGroup; |
||||
|
|
||||
|
latestKeyFormControl: UntypedFormControl; |
||||
|
|
||||
|
entityKeyFormControl: UntypedFormControl; |
||||
|
|
||||
|
private propagateChanges: (value: any) => void = () => {}; |
||||
|
|
||||
|
private modelValue: ValueSourceConfig | null = null; |
||||
|
|
||||
|
constructor(private fb: UntypedFormBuilder, |
||||
|
private destroyRef: DestroyRef) { |
||||
|
} |
||||
|
|
||||
|
ngOnInit() { |
||||
|
this.limitForm = this.fb.group({ |
||||
|
type: [ValueSourceType.constant], |
||||
|
value: [null], |
||||
|
entityAlias: [null] |
||||
|
}); |
||||
|
this.latestKeyFormControl = this.fb.control(null, [Validators.required]); |
||||
|
this.entityKeyFormControl = this.fb.control(null, [Validators.required]); |
||||
|
merge( |
||||
|
this.latestKeyFormControl.valueChanges, |
||||
|
this.entityKeyFormControl.valueChanges, |
||||
|
this.limitForm.valueChanges |
||||
|
).pipe(takeUntilDestroyed(this.destroyRef)) |
||||
|
.subscribe(() => { |
||||
|
this.updateValidators(); |
||||
|
this.updateModel(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
writeValue(value: ValueSourceConfig) { |
||||
|
this.modelValue = value; |
||||
|
this.limitForm.patchValue( |
||||
|
{ |
||||
|
type: value.type || ValueSourceType.constant, |
||||
|
value: value.value, |
||||
|
entityAlias: value.entityAlias, |
||||
|
}, {emitEvent: false} |
||||
|
); |
||||
|
if (value.type === ValueSourceType.latestKey) { |
||||
|
this.latestKeyFormControl.patchValue({ |
||||
|
type: value.latestKeyType, |
||||
|
name: value.latestKey |
||||
|
}, {emitEvent: false}); |
||||
|
} else if (value.type === ValueSourceType.entity) { |
||||
|
this.entityKeyFormControl.patchValue({ |
||||
|
type: value.entityKeyType, |
||||
|
name: value.entityKey |
||||
|
}, {emitEvent: false}); |
||||
|
} |
||||
|
|
||||
|
this.updateValidators(); |
||||
|
this.limitForm.markAllAsTouched(); |
||||
|
} |
||||
|
|
||||
|
registerOnChange(fn: any) { |
||||
|
this.propagateChanges = fn; |
||||
|
} |
||||
|
|
||||
|
registerOnTouched(fn: any) { |
||||
|
} |
||||
|
|
||||
|
validate(): ValidationErrors | null { |
||||
|
const type = this.limitForm.get('type')?.value; |
||||
|
const errors: any = {}; |
||||
|
|
||||
|
if (this.limitForm.invalid) { |
||||
|
errors.form = false; |
||||
|
} |
||||
|
|
||||
|
if (type === ValueSourceType.latestKey) { |
||||
|
if (!this.latestKeyFormControl.value || this.latestKeyFormControl.invalid) { |
||||
|
errors.latestKey = false; |
||||
|
} |
||||
|
} else if (type === ValueSourceType.entity) { |
||||
|
if (!this.limitForm.get('entityAlias')?.value) { |
||||
|
errors.entityAlias = false; |
||||
|
} |
||||
|
if (!this.entityKeyFormControl.value || this.entityKeyFormControl.invalid) { |
||||
|
errors.entityKey = false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return Object.keys(errors).length ? { axisLimitForm: errors } : null; |
||||
|
} |
||||
|
|
||||
|
private updateValidators() { |
||||
|
const axisTypeControl = this.limitForm.get('type'); |
||||
|
if (axisTypeControl && this.entityKeyFormControl && this.latestKeyFormControl) { |
||||
|
const type = axisTypeControl.value; |
||||
|
if (type === ValueSourceType.latestKey) { |
||||
|
this.latestKeyFormControl.setValidators([Validators.required]); |
||||
|
this.entityKeyFormControl.clearValidators(); |
||||
|
} else if (type === ValueSourceType.entity) { |
||||
|
this.latestKeyFormControl.clearValidators(); |
||||
|
this.limitForm.get('entityAlias').setValidators([Validators.required]); |
||||
|
this.entityKeyFormControl.setValidators([Validators.required]); |
||||
|
} else { |
||||
|
this.latestKeyFormControl.clearValidators(); |
||||
|
this.entityKeyFormControl.clearValidators(); |
||||
|
} |
||||
|
this.latestKeyFormControl.updateValueAndValidity({ emitEvent: false }); |
||||
|
this.entityKeyFormControl.updateValueAndValidity({ emitEvent: false }); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private updateModel() { |
||||
|
const value = this.limitForm.value; |
||||
|
const type = value.type; |
||||
|
let updates: Partial<ValueSourceConfig> = { type }; |
||||
|
if (type === ValueSourceType.latestKey) { |
||||
|
const latestKey: DataKey = this.latestKeyFormControl.value; |
||||
|
updates.latestKey = latestKey?.name; |
||||
|
updates.latestKeyType = latestKey?.type as any; |
||||
|
} else if (type === ValueSourceType.entity) { |
||||
|
const entityKey: DataKey = this.entityKeyFormControl.value; |
||||
|
updates.entityKey = entityKey?.name; |
||||
|
updates.entityKeyType = entityKey?.type as any; |
||||
|
updates.entityAlias = value?.entityAlias; |
||||
|
} else { |
||||
|
updates.value = value?.value; |
||||
|
} |
||||
|
this.modelValue = updates as ValueSourceConfig; |
||||
|
this.propagateChanges(this.modelValue); |
||||
|
} |
||||
|
} |
||||
@ -1,29 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2025 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
@import '../../../../../scss/constants'; |
|
||||
|
|
||||
:host { |
|
||||
display: flex; |
|
||||
flex: 1 1 0; |
|
||||
.tb-request-password-reset-content { |
|
||||
background-color: #eee; |
|
||||
.tb-request-password-reset-card { |
|
||||
@media #{$mat-gt-xs} { |
|
||||
width: 450px !important; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,34 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2025 The Thingsboard Authors |
|
||||
* |
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
* you may not use this file except in compliance with the License. |
|
||||
* You may obtain a copy of the License at |
|
||||
* |
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
|
||||
* |
|
||||
* Unless required by applicable law or agreed to in writing, software |
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||
* See the License for the specific language governing permissions and |
|
||||
* limitations under the License. |
|
||||
*/ |
|
||||
@import '../../../../../scss/constants'; |
|
||||
|
|
||||
:host { |
|
||||
display: flex; |
|
||||
flex: 1 1 0; |
|
||||
.tb-reset-password-content { |
|
||||
background-color: #eee; |
|
||||
.tb-reset-password-card { |
|
||||
@media #{$mat-gt-sm} { |
|
||||
width: 450px !important; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.tb-card-title{ |
|
||||
padding-top: 0; |
|
||||
padding-bottom: 0; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,47 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2025 The Thingsboard Authors
|
||||
|
///
|
||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
/// you may not use this file except in compliance with the License.
|
||||
|
/// You may obtain a copy of the License at
|
||||
|
///
|
||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
///
|
||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
/// See the License for the specific language governing permissions and
|
||||
|
/// limitations under the License.
|
||||
|
///
|
||||
|
|
||||
|
import { OverlayModule } from '@angular/cdk/overlay'; |
||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { DEFAULT_DIALOG_CONFIG, DialogConfig, DialogModule } from '@angular/cdk/dialog'; |
||||
|
import { MatDialogModule } from '@angular/material/dialog'; |
||||
|
import { DynamicDialog, DynamicMatDialog } from './dynamic-dialog'; |
||||
|
import { DynamicOverlay } from './dynamic-overlay'; |
||||
|
import { DynamicOverlayContainer } from './dynamic-overlay-container'; |
||||
|
|
||||
|
export const DYNAMIC_MAT_DIALOG_PROVIDERS = [ |
||||
|
DynamicOverlayContainer, |
||||
|
DynamicOverlay, |
||||
|
DynamicDialog, |
||||
|
DynamicMatDialog, |
||||
|
{ |
||||
|
provide: DEFAULT_DIALOG_CONFIG, |
||||
|
useValue: { |
||||
|
...new DialogConfig() |
||||
|
} |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
@NgModule( { |
||||
|
imports: [ |
||||
|
OverlayModule, |
||||
|
DialogModule, |
||||
|
MatDialogModule |
||||
|
], |
||||
|
providers: DYNAMIC_MAT_DIALOG_PROVIDERS |
||||
|
} ) |
||||
|
export class DynamicMatDialogModule { |
||||
|
} |
||||
@ -0,0 +1,85 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2025 The Thingsboard Authors
|
||||
|
///
|
||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
/// you may not use this file except in compliance with the License.
|
||||
|
/// You may obtain a copy of the License at
|
||||
|
///
|
||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
///
|
||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
/// See the License for the specific language governing permissions and
|
||||
|
/// limitations under the License.
|
||||
|
///
|
||||
|
|
||||
|
import { Location } from "@angular/common"; |
||||
|
import { Inject, Injectable, Injector, Optional, SkipSelf, TemplateRef } from '@angular/core'; |
||||
|
import { |
||||
|
MAT_DIALOG_DEFAULT_OPTIONS, |
||||
|
MAT_DIALOG_SCROLL_STRATEGY, |
||||
|
MatDialog, |
||||
|
MatDialogConfig, MatDialogRef |
||||
|
} from '@angular/material/dialog'; |
||||
|
import { DynamicOverlay } from "./dynamic-overlay"; |
||||
|
import { DynamicOverlayContainer } from '@shared/components/dialog/dynamic/dynamic-overlay-container'; |
||||
|
import { ComponentType, ScrollStrategy } from '@angular/cdk/overlay'; |
||||
|
import { DEFAULT_DIALOG_CONFIG, Dialog, DialogConfig } from '@angular/cdk/dialog'; |
||||
|
|
||||
|
export interface DynamicMatDialogConfig<D> extends MatDialogConfig<D> { |
||||
|
containerElement?: HTMLElement; |
||||
|
} |
||||
|
|
||||
|
@Injectable() |
||||
|
export class DynamicMatDialog extends MatDialog { |
||||
|
|
||||
|
private _customOverlay: DynamicOverlay; |
||||
|
|
||||
|
constructor( _overlay: DynamicOverlay, |
||||
|
_injector: Injector, |
||||
|
@Optional() location: Location, |
||||
|
@Inject( MAT_DIALOG_DEFAULT_OPTIONS ) _defaultOptions: MatDialogConfig, |
||||
|
@Inject( MAT_DIALOG_SCROLL_STRATEGY ) _scrollStrategy: ScrollStrategy, |
||||
|
@Optional() @SkipSelf() _parentDialog:DynamicMatDialog, |
||||
|
_overlayContainer: DynamicOverlayContainer) { |
||||
|
|
||||
|
super( _overlay, _injector, location, _defaultOptions, _scrollStrategy, _parentDialog, _overlayContainer ); |
||||
|
this._dialog = _injector.get(DynamicDialog); |
||||
|
this._customOverlay = _overlay; |
||||
|
} |
||||
|
|
||||
|
public open<T, D = any, R = any>(component: ComponentType<T> | TemplateRef<T>, config?: DynamicMatDialogConfig<D>): MatDialogRef<T, R> { |
||||
|
if (config?.containerElement) { |
||||
|
config.containerElement.style.transform = 'translateZ(0)'; |
||||
|
this._customOverlay.setContainerElement( config.containerElement ); |
||||
|
} |
||||
|
const ref = super.open(component, config); |
||||
|
if (config?.containerElement) { |
||||
|
ref.afterClosed().subscribe( |
||||
|
{ |
||||
|
next: () => { |
||||
|
this._customOverlay.setContainerElement(null); |
||||
|
}, |
||||
|
error: () => { |
||||
|
this._customOverlay.setContainerElement(null); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
return ref; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Injectable() |
||||
|
export class DynamicDialog extends Dialog { |
||||
|
constructor( _overlay: DynamicOverlay, |
||||
|
_injector: Injector, |
||||
|
@Inject( DEFAULT_DIALOG_CONFIG ) _defaultOptions: DialogConfig, |
||||
|
@Inject( MAT_DIALOG_SCROLL_STRATEGY ) _scrollStrategy: ScrollStrategy, |
||||
|
@Optional() @SkipSelf() _parentDialog: DynamicDialog, |
||||
|
_overlayContainer: DynamicOverlayContainer) { |
||||
|
|
||||
|
super( _overlay, _injector, _defaultOptions, _parentDialog, _overlayContainer, _scrollStrategy ); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2025 The Thingsboard Authors
|
||||
|
///
|
||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
/// you may not use this file except in compliance with the License.
|
||||
|
/// You may obtain a copy of the License at
|
||||
|
///
|
||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
///
|
||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
/// See the License for the specific language governing permissions and
|
||||
|
/// limitations under the License.
|
||||
|
///
|
||||
|
|
||||
|
import { OverlayContainer } from "@angular/cdk/overlay"; |
||||
|
import { Injectable } from "@angular/core"; |
||||
|
|
||||
|
@Injectable() |
||||
|
export class DynamicOverlayContainer extends OverlayContainer { |
||||
|
|
||||
|
public setContainerElement( containerElement:HTMLElement ):void { |
||||
|
|
||||
|
this._containerElement = containerElement; |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue