diff --git a/app/assets/javascripts/directives/views/actionsMenu.ts b/app/assets/javascripts/directives/views/actionsMenu.ts index b575683ec6b..1defb6d1096 100644 --- a/app/assets/javascripts/directives/views/actionsMenu.ts +++ b/app/assets/javascripts/directives/views/actionsMenu.ts @@ -2,7 +2,7 @@ import { WebApplication } from '@/ui_models/application'; import { WebDirective } from './../../types'; import template from '%/directives/actions-menu.pug'; import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl'; -import { SNItem, Action, SNActionsExtension } from 'snjs/dist/@types'; +import { SNItem, Action, SNActionsExtension, UuidString } from 'snjs/dist/@types'; import { ActionResponse } from 'snjs/dist/@types/services/actions_service'; import { ActionsExtensionMutator } from 'snjs/dist/@types/models/app/extension'; @@ -24,13 +24,10 @@ type UpdateActionParams = { subrows?: ActionSubRow[] } -type UpdateExtensionParams = { - hidden?: boolean - loading?: boolean -} - type ActionsMenuState = { - extensions: SNActionsExtension[] + extensions: SNActionsExtension[], + hiddenState: Record + loadingState: Record } class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements ActionsMenuScope { @@ -57,17 +54,22 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti const extensions = this.application.actionsManager!.getExtensions().sort((a, b) => { return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; }); - return { extensions }; + return { + extensions, + loadingState: {}, + hiddenState: {} + }; } async loadExtensions() { await Promise.all(this.state.extensions.map(async (extension: SNActionsExtension) => { - extension = await this.updateExtension(extension, { loading: true }); + await this.setLoadingExtension(extension.uuid, true); const updatedExtension = await this.application.actionsManager!.loadExtensionInContextOfItem( extension, this.item ); - await this.updateExtension(updatedExtension!, { loading: false }); + await this.updateExtension(updatedExtension!); + await this.setLoadingExtension(extension.uuid, false); })); } @@ -147,25 +149,16 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti await this.updateExtension(updatedExtension); } - private async updateExtension( - extension: SNActionsExtension, - params?: UpdateExtensionParams - ) { - const updatedExtension = await this.application.changeItem(extension.uuid, (mutator) => { - const extensionMutator = mutator as ActionsExtensionMutator; - extensionMutator.hidden = Boolean(params?.hidden); - extensionMutator.loading = Boolean(params?.loading); - }) as SNActionsExtension; + private async updateExtension(extension: SNActionsExtension) { const extensions = this.state.extensions.map((ext: SNActionsExtension) => { if (extension.uuid === ext.uuid) { - return updatedExtension; + return extension; } return ext; }); await this.setState({ extensions }); - return updatedExtension; } private async reloadExtension(extension: SNActionsExtension) { @@ -183,6 +176,32 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti extensions }); } + + private async toggleExtensionVisibility(extensionUuid: UuidString) { + const { hiddenState } = this.state; + hiddenState[extensionUuid] = !hiddenState[extensionUuid] ?? false; + await this.setState({ + hiddenState + }); + } + + private isExtensionVisible(extensionUuid: UuidString) { + const { hiddenState } = this.state; + return hiddenState[extensionUuid] ?? false; + } + + private async setLoadingExtension(extensionUuid: UuidString, value = false) { + const { loadingState } = this.state; + loadingState[extensionUuid] = value; + await this.setState({ + loadingState + }); + } + + private isExtensionLoading(extensionUuid: UuidString) { + const { loadingState } = this.state; + return loadingState[extensionUuid] ?? false; + } } export class ActionsMenu extends WebDirective { diff --git a/app/assets/templates/directives/actions-menu.pug b/app/assets/templates/directives/actions-menu.pug index 0e5e7f8afb1..8bce7da0c1d 100644 --- a/app/assets/templates/directives/actions-menu.pug +++ b/app/assets/templates/directives/actions-menu.pug @@ -9,17 +9,17 @@ menu-row(label="'Download Actions'") div(ng-repeat='extension in self.state.extensions track by extension.uuid') .sk-menu-panel-header( - ng-click='self.updateExtension(extension, { hidden: !extension.hidden }); $event.stopPropagation();' + ng-click='self.toggleExtensionVisibility(extension.uuid); $event.stopPropagation();' ) .sk-menu-panel-column .sk-menu-panel-header-title {{extension.name}} - div(ng-if='extension.hidden') … - div(ng-if='extension.loading') + div(ng-if='self.isExtensionVisible(extension.uuid)') … + div(ng-if='self.isExtensionLoading(extension.uuid)') .sk-spinner.small.loading menu-row( action='self.executeAction(action, extension)', label='action.label', - ng-if='!extension.hidden && !extension.loading', + ng-if='!self.isExtensionVisible(extension.uuid) && !self.isExtensionLoading(extension.uuid)', ng-repeat='action in extension.actionsWithContextForItem(self.item) track by $index', disabled='action.running' spinner-class="action.running ? 'info' : null",