-
-
-
-
-
+ this.getContentNode(id));
+ const orderedNodes = selectedNodes.sort(this.compareNodeTitles);
+
+ const reversedNodes = orderedNodes.reverse();
+
+ const nodeX = this.findNodeBeforeFirstSelected(orderedNodes, selected);
+
+ const targetParent = this.node.id;
+ const targetNode = nodeX || targetParent;
+ const targetPosition = nodeX
+ ? RELATIVE_TREE_POSITIONS.RIGHT
+ : RELATIVE_TREE_POSITIONS.FIRST_CHILD;
+
+ const nodeIdsToMove = reversedNodes.map(node => String(node.id));
+
+ this.moveContentNodes({
+ id__in: nodeIdsToMove,
+ target: targetNode,
+ position: targetPosition,
+ });
+ },
+
+ findNodeBeforeFirstSelected(nodes, selected) {
+ for (let i = 1; i < nodes.length; i++) {
+ if (selected.includes(nodes[i])) {
+ return nodes[i - 1];
+ }
+ }
+ return null;
+ },
+
+ compareNodeTitles(nodeA, nodeB) {
+ const titleA = nodeA.title.toLowerCase();
+ const titleB = nodeB.title.toLowerCase();
+ return titleA.localeCompare(titleB);
+ },
updateTitleForPage() {
let detailTitle;
const topicTitle = this.getTitle(this.getContentNode(this.topicId));
@@ -707,6 +751,7 @@
},
$trs: {
addTopic: 'New folder',
+ SortAlphabetically: 'Sort alphabetically',
addExercise: 'New exercise',
uploadFiles: 'Upload files',
importFromChannels: 'Import from channels',
diff --git a/contentcuration/contentcuration/frontend/channelEdit/views/trash/__tests__/trashModal.spec.js b/contentcuration/contentcuration/frontend/channelEdit/views/trash/__tests__/trashModal.spec.js
index 63130d7bd1..3e27f3924e 100644
--- a/contentcuration/contentcuration/frontend/channelEdit/views/trash/__tests__/trashModal.spec.js
+++ b/contentcuration/contentcuration/frontend/channelEdit/views/trash/__tests__/trashModal.spec.js
@@ -90,9 +90,12 @@ describe('trashModal', () => {
wrapper.find('[data-test="item"]').trigger('click');
expect(wrapper.vm.previewNodeId).toBe(testChildren[0].id);
});
- it('checking item in list should set selected', () => {
- wrapper.find('[data-test="checkbox"]').vm.$emit('change', ['selected']);
- expect(wrapper.vm.selected).toEqual(['selected']);
+ it('checking item in list should add the item ID to the selected array', () => {
+ wrapper
+ .find('[data-test="checkbox"]')
+ .find('input[type="checkbox"]')
+ .element.click();
+ expect(wrapper.vm.selected).toEqual(['test1']);
});
it('checking select all checkbox should check all items', () => {
wrapper.find('[data-test="selectall"]').vm.$emit('change', true);
diff --git a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/ChannelSelectionList.vue b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/ChannelSelectionList.vue
index 05b5ca4eee..f268ecb7f5 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/ChannelSelectionList.vue
+++ b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/ChannelSelectionList.vue
@@ -23,7 +23,7 @@
diff --git a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSelectionList.spec.js b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSelectionList.spec.js
index b3d88ee0fb..efdcbf96f5 100644
--- a/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSelectionList.spec.js
+++ b/contentcuration/contentcuration/frontend/channelList/views/ChannelSet/__tests__/channelSelectionList.spec.js
@@ -60,13 +60,17 @@ describe('channelSelectionList', () => {
});
it('should select channels when the channel has been checked', () => {
wrapper.setData({ loading: false });
- wrapper.find('[data-test="checkbox"]').vm.$emit('change', [editChannel.id]);
+ wrapper.find(`[data-test="checkbox-${editChannel.id}"]`).element.click();
+
expect(wrapper.emitted('input')[0][0]).toEqual([editChannel.id]);
});
it('should deselect channels when the channel has been unchecked', () => {
wrapper.setData({ loading: false });
- wrapper.find('[data-test="checkbox"]').vm.$emit('change', []);
- expect(wrapper.emitted('input')[0][0]).toEqual([]);
+ wrapper.find(`[data-test="checkbox-${editChannel.id}"]`).element.click(); // Check the channel
+ wrapper.find(`[data-test="checkbox-${editChannel.id}"]`).element.click(); // Uncheck the channel
+
+ expect(wrapper.emitted('input')[0].length).toEqual(1); // Only one event should be emitted (corresponding to the initial check)
+ expect(wrapper.emitted('input')[0][0]).toEqual([editChannel.id]); // The initial check event should be emitted
});
it('should filter channels based on the search text', () => {
wrapper.setData({ loading: false, search: searchWord });
diff --git a/contentcuration/contentcuration/frontend/shared/data/broadcastChannel.js b/contentcuration/contentcuration/frontend/shared/data/broadcastChannel.js
deleted file mode 100644
index 6d42c42811..0000000000
--- a/contentcuration/contentcuration/frontend/shared/data/broadcastChannel.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { APP_ID } from './constants';
-
-const { BroadcastChannel } = require('broadcast-channel');
-
-// N.B. channels do not subscribe to messages that
-// they send, so if you want to listen to all messages
-// sent on a channel, even from the same window
-// you have to create a new channel object instance.
-export function createChannel(id = APP_ID) {
- return new BroadcastChannel(id);
-}
-
-const channel = createChannel();
-
-export default channel;
diff --git a/contentcuration/contentcuration/frontend/shared/views/ResizableNavigationDrawer.vue b/contentcuration/contentcuration/frontend/shared/views/ResizableNavigationDrawer.vue
index a0c817f2dd..28801fefda 100644
--- a/contentcuration/contentcuration/frontend/shared/views/ResizableNavigationDrawer.vue
+++ b/contentcuration/contentcuration/frontend/shared/views/ResizableNavigationDrawer.vue
@@ -37,6 +37,10 @@
type: Number,
default: 100,
},
+ defaultWidth: {
+ type: Number,
+ default: 150,
+ },
maxWidth: {
type: Number,
default: window.innerWidth - 100,
@@ -68,7 +72,7 @@
const localStorageName = this.localName + '-drawer-width';
return {
dragging: false,
- width: parseFloat(localStorage[localStorageName]) || this.minWidth,
+ width: parseFloat(localStorage[localStorageName]) || this.defaultWidth || this.minWidth,
localStorageName,
};
},
diff --git a/contentcuration/contentcuration/frontend/shared/views/form/Checkbox.vue b/contentcuration/contentcuration/frontend/shared/views/form/Checkbox.vue
index f137545c48..fab75de77f 100644
--- a/contentcuration/contentcuration/frontend/shared/views/form/Checkbox.vue
+++ b/contentcuration/contentcuration/frontend/shared/views/form/Checkbox.vue
@@ -1,21 +1,138 @@
+
+
+
+
+
+
+
+