From 45fe64191deef4046ec3b230a331ea3fd0ed64c7 Mon Sep 17 00:00:00 2001 From: Johnny Almonte Date: Thu, 25 Jun 2020 23:37:49 -0400 Subject: [PATCH] refactor: actions menu --- .../directives/views/actionsMenu.ts | 90 +++++++++++++++---- .../templates/directives/actions-menu.pug | 19 ++-- 2 files changed, 85 insertions(+), 24 deletions(-) diff --git a/app/assets/javascripts/directives/views/actionsMenu.ts b/app/assets/javascripts/directives/views/actionsMenu.ts index b7a91a709..5e3791568 100644 --- a/app/assets/javascripts/directives/views/actionsMenu.ts +++ b/app/assets/javascripts/directives/views/actionsMenu.ts @@ -2,19 +2,38 @@ 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 '@node_modules/snjs/dist/@types'; -import { ActionResponse } from '@node_modules/snjs/dist/@types/services/actions_service'; +import { SNItem, Action, SNActionsExtension } from 'snjs/dist/@types'; +import { ActionResponse } from 'snjs/dist/@types/services/actions_service'; +import { ActionsExtensionMutator } from 'snjs/dist/@types/models/app/extension'; type ActionsMenuScope = { application: WebApplication item: SNItem } +type ActionSubRow = { + onClick: () => void + label: string + subtitle: string + spinnerClass: string | undefined +} + +type UpdateActionParams = { + running?: boolean + error?: boolean + subrows?: ActionSubRow[] +} + +type UpdateExtensionParams = { + hidden?: boolean + loading?: boolean +} + class ActionsMenuCtrl extends PureViewCtrl implements ActionsMenuScope { application!: WebApplication item!: SNItem - public loadingState: Partial> = {} + public loadingExtensions: boolean = true /* @ngInject */ constructor( @@ -39,14 +58,15 @@ class ActionsMenuCtrl extends PureViewCtrl implements ActionsMenuScope { return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; }); for (const extension of extensions) { - this.loadingState[extension.uuid] = true; await this.application.actionsManager!.loadExtensionInContextOfItem( extension, this.props.item ); - this.loadingState[extension.uuid] = false; } - this.setState({ + if (extensions.length == 0) { + this.loadingExtensions = false; + } + await this.setState({ extensions: extensions }); } @@ -54,13 +74,12 @@ class ActionsMenuCtrl extends PureViewCtrl implements ActionsMenuScope { async executeAction(action: Action, extension: SNActionsExtension) { if (action.verb === 'nested') { if (!action.subrows) { - action.subrows = this.subRowsForAction(action, extension); - } else { - action.subrows = undefined; + const subrows = this.subRowsForAction(action, extension); + await this.updateAction(action, extension, { subrows }); } return; } - action.running = true; + await this.updateAction(action, extension, { running: true }); const response = await this.application.actionsManager!.runAction( action, this.props.item, @@ -69,18 +88,17 @@ class ActionsMenuCtrl extends PureViewCtrl implements ActionsMenuScope { return ''; } ); - if (action.error) { + if (response.error) { + await this.updateAction(action, extension, { error: true }); return; } - action.running = false; + await this.updateAction(action, extension, { running: false }); this.handleActionResponse(action, response); - await this.application.actionsManager!.loadExtensionInContextOfItem( + const updatedExtension = await this.application.actionsManager!.loadExtensionInContextOfItem( extension, this.props.item ); - this.setState({ - extensions: this.state.extensions - }); + await this.updateExtension(updatedExtension!); } handleActionResponse(action: Action, result: ActionResponse) { @@ -95,7 +113,7 @@ class ActionsMenuCtrl extends PureViewCtrl implements ActionsMenuScope { } } - subRowsForAction(parentAction: Action, extension: SNActionsExtension) { + subRowsForAction(parentAction: Action, extension: SNActionsExtension): ActionSubRow[] | undefined { if (!parentAction.subactions) { return undefined; } @@ -110,6 +128,44 @@ class ActionsMenuCtrl extends PureViewCtrl implements ActionsMenuScope { }; }); } + + async updateAction( + action: Action, + extension: SNActionsExtension, + params: UpdateActionParams + ) { + const updatedExtension = await this.application.changeItem(extension.uuid, (mutator) => { + const extensionMutator = mutator as ActionsExtensionMutator; + extensionMutator.actions = extension!.actions.map((act) => { + if (act && params && act.verb === action.verb && act.url === action.url) { + return { + ...action, + running: params?.running, + error: params?.error, + subrows: params?.subrows || act?.subrows, + }; + } + return act; + }); + }) as SNActionsExtension; + await this.updateExtension(updatedExtension); + } + + async updateExtension(extension: SNActionsExtension, params?: UpdateExtensionParams) { + const updatedExtension = await this.application.changeItem(extension.uuid, (mutator) => { + const extensionMutator = mutator as ActionsExtensionMutator; + extensionMutator.hidden = params && params.hidden; + }) as SNActionsExtension; + const updatedExtensions = this.state.extensions.map((ext: SNActionsExtension) => { + if (extension.uuid === ext.uuid) { + return updatedExtension; + } + return ext; + }); + await this.setState({ + extensions: updatedExtensions + }); + } } export class ActionsMenu extends WebDirective { diff --git a/app/assets/templates/directives/actions-menu.pug b/app/assets/templates/directives/actions-menu.pug index 88804429a..21ed0b287 100644 --- a/app/assets/templates/directives/actions-menu.pug +++ b/app/assets/templates/directives/actions-menu.pug @@ -7,19 +7,24 @@ target='blank' ) menu-row(label="'Download Actions'") - div(ng-repeat='extension in self.state.extensions track by extension.uuid') + div(ng-if='self.loadingExtensions') + .sk-menu-panel-header + .sk-menu-panel-column + .sk-menu-panel-header-title Loading... + .sk-spinner.small.loading + div(ng-repeat='extension in self.state.extensions track by extension.uuid; self.loadingExtensions = false') .sk-menu-panel-header( - ng-click='extension.hide = !extension.hide; $event.stopPropagation();' + ng-click='self.updateExtension(extension, { hidden: !extension.hidden }); $event.stopPropagation();' ) .sk-menu-panel-column .sk-menu-panel-header-title {{extension.name}} - .sk-spinner.small.loading(ng-if='self.loadingState[extension.uuid]') - div(ng-if='extension.hide') … + div(ng-if='extension.hidden') … menu-row( - action='self.executeAction(action, extension);', + action='self.executeAction(action, extension)', label='action.label', - ng-if='!extension.hide', - ng-repeat='action in extension.actionsWithContextForItem(self.props.item)', + ng-if='!extension.hidden', + ng-repeat='action in extension.actionsWithContextForItem(self.props.item) track by $index', + disabled='action.running' spinner-class="action.running ? 'info' : null", sub-rows='action.subrows', subtitle='action.desc'