diff --git a/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts b/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts index f902d9b28..0008c5f7a 100644 --- a/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts @@ -54,6 +54,8 @@ export class NodeListComponent implements OnInit, OnDestroy { tabsData: TabButtonData[] = []; options: MenuOptionData[] = []; showDmsgInfo = false; + canLogOut = true; + hasUpdatableNodes = false; // Vars for the pagination functionality. allNodes: Node[]; @@ -138,13 +140,12 @@ export class NodeListComponent implements OnInit, OnDestroy { route: ActivatedRoute, ) { // Configure the options menu shown in the top bar. - this.updateOptionsMenu(true); + this.updateOptionsMenu(); // Check if logout button must be removed. this.authVerificationSubscription = this.authService.checkLogin().subscribe(response => { - if (response === AuthStates.AuthDisabled) { - this.updateOptionsMenu(false); - } + this.canLogOut = response !== AuthStates.AuthDisabled; + this.updateOptionsMenu(); }); // Show the dmsg info if the dmsg url was used. @@ -233,18 +234,19 @@ export class NodeListComponent implements OnInit, OnDestroy { /** * Configures the options menu shown in the top bar. - * @param showLogoutOption If the logout option must be included. */ - private updateOptionsMenu(showLogoutOption: boolean) { - this.options = [ - { + private updateOptionsMenu() { + this.options = []; + + if (this.hasUpdatableNodes) { + this.options.push({ name: 'nodes.update-all', actionName: 'updateAll', icon: 'get_app' - } - ]; + }); + } - if (showLogoutOption) { + if (this.canLogOut) { this.options.push({ name: 'common.logout', actionName: 'logout', @@ -366,6 +368,15 @@ export class NodeListComponent implements OnInit, OnDestroy { // If the data was obtained. if (result.data && !result.error) { this.allNodes = result.data as Node[]; + + this.hasUpdatableNodes = false; + this.allNodes.forEach(node => { + if (GeneralUtils.checkIfTagIsUpdatable(node.buildTag)) { + this.hasUpdatableNodes = true; + } + }); + this.updateOptionsMenu(); + if (this.showDmsgInfo) { // Add the label data to the array, to be able to use it for filtering and sorting. this.allNodes.forEach(node => { @@ -461,7 +472,7 @@ export class NodeListComponent implements OnInit, OnDestroy { const nodesData: NodeData[] = []; this.dataSource.forEach(node => { - if (node.online) { + if (node.online && GeneralUtils.checkIfTagIsUpdatable(node.buildTag)) { nodesData.push({ key: node.localPk, label: node.label, diff --git a/static/skywire-manager-src/src/app/components/pages/node/actions/node-actions-helper.ts b/static/skywire-manager-src/src/app/components/pages/node/actions/node-actions-helper.ts index af5fa1096..bd6d89634 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/actions/node-actions-helper.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/actions/node-actions-helper.ts @@ -1,7 +1,6 @@ import { MatDialog } from '@angular/material/dialog'; import { Router } from '@angular/router'; import { Subscription } from 'rxjs'; -import { TranslateService } from '@ngx-translate/core'; import { Injector } from '@angular/core'; import { BasicTerminalComponent } from './basic-terminal/basic-terminal.component'; @@ -27,8 +26,11 @@ export class NodeActionsHelper { private showingFullList: boolean; private currentNode: Node; private currentNodeKey: string; + private canBeUpdated = false; + private canBeRestarted = false; options: MenuOptionData[] = []; + returnButtonText: string; private rebootSubscription: Subscription; @@ -39,7 +41,6 @@ export class NodeActionsHelper { private router: Router; private snackbarService: SnackbarService; private nodeService: NodeService; - private translateService: TranslateService; private storageService: StorageService; constructor(injector: Injector, showingFullList: boolean) { @@ -48,26 +49,24 @@ export class NodeActionsHelper { this.router = injector.get(Router); this.snackbarService = injector.get(SnackbarService); this.nodeService = injector.get(NodeService); - this.translateService = injector.get(TranslateService); this.storageService = injector.get(StorageService); - // Options for the menu shown in the top bar. + this.showingFullList = showingFullList; + this.returnButtonText = !showingFullList ? 'nodes.title' : 'node.title'; + + this.updateOptions(); + } + + /** + * Options for the menu shown in the top bar. + */ + private updateOptions() { this.options = [ { name: 'actions.menu.terminal', actionName: 'terminal', icon: 'laptop' }, - { - name: 'actions.menu.reboot', - actionName: 'reboot', - icon: 'rotate_right' - }, - { - name: 'actions.menu.update', - actionName: 'update', - icon: 'get_app', - }, { name: 'actions.menu.logs', actionName: 'logs', @@ -75,8 +74,21 @@ export class NodeActionsHelper { } ]; - this.showingFullList = showingFullList; - this.returnButtonText = !showingFullList ? 'nodes.title' : 'node.title'; + if (this.canBeRestarted) { + this.options.push({ + name: 'actions.menu.reboot', + actionName: 'reboot', + icon: 'rotate_right' + }); + } + + if (this.canBeUpdated) { + this.options.push({ + name: 'actions.menu.update', + actionName: 'update', + icon: 'get_app', + }); + } } /** @@ -84,6 +96,16 @@ export class NodeActionsHelper { */ setCurrentNode(currentNode: Node) { this.currentNode = currentNode; + + if (GeneralUtils.checkIfTagIsUpdatable(currentNode.buildTag)) { + this.canBeUpdated = true; + this.canBeRestarted = true; + } else { + this.canBeUpdated = false; + this.canBeRestarted = false; + } + + this.updateOptions(); } /** diff --git a/static/skywire-manager-src/src/app/services/node.service.ts b/static/skywire-manager-src/src/app/services/node.service.ts index 83632bf0c..de514f42d 100644 --- a/static/skywire-manager-src/src/app/services/node.service.ts +++ b/static/skywire-manager-src/src/app/services/node.service.ts @@ -480,6 +480,7 @@ export class NodeService { node.online = response.online; node.localPk = response.overview.local_pk; node.autoconnectTransports = response.public_autoconnect; + node.buildTag = response.build_tag ? response.build_tag : ''; // Ip. if (response.overview && response.overview.local_ip && (response.overview.local_ip as string).trim()) { diff --git a/static/skywire-manager-src/src/app/utils/generalUtils.ts b/static/skywire-manager-src/src/app/utils/generalUtils.ts index d0fc7b774..0035a35e9 100644 --- a/static/skywire-manager-src/src/app/utils/generalUtils.ts +++ b/static/skywire-manager-src/src/app/utils/generalUtils.ts @@ -27,4 +27,24 @@ export default class GeneralUtils { return dialog.open(ConfirmationComponent, config); } + + /** + * Checks the tag of a node, to know if the node is updatable via API calls. + */ + static checkIfTagIsUpdatable(tag: string) { + if ( + tag === undefined || + tag === null || + tag.toUpperCase() === 'Windows'.toUpperCase() || + tag.toUpperCase() === 'Win'.toUpperCase() || + tag.toUpperCase() === 'Mac'.toUpperCase() || + tag.toUpperCase() === 'Macos'.toUpperCase() || + tag.toUpperCase() === 'Mac OS'.toUpperCase() || + tag.toUpperCase() === 'Darwin'.toUpperCase() + ) { + return false; + } + + return true; + } }