Skip to content

Commit 94959ca

Browse files
committed
perf(quick-actions): eliminate dublicate api calld for each envelope
Signed-off-by: Hamza <hamzamahjoubi221@gmail.com>
1 parent 91986b9 commit 94959ca

File tree

8 files changed

+69
-83
lines changed

8 files changed

+69
-83
lines changed

appinfo/routes.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -510,11 +510,6 @@
510510
'url' => '/api/textBlocks/{id}/shares',
511511
'verb' => 'GET',
512512
],
513-
[
514-
'name' => 'actionStep#findAllStepsForAction',
515-
'url' => '/api/action-step/{actionId}/steps',
516-
'verb' => 'GET'
517-
],
518513
],
519514
'resources' => [
520515
'accounts' => ['url' => '/api/accounts'],

lib/Controller/ActionStepController.php

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,6 @@ public function __construct(
3333
$this->uid = $userId;
3434
}
3535

36-
/**
37-
* @NoAdminRequired
38-
*
39-
* @return JsonResponse
40-
*/
41-
#[TrapError]
42-
public function findAllStepsForAction(int $actionId): JsonResponse {
43-
if ($this->uid === null) {
44-
return JsonResponse::error('User not found', Http::STATUS_UNAUTHORIZED);
45-
}
46-
$actionSteps = $this->quickActionsService->findAllActionSteps($actionId, $this->uid);
47-
48-
return JsonResponse::success($actionSteps);
49-
}
50-
5136
/**
5237
* @NoAdminRequired
5338
* @param string $name

lib/Db/Actions.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,30 @@
2222
class Actions extends Entity implements JsonSerializable {
2323
protected $name;
2424
protected $accountId;
25+
protected $actionSteps = [];
26+
protected $icon = '';
2527

2628
public function __construct() {
2729
$this->addType('name', 'string');
2830
$this->addType('accountId', 'integer');
2931
}
3032

33+
public function setActionSteps(array $actionSteps): void {
34+
$this->actionSteps = $actionSteps;
35+
}
36+
37+
public function setIcon(string $icon): void {
38+
$this->icon = $icon;
39+
}
40+
3141
#[ReturnTypeWillChange]
3242
public function jsonSerialize() {
3343
return [
3444
'id' => $this->getId(),
3545
'name' => $this->getName(),
3646
'accountId' => $this->getAccountId(),
47+
'actionSteps' => $this->actionSteps,
48+
'icon' => $this->icon,
3749

3850
];
3951
}

lib/Service/QuickActionsService.php

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,18 @@ public function __construct(
3535
private ActionStepMapper $actionStepMapper,
3636
) {
3737
}
38-
3938
/**
4039
* @param string $userId
4140
* @return Actions[]
4241
*/
4342
public function findAll(string $userId): array {
44-
return $this->actionsMapper->findAll($userId);
43+
$actions = $this->actionsMapper->findAll($userId);
44+
foreach ($actions as $action) {
45+
$actionSteps = $this->actionStepMapper->findAllStepsForOneAction($action->getId(), $userId);
46+
$action->setActionSteps($actionSteps);
47+
$action->setIcon($actionSteps[0]->getName());
48+
}
49+
return $actions;
4550
}
4651

4752
/**
@@ -74,14 +79,6 @@ public function delete(int $actionId, string $userId): void {
7479
$this->actionsMapper->delete($action);
7580
}
7681

77-
/**
78-
* @param string $userId
79-
* @return ActionStep[]
80-
*/
81-
public function findAllActionSteps(int $actionId, string $userId): array {
82-
return $this->actionStepMapper->findAllStepsForOneAction($actionId, $userId);
83-
}
84-
8582
/**
8683
* @throws DoesNotExistException
8784
*/

src/components/Envelope.vue

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,6 @@ import NoTrashMailboxConfiguredError
479479
from '../errors/NoTrashMailboxConfiguredError.js'
480480
import logger from '../logger.js'
481481
import { buildRecipients as buildReplyRecipients } from '../ReplyBuilder.js'
482-
import { findAllStepsForAction } from '../service/QuickActionsService.js'
483482
import { FOLLOW_UP_TAG_LABEL } from '../store/constants.js'
484483
import useMainStore from '../store/mainStore.js'
485484
import { mailboxHasRights } from '../util/acl.js'
@@ -589,7 +588,6 @@ export default {
589588
customSnoozeDateTime: new Date(moment().add(2, 'hours').minute(0).second(0).valueOf()),
590589
overwriteOneLineMobile: false,
591590
hoveringAvatar: false,
592-
filteredQuickActions: [],
593591
quickActionLoading: false,
594592
}
595593
},
@@ -846,20 +844,36 @@ export default {
846844
},
847845
].filter((option) => option.timestamp !== null)
848846
},
849-
},
850847
851-
watch: {
852-
storeActions() {
853-
this.filterAndEnrichQuickActions()
848+
filteredQuickActions() {
849+
const filteredQuickActions = []
850+
const quickActions = this.mainStore.getQuickActions().filter((action) => action.accountId === this.data.accountId)
851+
for (const action of quickActions) {
852+
const check = action.actionSteps.every((step) => {
853+
if (['markAsSpam', 'applyTag', 'markAsImportant', 'markAsFavorite'].includes(step.name) && !this.hasWriteAcl) {
854+
return false
855+
}
856+
if (['markAsRead', 'markAsUnread'].includes(step.name) && !this.hasSeenAcl) {
857+
return false
858+
}
859+
if (['moveThread', 'deleteThread'].includes(step.name) && !this.hasDeleteAcl) {
860+
return false
861+
}
862+
return true
863+
})
864+
if (check) {
865+
filteredQuickActions.push({
866+
...action,
867+
})
868+
}
869+
}
870+
return filteredQuickActions
854871
},
855872
},
856873
857-
async mounted() {
874+
mounted() {
858875
this.onWindowResize()
859876
window.addEventListener('resize', this.onWindowResize)
860-
if (this.filteredQuickActions.length === 0) {
861-
await this.filterAndEnrichQuickActions()
862-
}
863877
},
864878
865879
methods: {
@@ -874,38 +888,11 @@ export default {
874888
return shortRelativeDatetime(new Date(this.data.dateInt * 1000))
875889
},
876890
877-
async filterAndEnrichQuickActions() {
878-
this.filteredQuickActions = []
879-
const quickActions = this.mainStore.getQuickActions().filter((action) => action.accountId === this.data.accountId)
880-
for (const action of quickActions) {
881-
const steps = await findAllStepsForAction(action.id)
882-
const check = steps.every((step) => {
883-
if (['markAsSpam', 'applyTag', 'markAsImportant', 'markAsFavorite'].includes(step.type) && !this.hasWriteAcl) {
884-
return false
885-
}
886-
if (['markAsRead', 'markAsUnread'].includes(step.type) && !this.hasSeenAcl) {
887-
return false
888-
}
889-
if (['moveThread', 'deleteThread'].includes(step.type) && !this.hasDeleteAcl) {
890-
return false
891-
}
892-
return true
893-
})
894-
if (check) {
895-
this.filteredQuickActions.push({
896-
...action,
897-
steps,
898-
icon: steps[0]?.name,
899-
})
900-
}
901-
}
902-
},
903-
904891
async executeQuickAction(action) {
905892
this.closeQuickActionsMenu()
906893
this.quickActionLoading = true
907894
try {
908-
for (const step of action.steps) {
895+
for (const step of action.actionSteps) {
909896
switch (step.name) {
910897
case 'markAsSpam':
911898
if (this.layoutMessageViewThreaded) {

src/components/quickActions/Settings.vue

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ import TagIcon from 'vue-material-design-icons/TagOutline.vue'
132132
import IconDelete from 'vue-material-design-icons/TrashCanOutline.vue'
133133
import Action from './Action.vue'
134134
import logger from '../../logger.js'
135-
import { createActionStep, deleteActionStep, findAllStepsForAction, updateActionStep } from '../../service/QuickActionsService.js'
135+
import { createActionStep, deleteActionStep, updateActionStep } from '../../service/QuickActionsService.js'
136136
import useMainStore from '../../store/mainStore.js'
137137
138138
export default {
@@ -228,8 +228,8 @@ export default {
228228
this.localAction = { id: null, name: '' }
229229
this.actions = []
230230
} else {
231-
this.localAction = { ...action }
232-
this.actions = await findAllStepsForAction(action.id)
231+
this.localAction = { id: action.id, name: action.name, accountId: action.accountId }
232+
this.actions = action.actionSteps
233233
this.highestOrder = Math.max(...this.actions.map((a) => a.order), 0)
234234
this.editMode = true
235235
}
@@ -260,7 +260,7 @@ export default {
260260
for (const [index, action] of this.actions.entries()) {
261261
if (action?.id !== null && action?.id !== undefined) {
262262
try {
263-
await updateActionStep(action.id, action.name, action.order, action?.tagId, action?.mailboxId)
263+
this.actions[index] = await updateActionStep(action.id, action.name, action.order, action?.tagId, action?.mailboxId)
264264
} catch (error) {
265265
logger.error('Could not update quick action step', {
266266
error,
@@ -273,10 +273,12 @@ export default {
273273
this.actions[index] = createdStep
274274
}
275275
}
276+
this.localAction = quickAction
276277
}
277278
showSuccess(t('mail', 'Quick action updated'))
278279
} else {
279280
let quickAction
281+
const createdSteps = []
280282
try {
281283
quickAction = await this.mainStore.createQuickAction(this.localAction.name, this.account.id)
282284
} catch (error) {
@@ -288,17 +290,23 @@ export default {
288290
}
289291
try {
290292
for (const action of this.actions) {
291-
await createActionStep(action.name, action.order, quickAction.id, action?.tagId, action?.mailboxId)
293+
const createdStep = await createActionStep(action.name, action.order, quickAction.id, action?.tagId, action?.mailboxId)
294+
if (createdStep) {
295+
createdSteps.push(createdStep)
296+
}
292297
}
298+
this.actions = createdSteps
293299
} catch (error) {
294300
logger.error('Could not add step to quick action', {
295301
error,
296302
})
297303
showError(t('mail', 'Failed to add steps to quick action'))
298304
this.closeEditModal()
299305
}
306+
this.localAction = quickAction
300307
showSuccess(t('mail', 'Quick action created'))
301308
}
309+
this.mainStore.patchActionStepsLocally(this.localAction.id, this.actions)
302310
this.closeEditModal()
303311
},
304312
@@ -338,9 +346,13 @@ export default {
338346
},
339347
340348
async deleteAction(item) {
349+
this.actions = this.actions.filter((action) => action.order !== item.order).map((action, index) => ({ ...action, order: index + 1 }))
350+
this.highestOrder = Math.max(...this.actions.map((a) => a.order), 0)
341351
if (item.id) {
342352
try {
343353
await deleteActionStep(item.id)
354+
const actions = this.actions.filter((action) => action.id)
355+
this.mainStore.patchActionStepsLocally(this.localAction.id, actions)
344356
} catch (error) {
345357
logger.error('Could not delete action step', {
346358
error,
@@ -349,8 +361,6 @@ export default {
349361
return
350362
}
351363
}
352-
this.actions = this.actions.filter((action) => action.order !== item.order).map((action, index) => ({ ...action, order: index + 1 }))
353-
this.highestOrder = Math.max(...this.actions.map((a) => a.order), 0)
354364
},
355365
},
356366
}

src/service/QuickActionsService.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,6 @@ export async function deleteQuickAction(id) {
4040
})
4141
}
4242

43-
export async function findAllStepsForAction(actionId) {
44-
const url = generateUrl('/apps/mail/api/action-step/{id}/steps', { id: actionId })
45-
return handleHttpAuthErrors(async () => {
46-
const response = await axios.get(url)
47-
return response.data.data
48-
})
49-
}
50-
5143
export async function createActionStep(name, order, actionId, tagId = null, mailboxId = null) {
5244
const url = generateUrl('/apps/mail/api/action-step')
5345
return handleHttpAuthErrors(async () => {

src/store/mainStore/actions.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2322,6 +2322,14 @@ export default function mainStoreActions() {
23222322
Vue.set(this.quickActions, index, quickAction)
23232323
}
23242324
},
2325+
patchActionStepsLocally(id, steps) {
2326+
const index = this.quickActions.findIndex((s) => s.id === id)
2327+
if (index !== -1) {
2328+
const updatedQuickAction = this.quickActions[index]
2329+
updatedQuickAction.actionSteps = steps
2330+
Vue.set(this.quickActions, index, updatedQuickAction)
2331+
}
2332+
},
23252333
deleteQuickActionLocally(id) {
23262334
const index = this.quickActions.findIndex((s) => s.id === id)
23272335
if (index !== -1) {

0 commit comments

Comments
 (0)