Skip to content

Commit 03fba17

Browse files
update api.factory.js based on updated
activedTabsHistory.js
1 parent 79dfdbd commit 03fba17

File tree

4 files changed

+111
-55
lines changed

4 files changed

+111
-55
lines changed

src/useDynamicTabs/useDynamicTabs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ function useDynamicTabs(getDeps, options = {}) {
2828
}, []);
2929
useLayoutEffect(() => {
3030
const oldState = api.getCopyPerviousData(),
31-
[openedTabsId, closedTabsId] = api.helper.getArraysDiff(state.openTabIDs, oldState.openTabIDs),
31+
[openedTabIDs, closeTabIDs] = api.helper.getArraysDiff(state.openTabIDs, oldState.openTabIDs),
3232
isSwitched = oldState.selectedTabID !== state.selectedTabID;
33-
api.onChange({newState: state, oldState, closedTabsId, openedTabsId, isSwitched});
33+
api.onChange({newState: state, oldState, closeTabIDs, openedTabIDs, isSwitched});
3434
}, [state]);
3535
useLayoutEffect(() => {
3636
api.trigger('_onFlushEffects', api.userProxy, {currentData: api.getCopyData(), instance: api.userProxy});

src/utils/api/api.factory.js

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,13 @@ const _apiProps = {
5151
return this;
5252
},
5353
_subscribeSelectedTabsHistory: function () {
54-
this.on('onChange', ({currentData, perviousData}) => {
54+
this.on('onChange', ({currentData, perviousData, closeTabIDs}) => {
55+
for (let i = 0, l = closeTabIDs.length; i < l; i++) {
56+
this.activedTabsHistory.remove(closeTabIDs[i]);
57+
}
5558
const isSwitched = perviousData.selectedTabID !== currentData.selectedTabID;
56-
isSwitched && this.activedTabsHistory.add(perviousData.selectedTabID);
59+
if (isSwitched && this.isOpen(perviousData.selectedTabID) && !this.isSelected(perviousData.selectedTabID))
60+
this.activedTabsHistory.add(perviousData.selectedTabID);
5761
});
5862
return this;
5963
},
@@ -98,37 +102,37 @@ const _apiProps = {
98102
this._select(id);
99103
return result;
100104
},
101-
_findTabIdForSwitching: (function () {
102-
const _findOpenedAndNoneDisableTabId = function (tabsIdArr, isRightToLeft) {
103-
return (
104-
this.helper.arrFilterUntilFirstValue(
105-
tabsIdArr,
106-
(id) => this.isOpen(id) && !this.getTab(id).disable && !this.isSelected(id),
107-
isRightToLeft,
108-
) || ''
109-
);
110-
},
111-
_getPreSelectedTabId = function () {
112-
return _findOpenedAndNoneDisableTabId.call(this, [...this.activedTabsHistory.tabsId], true);
113-
},
114-
_getPreSiblingTabId = function () {
115-
const data = this.stateRef,
116-
arr = data.openTabIDs;
117-
return _findOpenedAndNoneDisableTabId.call(this, arr.slice(0, arr.indexOf(data.selectedTabID)), true);
118-
},
119-
_getNextSiblingTabId = function () {
120-
const data = this.stateRef,
121-
arr = data.openTabIDs;
122-
return _findOpenedAndNoneDisableTabId.call(this, arr.slice(arr.indexOf(data.selectedTabID) + 1));
123-
};
124-
return function () {
125-
let tabId = '';
126-
tabId = _getPreSelectedTabId.call(this);
127-
tabId = tabId || _getPreSiblingTabId.call(this);
128-
tabId = tabId || _getNextSiblingTabId.call(this);
129-
return tabId;
130-
};
131-
})(),
105+
_getPreSelectedTabId: function () {
106+
const selectedTabHistory = this.activedTabsHistory;
107+
let tabID = '';
108+
while (!tabID && selectedTabHistory.tabsId.length) {
109+
const _tabID = selectedTabHistory.popLastTabID();
110+
if (_tabID) {
111+
const _tabData = this.getTab(_tabID);
112+
if (_tabData && !_tabData.disable && this.isOpen(_tabID) && !this.isSelected(_tabID)) tabID = _tabID;
113+
}
114+
}
115+
return tabID;
116+
},
117+
_getPreSiblingTabId: function () {
118+
const {selectedTabID, openTabIDs} = this.stateRef;
119+
const isRightToLeft = true;
120+
const arr = openTabIDs.slice(0, openTabIDs.indexOf(selectedTabID));
121+
return this.helper.filterArrayUntilFirstValue(arr, (id) => !this.getTab(id).disable, isRightToLeft);
122+
},
123+
_getNextSiblingTabId: function () {
124+
const {selectedTabID, openTabIDs} = this.stateRef;
125+
const isRightToLeft = false;
126+
const arr = openTabIDs.slice(openTabIDs.indexOf(selectedTabID) + 1);
127+
return this.helper.filterArrayUntilFirstValue(arr, (id) => !this.getTab(id).disable, isRightToLeft);
128+
},
129+
_findTabIdForSwitching: function () {
130+
let tabId = '';
131+
tabId = this._getPreSelectedTabId();
132+
tabId = tabId || this._getPreSiblingTabId();
133+
tabId = tabId || this._getNextSiblingTabId();
134+
return tabId || '';
135+
},
132136
setTab: function (id, newData = {}) {
133137
this.optionsManager.validateObjectiveTabData(newData).validatePanelComponent(newData);
134138
this._setTab(id, newData);
@@ -163,28 +167,16 @@ const _apiProps = {
163167
},
164168
};
165169
Helper.setNoneEnumProps(_apiProps, {
166-
// getInitialState: function () {
167-
// if (!this._initialState) {
168-
// const { selectedTabID, tabs, defaultPanelComponent } = this.optionsManager.options, openTabIDs = [];
169-
// tabs.map(tab => {
170-
// const newTab = this._addTab(tab, { defaultPanelComponent });
171-
// openTabIDs.push(newTab.id);
172-
// });
173-
// this._initialState = {
174-
// selectedTabID: selectedTabID + '', //make sure it is type of string
175-
// openTabIDs
176-
// };
177-
// }
178-
// return this._initialState;
179-
// },
180-
onChange: function ({newState, oldState, closedTabsId, openedTabsId, isSwitched}) {
181-
if (isSwitched || openedTabsId.length || closedTabsId.length) {
170+
onChange: function ({newState, oldState, closeTabIDs, openedTabIDs, isSwitched}) {
171+
if (isSwitched || openedTabIDs.length || closeTabIDs.length) {
182172
this.trigger('onChange', this.userProxy, {
183173
currentData: {...newState},
184174
perviousData: {...oldState},
175+
closeTabIDs,
176+
openedTabIDs,
185177
});
186-
openedTabsId.length && this.trigger('onOpen', this.userProxy, openedTabsId);
187-
closedTabsId.length && this.trigger('onClose', this.userProxy, closedTabsId);
178+
openedTabIDs.length && this.trigger('onOpen', this.userProxy, openedTabIDs);
179+
closeTabIDs.length && this.trigger('onClose', this.userProxy, closeTabIDs);
188180
isSwitched &&
189181
this.trigger('onSelect', this.userProxy, {
190182
currentSelectedTabId: newState.selectedTabID,

src/utils/api/api.factory.test.js

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ describe('context of callback options should be userProxy object : ', () => {
323323
};
324324
const obj = new apiConstructor(getDeps, {options});
325325
expect(options.onChange.mock.calls.length === 0).toBe(true);
326-
obj.trigger('onChange', obj.userProxy, {currentData: {}, perviousData: {}});
326+
obj.trigger('onChange', obj.userProxy, {currentData: {}, perviousData: {}, closeTabIDs: [], openTabIDs: []});
327327
expect(options.onChange.mock.calls.length === 1).toBe(true);
328328
});
329329
});
@@ -464,3 +464,67 @@ describe('Api.prototype.setTab : ', () => {
464464
);
465465
});
466466
});
467+
describe('Api.prototype._subscribeSelectedTabsHistory : ', () => {
468+
test('it should call "on" method', () => {
469+
obj.on = jest.fn(() => {});
470+
obj._subscribeSelectedTabsHistory();
471+
expect(obj.on.mock.calls.length).toBe(1);
472+
expect(obj.on.mock.calls[0][0]).toBe('onChange');
473+
});
474+
test('subscribed function should call activedTabsHistory.remove per each closed tabID when onChange event is triggered', () => {
475+
obj.activedTabsHistory.remove = jest.fn(() => {});
476+
const currentData = {selectedTabID: '2', openTabIDs: ['2']};
477+
const perviousData = {selectedTabID: '2', openTabIDs: ['2']};
478+
const closeTabIDs = ['1', '3'];
479+
obj.trigger('onChange', obj.userProxy, {currentData, perviousData, closeTabIDs, openTabIDs: []});
480+
expect(obj.activedTabsHistory.remove.mock.calls.length).toBe(2);
481+
expect(obj.activedTabsHistory.remove.mock.calls[0][0]).toBe('1');
482+
expect(obj.activedTabsHistory.remove.mock.calls[1][0]).toBe('3');
483+
});
484+
test(`when onChange event is triggered, subscribed function should call activedTabsHistory.add with
485+
previously selectedTabID as a parameter if it is open, not selected and none disable.`, () => {
486+
obj.activedTabsHistory.add = jest.fn(() => {});
487+
obj.isOpen = jest.fn((id) => {
488+
if (id === '1' || id === '2') return true;
489+
return false;
490+
});
491+
obj.isSelected = jest.fn((id) => {
492+
if (id === '2') return true;
493+
return false;
494+
});
495+
const currentData = {selectedTabID: '2', openTabIDs: ['1', '2']};
496+
const perviousData = {selectedTabID: '1', openTabIDs: ['1', '2']};
497+
obj.trigger('onChange', obj.userProxy, {currentData, perviousData, closeTabIDs: [], openTabIDs: []});
498+
expect(obj.activedTabsHistory.add.mock.calls.length).toBe(1);
499+
expect(obj.activedTabsHistory.add.mock.calls[0][0]).toBe('1');
500+
});
501+
});
502+
describe('Api.prototype._getPreSelectedTabId : ', () => {
503+
test(`it calls activeTabsHistory.popLastTabID repeatedly until it returns a tabID
504+
which is opened, not selected and none disable`, () => {
505+
const obj = new apiConstructor(getDeps, {
506+
options: {
507+
tabs: [{id: '1'}, {id: '2'}, {id: '3'}, {id: '4'}, {id: '5'}],
508+
selectedTabID: 'tab1',
509+
},
510+
});
511+
obj.stateRef = {selectedTabID: '1', openTabIDs: ['1', '2', '3', '4']};
512+
obj.activedTabsHistory.tabsId = ['3', '2', '1', '3', '1', '3', '4', '5'];
513+
obj.setTab('3', {disable: true}).setTab('4', {disable: true});
514+
const tabID = obj._getPreSelectedTabId();
515+
expect(tabID).toBe('2');
516+
expect(obj.activedTabsHistory.tabsId).toEqual(['3']);
517+
});
518+
test('it should return an empty string if activedTabsHistory.tabsId is empty or does not contain any valid tabID', () => {
519+
obj.stateRef = {selectedTabID: 'tab1', openTabIDs: ['tab1', 'tab2']};
520+
expect(obj._getPreSelectedTabId()).toBe('');
521+
obj.activedTabsHistory.tabsId = ['tab1'];
522+
expect(obj._getPreSelectedTabId()).toBe('');
523+
obj.activedTabsHistory.tabsId = ['tab1', ' ', '', null, 'tab2'];
524+
obj.setTab('tab2', {disable: true});
525+
expect(obj._getPreSelectedTabId()).toBe('');
526+
obj.activedTabsHistory.tabsId = ['tab1', 'tab2'];
527+
obj.setTab('tab2', {disable: false});
528+
expect(obj._getPreSelectedTabId()).toBe('tab2');
529+
});
530+
});

src/utils/helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ helper.getArraysDiff = function (arr1, arr2) {
4747
});
4848
return [arr1Copy, arr2Copy];
4949
};
50-
helper.arrFilterUntilFirstValue = (arr, callback, isRightToLeft) => {
50+
helper.filterArrayUntilFirstValue = (arr, callback, isRightToLeft) => {
5151
isRightToLeft && arr.reverse();
5252
for (let i = 0, l = arr.length; i < l; i++) if (callback(arr[i], i, arr)) return arr[i];
5353
return null;

0 commit comments

Comments
 (0)