Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:standardnotes/web into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
moughxyz committed Sep 25, 2020
2 parents 949cd55 + 368eb4c commit b124ac4
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 66 deletions.
105 changes: 66 additions & 39 deletions app/assets/javascripts/directives/views/actionsMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ type ActionSubRow = {
spinnerClass?: string
}

type UpdateActionParams = {
running?: boolean
error?: boolean
subrows?: ActionSubRow[]
}

type ExtensionState = {
hidden: boolean
loading: boolean
Expand All @@ -33,6 +27,17 @@ type ExtensionState = {
type ActionsMenuState = {
extensions: SNActionsExtension[]
extensionsState: Record<UuidString, ExtensionState>
selectedActionId?: number
menu: {
uuid: UuidString,
name: string,
loading: boolean,
error: boolean,
hidden: boolean,
actions: (Action & {
subrows?: ActionSubRow[]
})[]
}[]
}

class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements ActionsMenuScope {
Expand All @@ -52,6 +57,7 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti
item: this.item
});
this.loadExtensions();
this.rebuildMenu();
};

/** @override */
Expand All @@ -69,10 +75,43 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti
});
return {
extensions,
extensionsState
extensionsState,
menu: [],
};
}

rebuildMenu({
extensions = this.state.extensions,
extensionsState = this.state.extensionsState,
selectedActionId = this.state.selectedActionId,
} = {}) {
return this.setState({
extensions,
extensionsState,
selectedActionId,
menu: extensions.map(extension => {
const state = extensionsState[extension.uuid];
return {
uuid: extension.uuid,
name: extension.name,
loading: state?.loading ?? false,
error: state?.error ?? false,
hidden: state?.hidden ?? false,
actions: extension.actionsWithContextForItem(this.item).map(action => {
if (action.id === selectedActionId) {
return {
...action,
subrows: this.subRowsForAction(action, extension)
}
} else {
return action;
}
})
};
})
});
}

async loadExtensions() {
await Promise.all(this.state.extensions.map(async (extension: SNActionsExtension) => {
await this.setLoadingExtension(extension.uuid, true);
Expand All @@ -89,14 +128,14 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti
}));
}

async executeAction(action: Action, extension: SNActionsExtension) {
async executeAction(action: Action, extensionUuid: UuidString) {
if (action.verb === 'nested') {
if (!action.subrows) {
const subrows = this.subRowsForAction(action, extension);
await this.updateAction(action, extension, { subrows });
}
this.rebuildMenu({
selectedActionId: action.id
});
return;
}
const extension = this.application.findItem(extensionUuid) as SNActionsExtension;
await this.updateAction(action, extension, { running: true });
const response = await this.application.actionsManager!.runAction(
action,
Expand Down Expand Up @@ -127,14 +166,15 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti
}
}

private subRowsForAction(parentAction: Action, extension: SNActionsExtension): ActionSubRow[] | undefined {
private subRowsForAction(parentAction: Action, extension: Pick<SNActionsExtension, 'uuid'>): ActionSubRow[] | undefined {
if (!parentAction.subactions) {
return undefined;
}
return parentAction.subactions.map((subaction) => {
return {
id: subaction.id,
onClick: () => {
this.executeAction(subaction, extension);
this.executeAction(subaction, extension.uuid);
},
label: subaction.label,
subtitle: subaction.desc,
Expand All @@ -146,7 +186,10 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti
private async updateAction(
action: Action,
extension: SNActionsExtension,
params: UpdateActionParams
params: {
running?: boolean
error?: boolean
}
) {
const updatedExtension = await this.application.changeItem(extension.uuid, (mutator) => {
const extensionMutator = mutator as ActionsExtensionMutator;
Expand All @@ -156,7 +199,6 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti
...action,
running: params?.running,
error: params?.error,
subrows: params?.subrows || act?.subrows,
} as Action;
}
return act;
Expand All @@ -172,7 +214,7 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti
}
return ext;
});
await this.setState({
await this.rebuildMenu({
extensions
});
}
Expand All @@ -188,49 +230,34 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti
}
return ext;
});
this.setState({
this.rebuildMenu({
extensions
});
}

private async toggleExtensionVisibility(extensionUuid: UuidString) {
public toggleExtensionVisibility(extensionUuid: UuidString) {
const { extensionsState } = this.state;
extensionsState[extensionUuid].hidden = !extensionsState[extensionUuid].hidden;
await this.setState({
this.rebuildMenu({
extensionsState
});
}

private isExtensionVisible(extensionUuid: UuidString) {
const { extensionsState } = this.state;
return extensionsState[extensionUuid].hidden;
}

private async setLoadingExtension(extensionUuid: UuidString, value = false) {
private setLoadingExtension(extensionUuid: UuidString, value = false) {
const { extensionsState } = this.state;
extensionsState[extensionUuid].loading = value;
await this.setState({
this.rebuildMenu({
extensionsState
});
}

private isExtensionLoading(extensionUuid: UuidString) {
const { extensionsState } = this.state;
return extensionsState[extensionUuid].loading;
}

private async setErrorExtension(extensionUuid: UuidString, value = false) {
private setErrorExtension(extensionUuid: UuidString, value = false) {
const { extensionsState } = this.state;
extensionsState[extensionUuid].error = value;
await this.setState({
this.rebuildMenu({
extensionsState
});
}

private extensionHasError(extensionUuid: UuidString) {
const { extensionsState } = this.state;
return extensionsState[extensionUuid].error;
}
}

export class ActionsMenu extends WebDirective {
Expand Down
40 changes: 20 additions & 20 deletions app/assets/templates/directives/actions-menu.pug
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
.sn-component
.sk-menu-panel.dropdown-menu
a.no-decoration(
href='https://standardnotes.org/extensions',
ng-if='self.state.extensions.length == 0',
rel='noopener',
href='https://standardnotes.org/extensions',
ng-if='self.state.extensions.length == 0',
rel='noopener',
target='blank'
)
menu-row(label="'Download Actions'")
div(ng-repeat='extension in self.state.extensions track by extension.uuid')
div(ng-repeat='extension in self.state.menu track by extension.uuid')
.sk-menu-panel-header(
ng-click='self.toggleExtensionVisibility(extension.uuid); $event.stopPropagation();'
)
)
.sk-menu-panel-column
.sk-menu-panel-header-title {{extension.name}}
div(ng-if='self.isExtensionVisible(extension.uuid)')
div(ng-if='self.isExtensionLoading(extension.uuid)')
div(ng-if='extension.visible')
div(ng-if='extension.loading')
.sk-spinner.small.loading
menu-row(
action='self.executeAction(action, extension)',
label='action.label',
ng-if='!self.isExtensionVisible(extension.uuid) && !self.isExtensionLoading(extension.uuid) && !self.extensionHasError(extension.uuid)',
ng-repeat='action in extension.actionsWithContextForItem(self.item) track by $index',
action='self.executeAction(action, extension.uuid)',
label='action.label',
ng-if='!extension.visible && !extension.loading && !extension.error',
ng-repeat='action in extension.actions track by $index',
disabled='action.running'
spinner-class="action.running ? 'info' : null",
sub-rows='action.subrows',
spinner-class="action.running ? 'info' : null",
sub-rows='action.subrows',
subtitle='action.desc'
)
.sk-sublabel(ng-if="action.access_type")
| Uses
| Uses
strong {{action.access_type}}
| access to this note.
menu-row(
faded='true',
label="'No Actions Available'",
ng-if='extension.actionsWithContextForItem(self.item).length == 0'
faded='true',
label="'No Actions Available'",
ng-if='!extension.actions.length'
)
menu-row(
faded='true',
label="'Error loading actions'",
faded='true',
label="'Error loading actions'",
subtitle="'Please try again later.'"
ng-if='self.extensionHasError(extension.uuid)'
ng-if='extension.error'
)
14 changes: 7 additions & 7 deletions app/assets/templates/directives/menu-row.pug
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
.sk-menu-panel-row.row(
ng-attr-title='{{ctrl.desc}}',
ng-attr-title='{{ctrl.desc}}',
ng-click='ctrl.onClick($event)'
)
.sk-menu-panel-column
.left
.sk-menu-panel-column(
ng-if=`
ctrl.circle &&
ctrl.circle &&
(!ctrl.circleAlign || ctrl.circleAlign == 'left')
`
)
Expand All @@ -21,17 +21,17 @@
ng-transclude
.sk-menu-panel-subrows(ng-if='ctrl.subRows && ctrl.subRows.length > 0')
menu-row(
ng-repeat='row in ctrl.subRows',
action='row.onClick()',
label='row.label',
spinner-class='row.spinnerClass',
ng-repeat='row in ctrl.subRows',
action='row.onClick()',
label='row.label',
spinner-class='row.spinnerClass',
subtitle='row.subtitle'
)
.sk-menu-panel-column(ng-if="ctrl.circle && ctrl.circleAlign == 'right'")
.sk-circle.small(ng-class='ctrl.circle')
.sk-menu-panel-column(ng-if='ctrl.hasButton')
.sk-button(
ng-class='ctrl.buttonClass',
ng-class='ctrl.buttonClass',
ng-click='ctrl.clickAccessoryButton($event)'
)
.sk-label {{ctrl.buttonText}}
Expand Down

0 comments on commit b124ac4

Please sign in to comment.