18 changed files with 536 additions and 41 deletions
@ -0,0 +1,31 @@ |
|||||
|
{ |
||||
|
"widgetsBundle": { |
||||
|
"alias": "home_page_widgets", |
||||
|
"title": "Home page widgets", |
||||
|
"image": null, |
||||
|
"description": null, |
||||
|
"externalId": null, |
||||
|
"name": "Home page widgets" |
||||
|
}, |
||||
|
"widgetTypes": [ |
||||
|
{ |
||||
|
"alias": "documentation_links", |
||||
|
"name": "Documentation links", |
||||
|
"image": null, |
||||
|
"description": null, |
||||
|
"descriptor": { |
||||
|
"type": "static", |
||||
|
"sizeX": 7.5, |
||||
|
"sizeY": 3, |
||||
|
"resources": [], |
||||
|
"templateHtml": "<tb-doc-links-widget\n [ctx]=\"ctx\">\n</tb-doc-links-widget>\n", |
||||
|
"templateCss": "", |
||||
|
"controllerScript": "self.onInit = function() {\n}", |
||||
|
"settingsSchema": "", |
||||
|
"dataKeySettingsSchema": "", |
||||
|
"settingsDirective": "tb-doc-links-widget-settings", |
||||
|
"defaultConfig": "{\"datasources\":[{\"type\":\"static\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"columns\":3},\"title\":\"Documentation links\",\"dropShadow\":true}" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2023 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 class="tb-card-content" fxLayout="column" fxLayoutGap="8px"> |
||||
|
<div class="tb-card-header"> |
||||
|
<a class="tb-title-link" href="https://thingsboard.io/docs/" target="_blank">Documentation</a> |
||||
|
<button class="tb-title-icon" |
||||
|
matTooltip="Edit" |
||||
|
matTooltipPosition="above" |
||||
|
mat-icon-button |
||||
|
(click)="edit()"> |
||||
|
<mat-icon>edit</mat-icon> |
||||
|
</button> |
||||
|
</div> |
||||
|
<mat-grid-list fxFlex [cols]="columns" rowHeight="fit" gutterSize="12px"> |
||||
|
<mat-grid-tile class="tb-docs-tile" *ngFor="let docLink of documentationLinks?.links"> |
||||
|
<a fxFlex class="tb-doc-button" |
||||
|
[href]="docLink.link" target="_blank"> |
||||
|
<div class="tb-doc-container"> |
||||
|
<div class="tb-doc-icon-container"> |
||||
|
<mat-icon color="primary">{{ docLink.icon }}</mat-icon> |
||||
|
</div> |
||||
|
<div class="tb-doc-text">{{ docLink.name }}</div> |
||||
|
</div> |
||||
|
</a> |
||||
|
</mat-grid-tile> |
||||
|
<mat-grid-tile class="tb-docs-tile"> |
||||
|
<div fxFlex class="tb-add-doc-button" |
||||
|
matTooltip="Add link" |
||||
|
matTooltipPosition="above" |
||||
|
(click)="addLink()"> |
||||
|
<mat-icon class="tb-add-icon">add</mat-icon> |
||||
|
</div> |
||||
|
</mat-grid-tile> |
||||
|
</mat-grid-list> |
||||
|
</div> |
||||
@ -0,0 +1,124 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2023 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. |
||||
|
*/ |
||||
|
:host { |
||||
|
.tb-card-content { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.tb-card-header { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.tb-title-link { |
||||
|
font-style: normal; |
||||
|
font-weight: 500; |
||||
|
font-size: 14px; |
||||
|
line-height: 20px; |
||||
|
letter-spacing: 0.25px; |
||||
|
color: rgba(0, 0, 0, 0.54); |
||||
|
position: relative; |
||||
|
border-bottom: none; |
||||
|
&:hover, &:focus { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
&::after { |
||||
|
content: 'arrow_forward'; |
||||
|
display: inline-block; |
||||
|
position: absolute; |
||||
|
top: -2px; |
||||
|
right: -28px; |
||||
|
transform: rotate(315deg); |
||||
|
font-family: 'Material Icons'; |
||||
|
font-weight: normal; |
||||
|
font-style: normal; |
||||
|
font-size: 18px; |
||||
|
color: rgba(0, 0, 0, 0.12); |
||||
|
} |
||||
|
&:hover::after { |
||||
|
color: inherit; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.tb-title-icon { |
||||
|
color: rgba(0, 0, 0, 0.38); |
||||
|
width: 32px; |
||||
|
height: 32px; |
||||
|
padding: 4px; |
||||
|
} |
||||
|
|
||||
|
.mat-grid-tile.tb-docs-tile { |
||||
|
overflow: visible; |
||||
|
} |
||||
|
|
||||
|
.tb-doc-button { |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
padding: 12px; |
||||
|
background: #FFFFFF; |
||||
|
border: 1px solid rgba(0, 0, 0, 0.05); |
||||
|
box-shadow: 0 5px 16px rgba(0, 0, 0, 0.04); |
||||
|
border-radius: 10px; |
||||
|
&:hover { |
||||
|
border: 1px solid rgba(0, 0, 0, 0.12); |
||||
|
box-shadow: 0 4px 10px rgba(23, 33, 90, 0.08); |
||||
|
} |
||||
|
.tb-doc-container { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
align-items: center; |
||||
|
.tb-doc-icon-container { |
||||
|
height: 40px; |
||||
|
padding: 8px; |
||||
|
background: #F3F6FA; |
||||
|
border-radius: 6px; |
||||
|
margin-right: 8px; |
||||
|
} |
||||
|
.tb-doc-text { |
||||
|
font-weight: 400; |
||||
|
font-size: 14px; |
||||
|
line-height: 20px; |
||||
|
letter-spacing: 0.2px; |
||||
|
color: rgba(0, 0, 0, 0.87); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.tb-add-doc-button { |
||||
|
height: 100%; |
||||
|
cursor: pointer; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
background: #FFFFFF; |
||||
|
padding: 12px; |
||||
|
border: 2px dashed rgba(0, 0, 0, 0.08); |
||||
|
border-radius: 10px; |
||||
|
.tb-add-icon { |
||||
|
color: rgba(0, 0, 0, 0.12); |
||||
|
} |
||||
|
&:hover { |
||||
|
.tb-add-icon { |
||||
|
color: rgba(0, 0, 0, 0.38); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,136 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2023 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 { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; |
||||
|
import { PageComponent } from '@shared/components/page.component'; |
||||
|
import { Store } from '@ngrx/store'; |
||||
|
import { AppState } from '@core/core.state'; |
||||
|
import { Authority } from '@shared/models/authority.enum'; |
||||
|
import { map } from 'rxjs'; |
||||
|
import { DocumentationLinks } from '@shared/models/user-settings.models'; |
||||
|
import { UserSettingsService } from '@core/http/user-settings.service'; |
||||
|
import { getCurrentAuthUser } from '@core/auth/auth.selectors'; |
||||
|
import { WidgetContext } from '@home/models/widget-component.models'; |
||||
|
|
||||
|
const defaultDocLinksMap = new Map<Authority, DocumentationLinks>( |
||||
|
[ |
||||
|
[Authority.SYS_ADMIN, { |
||||
|
links: [ |
||||
|
{ |
||||
|
icon: 'rocket', |
||||
|
name: 'Getting started', |
||||
|
link: 'https://thingsboard.io/docs/getting-started-guides/helloworld/' |
||||
|
}, |
||||
|
{ |
||||
|
icon: 'title', |
||||
|
name: 'Tenant profiles', |
||||
|
link: 'https://thingsboard.io/docs/user-guide/tenant-profiles/' |
||||
|
}, |
||||
|
{ |
||||
|
icon: 'insert_chart', |
||||
|
name: 'API', |
||||
|
link: 'https://thingsboard.io/docs/api/' |
||||
|
}, |
||||
|
{ |
||||
|
icon: 'now_widgets', |
||||
|
name: 'Widgets Library', |
||||
|
link: 'https://thingsboard.io/docs/user-guide/ui/widget-library/' |
||||
|
} |
||||
|
] |
||||
|
}], |
||||
|
[Authority.TENANT_ADMIN, { |
||||
|
links: [ |
||||
|
{ |
||||
|
icon: 'rocket', |
||||
|
name: 'Getting started', |
||||
|
link: 'https://thingsboard.io/docs/getting-started-guides/helloworld/' |
||||
|
}, |
||||
|
{ |
||||
|
icon: 'settings_ethernet', |
||||
|
name: 'Rule engine', |
||||
|
link: 'https://thingsboard.io/docs/user-guide/rule-engine-2-0/re-getting-started/' |
||||
|
}, |
||||
|
{ |
||||
|
icon: 'insert_chart', |
||||
|
name: 'API', |
||||
|
link: 'https://thingsboard.io/docs/api/' |
||||
|
}, |
||||
|
{ |
||||
|
icon: 'devices', |
||||
|
name: 'Device profiles', |
||||
|
link: 'https://thingsboard.io/docs/user-guide/device-profiles/' |
||||
|
} |
||||
|
] |
||||
|
}], |
||||
|
[Authority.CUSTOMER_USER, { |
||||
|
links: [] |
||||
|
}] |
||||
|
] |
||||
|
); |
||||
|
|
||||
|
interface DocLinksWidgetSettings { |
||||
|
columns: number; |
||||
|
} |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-doc-links-widget', |
||||
|
templateUrl: './doc-links-widget.component.html', |
||||
|
styleUrls: ['./doc-links-widget.component.scss'] |
||||
|
}) |
||||
|
export class DocLinksWidgetComponent extends PageComponent implements OnInit { |
||||
|
|
||||
|
@Input() |
||||
|
ctx: WidgetContext; |
||||
|
|
||||
|
settings: DocLinksWidgetSettings; |
||||
|
columns: number; |
||||
|
|
||||
|
documentationLinks: DocumentationLinks; |
||||
|
authUser = getCurrentAuthUser(this.store); |
||||
|
|
||||
|
constructor(protected store: Store<AppState>, |
||||
|
private cd: ChangeDetectorRef, |
||||
|
private userSettingsService: UserSettingsService) { |
||||
|
super(store); |
||||
|
} |
||||
|
|
||||
|
ngOnInit() { |
||||
|
this.settings = this.ctx.settings; |
||||
|
this.columns = this.settings.columns || 3; |
||||
|
this.userSettingsService.getDocumentationLinks().pipe( |
||||
|
map((documentationLinks) => { |
||||
|
if (!documentationLinks || !documentationLinks.links) { |
||||
|
return defaultDocLinksMap.get(this.authUser.authority); |
||||
|
} else { |
||||
|
return documentationLinks; |
||||
|
} |
||||
|
}) |
||||
|
).subscribe( |
||||
|
(documentationLinks) => { |
||||
|
this.documentationLinks = documentationLinks; |
||||
|
this.cd.markForCheck(); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
edit() { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
addLink() { |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2023 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. |
||||
|
|
||||
|
--> |
||||
|
<section class="tb-widget-settings" [formGroup]="docLinksWidgetSettingsForm" fxLayout="column"> |
||||
|
<mat-form-field fxFlex class="mat-block"> |
||||
|
<mat-label>Columns</mat-label> |
||||
|
<input required matInput type="number" step="1" min="1" max="20" formControlName="columns"> |
||||
|
</mat-form-field> |
||||
|
</section> |
||||
@ -0,0 +1,52 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2023 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 } from '@angular/core'; |
||||
|
import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; |
||||
|
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; |
||||
|
import { Store } from '@ngrx/store'; |
||||
|
import { AppState } from '@core/core.state'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-doc-links-widget-settings', |
||||
|
templateUrl: './doc-links-widget-settings.component.html', |
||||
|
styleUrls: ['./../widget-settings.scss'] |
||||
|
}) |
||||
|
export class DocLinksWidgetSettingsComponent extends WidgetSettingsComponent { |
||||
|
|
||||
|
docLinksWidgetSettingsForm: UntypedFormGroup; |
||||
|
|
||||
|
constructor(protected store: Store<AppState>, |
||||
|
private fb: UntypedFormBuilder) { |
||||
|
super(store); |
||||
|
} |
||||
|
|
||||
|
protected settingsForm(): UntypedFormGroup { |
||||
|
return this.docLinksWidgetSettingsForm; |
||||
|
} |
||||
|
|
||||
|
protected defaultSettings(): WidgetSettings { |
||||
|
return { |
||||
|
columns: 3 |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
protected onSettingsSet(settings: WidgetSettings) { |
||||
|
this.docLinksWidgetSettingsForm = this.fb.group({ |
||||
|
columns: [settings.columns, [Validators.required, Validators.min(1), Validators.max(20)]] |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue