Skip to content

Commit b488fd7

Browse files
fix: replying to email fails after sorting a large grid
refs #270
1 parent 105106f commit b488fd7

File tree

2 files changed

+150
-45
lines changed

2 files changed

+150
-45
lines changed

src/app/PackageController.js

+54-22
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ Ext.define("conjoon.cn_mail.app.PackageController", {
183183
"cn_mail-mailmessagegridbeforeload": "onMailMessageGridBeforeLoad",
184184
"cn_mail-mailmessagegridload": "onMailMessageGridLoad"
185185
},
186+
"cn_mail-maildesktopview > cn_mail-mailinboxview cn_mail-mailmessagereadermessageview": {
187+
"cn_mail-messageviewitemchange": "onMailMessageViewItemChange"
188+
},
186189
"cn_navport-tbar > #cn_mail-nodeNavCreateMessage": {
187190
click: "onMessageComposeButtonClick"
188191
},
@@ -221,6 +224,9 @@ Ext.define("conjoon.cn_mail.app.PackageController", {
221224
}, {
222225
ref: "mailInboxView",
223226
selector: "cn_mail-maildesktopview > cn_mail-mailinboxview"
227+
}, {
228+
ref: "mailInboxMessageView",
229+
selector: "cn_mail-maildesktopview > cn_mail-mailinboxview cn_mail-mailmessagereadermessageview"
224230
}, {
225231
ref: "mailMessageGrid",
226232
selector: "cn_mail-maildesktopview > cn_mail-mailinboxview > panel > container > cn_mail-mailmessagegrid"
@@ -675,6 +681,16 @@ Ext.define("conjoon.cn_mail.app.PackageController", {
675681
},
676682

677683

684+
onMailMessageViewItemChange (messageView, messageItem) {
685+
const me = this;
686+
// unloaded. disable context buttons, since this most likely means the
687+
// selection in the sibling grid is lost
688+
// (The vm of the MessageView is bound to the selection of the grid)
689+
if (!messageItem) {
690+
me.disableMessageItemContextButtons(true);
691+
}
692+
} ,
693+
678694
disableMessageItemContextButtons (disable) {
679695
const me = this;
680696
me.disableEmailActionButtons(disable);
@@ -873,20 +889,28 @@ Ext.define("conjoon.cn_mail.app.PackageController", {
873889
*/
874890
onMessageDeleteButtonClick (btn) {
875891
const me = this,
876-
item = me.getItemOrDraftFromActiveView();
892+
item = me.getDraftOrItemFromActiveView();
877893

878-
if (item === null) {
879-
Ext.raise("Unexpected null-value for item.");
894+
if (!item) {
895+
console.error ("no item found that could be referenced");
896+
return;
880897
}
881898

899+
me.moveOrDeleteMessage(item);
900+
901+
return true;
902+
},
903+
904+
moveOrDeleteMessage (item) {
905+
const me = this;
906+
882907
me.getMailInboxView().getController().moveOrDeleteMessage(
883908
item,
884909
false,
885910
me.getMailDesktopView().getActiveTab()
886911
);
887912
},
888913

889-
890914
/**
891915
* Callback for the node navigation's "replyTo message button".
892916
*
@@ -1148,44 +1172,51 @@ Ext.define("conjoon.cn_mail.app.PackageController", {
11481172
*
11491173
* @return {null|conjoon.cn_mail.model.mail.message.AbstractMessageItem}
11501174
*/
1151-
getItemOrDraftFromActiveView () {
1175+
getDraftOrItemFromActiveView () {
11521176

11531177
const me = this,
11541178
tab = me.getMailDesktopView().getActiveTab();
11551179

11561180
if (tab instanceof conjoon.cn_mail.view.mail.message.editor.MessageEditor) {
11571181
return tab.getMessageDraft();
1158-
} else if (tab instanceof conjoon.cn_mail.view.mail.message.reader.MessageView) {
1159-
return tab.getMessageItem();
1160-
} else if (tab === me.getMailInboxView()) {
1161-
return me.getMailMessageGrid().getSelection()[0];
11621182
}
11631183

1164-
return null;
1184+
return me.getItemFromGridOrMessageView();
11651185
},
11661186

11671187

1188+
getItemFromGridOrMessageView () {
1189+
const
1190+
me = this,
1191+
tab = me.getMailDesktopView().getActiveTab();
1192+
1193+
if (tab instanceof conjoon.cn_mail.view.mail.message.reader.MessageView) {
1194+
return tab.getMessageItem();
1195+
} else if (tab === me.getMailInboxView()) {
1196+
if (me.getMailMessageGrid().getSelection()) {
1197+
return me.getMailMessageGrid().getSelection()[0];
1198+
}
1199+
return me.getMailInboxMessageView().getMessageItem();
1200+
}
1201+
},
1202+
11681203
/**
11691204
* Helper function to retrieve the compound key of the selected record in
1170-
* the MessageGrid in the InboxView OR of the MessageItem of a MessageView,
1205+
* the InboxView's MessageGrid, MessageView OR of the MessageItem of a MailDesktopView's MessageView,
11711206
* depending on which tab is currently active in the MailDesktopView.
1207+
* The method will first query the MailDesktopView, then the embedded InboxView.
11721208
*
11731209
* @return {conjoon.cn_mail.data.mail.message.compoundKey.MessageEntityCompoundKey}
11741210
*
11751211
* @private
11761212
*/
11771213
getCompoundKeyFromGridOrMessageView () {
11781214

1179-
const me = this,
1180-
tab = me.getMailDesktopView().getActiveTab();
1181-
1182-
if (tab instanceof conjoon.cn_mail.view.mail.message.reader.MessageView) {
1183-
return tab.getMessageItem().getCompoundKey();
1184-
} else if (tab === me.getMailInboxView()) {
1185-
return me.getMailMessageGrid().getSelection()[0].getCompoundKey();
1186-
}
1215+
const
1216+
me = this,
1217+
item = me.getItemFromGridOrMessageView ();
11871218

1188-
return null;
1219+
return item?.getCompoundKey();
11891220
},
11901221

11911222

@@ -1238,14 +1269,15 @@ Ext.define("conjoon.cn_mail.app.PackageController", {
12381269

12391270
if (type !== "compose" &&
12401271
!(key instanceof conjoon.cn_mail.data.mail.message.compoundKey.MessageEntityCompoundKey)) {
1241-
Ext.raise({
1272+
console.error ({
12421273
msg: "anything but \"compose\" expects an instance of conjoon.cn_mail.data.mail.message.compoundKey.MessageEntityCompoundKey",
12431274
key: key,
12441275
type: type
12451276
});
1277+
return;
12461278
}
12471279

1248-
mailDesktopView.showMailEditor(key, type);
1280+
return mailDesktopView.showMailEditor(key, type);
12491281
}
12501282

12511283
},

tests/src/app/PackageControllerTest.js

+96-23
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ StartTest(async t => {
110110
packageCtrl = Ext.create("conjoon.cn_mail.app.PackageController");
111111
t.expect(packageCtrl instanceof coon.core.app.PackageController).toBe(true);
112112

113+
t.expect(packageCtrl.getControl()["cn_mail-maildesktopview > cn_mail-mailinboxview cn_mail-mailmessagereadermessageview"]).toEqual(
114+
{"cn_mail-messageviewitemchange": "onMailMessageViewItemChange"}
115+
);
116+
113117
t.expect(conjoon.cn_mail.app.PackageController.required).toEqual({
114118
mailAccountHandler: "conjoon.cn_mail.view.mail.account.MailAccountHandler"
115119
});
@@ -258,6 +262,7 @@ StartTest(async t => {
258262
t.it("showMailEditor()", t => {
259263

260264
let CN_HREF = "foo";
265+
const FAKE_EDITOR = {};
261266

262267
packageCtrl = Ext.create("conjoon.cn_mail.app.PackageController");
263268
let mvp = {
@@ -267,6 +272,7 @@ StartTest(async t => {
267272
};
268273
},
269274
showMailEditor: function () {
275+
return FAKE_EDITOR;
270276
}
271277
};
272278
packageCtrl.getMainPackageView = function () {
@@ -275,13 +281,9 @@ StartTest(async t => {
275281

276282
t.isCalledNTimes("showMailEditor", mvp, 1);
277283

278-
packageCtrl.showMailEditor("a", "compose");
284+
t.expect(packageCtrl.showMailEditor("a", "compose")).toBe(FAKE_EDITOR);
279285

280-
let exc;
281-
try {packageCtrl.showMailEditor();}catch(e){exc=e;}
282-
t.expect(exc).toBeDefined();
283-
t.expect(exc.msg).toBeDefined();
284-
t.expect(exc.msg.toLowerCase()).toContain("expects an instance");
286+
t.expect(packageCtrl.showMailEditor()).toBeUndefined();
285287

286288
});
287289

@@ -407,7 +409,7 @@ StartTest(async t => {
407409
};
408410
};
409411

410-
packageCtrl.getItemOrDraftFromActiveView = function () {
412+
packageCtrl.getDraftOrItemFromActiveView = function () {
411413
return "foo";
412414
};
413415

@@ -1332,9 +1334,22 @@ StartTest(async t => {
13321334
packageCtrl = Ext.create("conjoon.cn_mail.app.PackageController");
13331335

13341336
let activeTab = null,
1337+
mailInboxMessageView,
13351338
COMPOUNDKEY = MessageEntityCompoundKey.createFor(
13361339
1, 2, 3), SETKEY = null;
13371340

1341+
let FAKE_MESSAGE_ITEM = {
1342+
getCompoundKey: function () {
1343+
return COMPOUNDKEY;
1344+
}
1345+
};
1346+
1347+
let SELECTION = [FAKE_MESSAGE_ITEM];
1348+
let FAKE_MAIL_MESSAGE_GRID = {
1349+
getSelection () {
1350+
return SELECTION;
1351+
}
1352+
};
13381353
packageCtrl.getMailDesktopView = function () {
13391354
return {
13401355
getActiveTab: function () {
@@ -1353,22 +1368,51 @@ StartTest(async t => {
13531368

13541369
activeTab = Ext.create("conjoon.cn_mail.view.mail.message.reader.MessageView");
13551370
activeTab.getMessageItem = function () {
1356-
return {
1357-
getCompoundKey: function () {
1358-
return COMPOUNDKEY;
1359-
}
1360-
};
1371+
return FAKE_MESSAGE_ITEM;
13611372
};
13621373
packageCtrl.getMailInboxView = function () {
13631374
return activeTab;
13641375
};
1376+
mailInboxMessageView = Ext.create("conjoon.cn_mail.view.mail.message.reader.MessageView");
1377+
mailInboxMessageView.getMessageItem = function () {
1378+
return FAKE_MESSAGE_ITEM;
1379+
};
1380+
packageCtrl.getMailInboxMessageView = function () {
1381+
return mailInboxMessageView;
1382+
};
1383+
1384+
t.isCalledNTimes("getCompoundKeyFromGridOrMessageView", packageCtrl, 3);
1385+
t.isCalledNTimes("getMailInboxMessageView", packageCtrl, 1);
1386+
1387+
// return item from MailDesktopView's active MessageView
1388+
t.expect(SETKEY).toBe(null);
1389+
packageCtrl.onMessageEditButtonClick();
1390+
t.expect(SETKEY).toBe(COMPOUNDKEY);
13651391

1366-
t.isCalledOnce("getCompoundKeyFromGridOrMessageView", packageCtrl);
13671392

1393+
// return MessageItem from MessageGrid
1394+
packageCtrl.getMailMessageGrid = function () {
1395+
return FAKE_MAIL_MESSAGE_GRID;
1396+
};
1397+
let selectionSpy = t.spyOn(FAKE_MAIL_MESSAGE_GRID, "getSelection");
1398+
activeTab = null;
1399+
SETKEY = null;
1400+
t.expect(SETKEY).toBe(null);
1401+
packageCtrl.onMessageEditButtonClick();
1402+
t.expect(selectionSpy.calls.count()).toBe(2);
1403+
t.expect(SETKEY).toBe(COMPOUNDKEY);
1404+
1405+
// selection = null
1406+
// returns messageItem from MessageView embedded in MailInboxView
1407+
SELECTION = null;
1408+
activeTab = null;
1409+
SETKEY = null;
13681410
t.expect(SETKEY).toBe(null);
13691411
packageCtrl.onMessageEditButtonClick();
1412+
t.expect(selectionSpy.calls.count()).toBe(3);
13701413
t.expect(SETKEY).toBe(COMPOUNDKEY);
13711414

1415+
selectionSpy.remove();
13721416
});
13731417
});
13741418

@@ -1514,7 +1558,7 @@ StartTest(async t => {
15141558
});
15151559

15161560

1517-
t.it("getItemOrDraftFromActiveView()", t => {
1561+
t.it("getDraftOrItemFromActiveView()", t => {
15181562

15191563
let ACTIVETAB = "";
15201564

@@ -1544,17 +1588,16 @@ StartTest(async t => {
15441588
messageDraft: 1
15451589
});
15461590
ACTIVETAB.getMessageDraft = function () { return 1;};
1547-
t.expect(packageCtrl.getItemOrDraftFromActiveView()).toBe(1);
1548-
1549-
ACTIVETAB = Ext.create("conjoon.cn_mail.view.mail.message.reader.MessageView");
1550-
ACTIVETAB.getMessageItem = function () { return 2;};
1551-
t.expect(packageCtrl.getItemOrDraftFromActiveView()).toBe(2);
1591+
t.expect(packageCtrl.getDraftOrItemFromActiveView()).toBe(1);
15521592

1553-
ACTIVETAB = 3;
1554-
t.expect(packageCtrl.getItemOrDraftFromActiveView()).toBe(4);
1593+
const getItemFromGridOrMessageViewSpy = t.spyOn(
1594+
packageCtrl, "getItemFromGridOrMessageView").and.callFake(() => ({}));
1595+
ACTIVETAB = {};
1596+
t.expect(packageCtrl.getDraftOrItemFromActiveView()).toBe(
1597+
getItemFromGridOrMessageViewSpy.calls.mostRecent().returnValue
1598+
);
15551599

1556-
ACTIVETAB = 4;
1557-
t.expect(packageCtrl.getItemOrDraftFromActiveView()).toBe(null);
1600+
getItemFromGridOrMessageViewSpy.remove();
15581601
});
15591602

15601603

@@ -1914,5 +1957,35 @@ StartTest(async t => {
19141957

19151958
});
19161959

1960+
t.it("onMailMessageViewItemChange", t => {
1961+
1962+
packageCtrl = Ext.create("conjoon.cn_mail.app.PackageController");
1963+
1964+
const contextSpy = t.spyOn(packageCtrl, "disableMessageItemContextButtons").and.callFake(() => {});
1965+
1966+
packageCtrl.onMailMessageViewItemChange ({}, null);
1967+
t.expect(contextSpy.calls.mostRecent().args[0]).toBe(true);
1968+
1969+
packageCtrl.onMailMessageViewItemChange ({}, {});
1970+
t.expect(contextSpy.calls.count()).toBe(1);
1971+
});
1972+
1973+
1974+
t.it("onMessageDeleteButtonClick", t => {
1975+
1976+
packageCtrl = Ext.create("conjoon.cn_mail.app.PackageController");
1977+
1978+
let DRAFT = null;
1979+
const draftSpy = t.spyOn(packageCtrl, "getDraftOrItemFromActiveView").and.callFake(() => DRAFT);
1980+
const moveSpy = t.spyOn(packageCtrl, "moveOrDeleteMessage").and.callFake(() => {});
1981+
1982+
t.expect(packageCtrl.onMessageDeleteButtonClick()).toBeUndefined();
1983+
DRAFT = {};
1984+
t.expect(moveSpy.calls.count()).toBe(0);
1985+
t.expect(packageCtrl.onMessageDeleteButtonClick()).toBe(true);
1986+
t.expect(moveSpy.calls.mostRecent().args[0]).toBe(DRAFT);
1987+
[draftSpy, moveSpy].map(spy => spy.remove());
1988+
});
1989+
19171990

19181991
});});});

0 commit comments

Comments
 (0)