Skip to content

Commit fd9d25a

Browse files
authored
Merge pull request #4853 from learningequality/hotfixes
Merge down hotfixes into unstable
2 parents 86c89d5 + 161a0b4 commit fd9d25a

File tree

24 files changed

+521
-129
lines changed

24 files changed

+521
-129
lines changed

contentcuration/contentcuration/apps.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ class ContentConfig(AppConfig):
88
name = 'contentcuration'
99

1010
def ready(self):
11+
# Import signals
12+
import contentcuration.signals # noqa
13+
1114
if settings.AWS_AUTO_CREATE_BUCKET and not is_gcs_backend():
1215
from contentcuration.utils.minio_utils import ensure_storage_bucket_public
1316
ensure_storage_bucket_public()

contentcuration/contentcuration/frontend/channelEdit/components/move/MoveModal.vue

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@
9898
<VDivider v-if="index < children.length - 1" :key="`move-divider-${node.id}`" />
9999
</template>
100100
</VList>
101+
<div class="show-more-button-container">
102+
<KButton v-if="more" :disabled="moreLoading" @click="loadMore">
103+
{{ showMoreLabel }}
104+
</KButton>
105+
</div>
101106
</VFlex>
102107
<ResourceDrawer
103108
:nodeId="previewNodeId"
@@ -146,6 +151,13 @@
146151
import Thumbnail from 'shared/views/files/Thumbnail';
147152
import { ContentKindsNames } from 'shared/leUtils/ContentKinds';
148153
import { titleMixin } from 'shared/mixins';
154+
import { createTranslator } from 'shared/i18n';
155+
156+
// Can't use cross component translator to get the NodePanel translations
157+
// here, because the NodePanel component imports this component.
158+
const showMoreTranslator = createTranslator('NodePanel', {
159+
showMore: 'Show more',
160+
});
149161
150162
export default {
151163
name: 'MoveModal',
@@ -182,6 +194,8 @@
182194
return {
183195
showNewTopicModal: false,
184196
loading: false,
197+
more: null,
198+
moreLoading: false,
185199
moveNodesInProgress: false,
186200
targetNodeId: null,
187201
previewNodeId: null,
@@ -234,6 +248,10 @@
234248
crumbs() {
235249
return this.getContentNodeAncestors(this.targetNodeId, true) || [];
236250
},
251+
showMoreLabel() {
252+
// eslint-disable-next-line kolibri/vue-no-undefined-string-uses
253+
return showMoreTranslator.$tr('showMore');
254+
},
237255
},
238256
watch: {
239257
targetNodeId() {
@@ -247,7 +265,7 @@
247265
this.targetNodeId = this.currentLocationId || this.rootId;
248266
},
249267
methods: {
250-
...mapActions('contentNode', ['createContentNode', 'loadChildren']),
268+
...mapActions('contentNode', ['createContentNode', 'loadChildren', 'loadContentNodes']),
251269
isDisabled(node) {
252270
return this.moveNodeIds.includes(node.id);
253271
},
@@ -272,8 +290,9 @@
272290
return this.loadChildren({
273291
parent: this.targetNodeId,
274292
root_id: this.rootId,
275-
}).then(() => {
293+
}).then(childrenResponse => {
276294
this.loading = false;
295+
this.more = childrenResponse.more || null;
277296
});
278297
}
279298
return Promise.resolve();
@@ -302,6 +321,15 @@
302321
});
303322
this.moveNodesInProgress = false;
304323
},
324+
loadMore() {
325+
if (this.more && !this.moreLoading) {
326+
this.moreLoading = true;
327+
this.loadContentNodes(this.more).then(response => {
328+
this.more = response.more || null;
329+
this.moreLoading = false;
330+
});
331+
}
332+
},
305333
},
306334
$trs: {
307335
moveItems:
@@ -350,4 +378,11 @@
350378
}
351379
}
352380
381+
.show-more-button-container {
382+
display: flex;
383+
justify-content: center;
384+
width: 100%;
385+
margin-bottom: 10px;
386+
}
387+
353388
</style>

contentcuration/contentcuration/frontend/channelEdit/views/CurrentTopicView.vue

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@
533533
},
534534
inheritanceParent() {
535535
const firstNode = this.currentInheritingNodes[0];
536+
536537
if (!firstNode) {
537538
return;
538539
}
@@ -726,6 +727,7 @@
726727
handleDragDrop(drop) {
727728
const { data } = drop;
728729
const { identity, section, relative } = data.target;
730+
const targetMetadata = identity.metadata || {};
729731
const isTargetTree =
730732
drop.target && drop.target.region && drop.target.region.id === DraggableRegions.TREE;
731733
@@ -742,7 +744,7 @@
742744
position = this.relativePosition(relative > DraggableFlags.NONE ? relative : section);
743745
} else {
744746
// Safety check
745-
const { kind } = identity.metadata || {};
747+
const { kind } = targetMetadata;
746748
if (kind && kind !== ContentKindsNames.TOPIC) {
747749
return Promise.reject('Cannot set child of non-topic');
748750
}
@@ -756,7 +758,7 @@
756758
const sources = drop.sources || [];
757759
const sourceRegion = sources.length > 0 ? sources[0].region : null;
758760
const payload = {
759-
target: identity.metadata.id,
761+
target: targetMetadata.id,
760762
position,
761763
};
762764
@@ -765,7 +767,7 @@
765767
// `excluded_descendants` by accessing the copy trees through the clipboard node ID
766768
if (sourceRegion && sourceRegion.id === DraggableRegions.CLIPBOARD) {
767769
return Promise.all(
768-
data.sources.map(source => {
770+
sources.map(source => {
769771
// Using `getCopyTrees` we can access the `excluded_descendants` for the node, such
770772
// that we make sure to skip copying nodes that aren't intended to be copied
771773
const trees = this.getCopyTrees(source.metadata.clipboardNodeId, true);
@@ -789,10 +791,27 @@
789791
);
790792
}
791793
794+
// We want to avoid launching the inherit modal when the move operation is a prepend or
795+
// append move, and target is the current parent. When the move operation is relative to
796+
// the target, that is left or right, we want only launch the modal if the parent is
797+
// changing
798+
let inherit = false;
799+
if (
800+
position === RELATIVE_TREE_POSITIONS.FIRST_CHILD ||
801+
position === RELATIVE_TREE_POSITIONS.LAST_CHILD
802+
) {
803+
inherit = !sources.some(s => s.metadata.parent === targetMetadata.id);
804+
} else if (
805+
position === RELATIVE_TREE_POSITIONS.LEFT ||
806+
position === RELATIVE_TREE_POSITIONS.RIGHT
807+
) {
808+
inherit = !sources.some(s => s.metadata.parent === targetMetadata.parent);
809+
}
810+
792811
return this.moveContentNodes({
793812
...payload,
794-
id__in: data.sources.map(s => s.metadata.id),
795-
inherit: !data.sources.some(s => s.metadata.parent === payload.target),
813+
id__in: sources.map(s => s.metadata.id),
814+
inherit,
796815
});
797816
}
798817
},

contentcuration/contentcuration/frontend/channelEdit/views/ImportFromChannels/ContentTreeList.vue

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
/>
4444
</VFlex>
4545
</VLayout>
46+
<div class="show-more-button-container">
47+
<KButton v-if="more" :disabled="moreLoading" @click="loadMore">
48+
{{ showMoreLabel }}
49+
</KButton>
50+
</div>
4651
</div>
4752
</VContainer>
4853

@@ -55,13 +60,17 @@
5560
import intersectionBy from 'lodash/intersectionBy';
5661
import { mapActions, mapGetters } from 'vuex';
5762
import find from 'lodash/find';
63+
import NodePanel from '../NodePanel';
5864
import { RouteNames } from '../../constants';
5965
import BrowsingCard from './BrowsingCard';
6066
import Breadcrumbs from 'shared/views/Breadcrumbs';
6167
import Checkbox from 'shared/views/form/Checkbox';
6268
import LoadingText from 'shared/views/LoadingText';
6369
import { constantsTranslationMixin } from 'shared/mixins';
6470
import { ChannelListTypes } from 'shared/constants';
71+
import { crossComponentTranslator } from 'shared/i18n';
72+
73+
const showMoreTranslator = crossComponentTranslator(NodePanel);
6574
6675
export default {
6776
name: 'ContentTreeList',
@@ -85,6 +94,8 @@
8594
data() {
8695
return {
8796
loading: false,
97+
more: null,
98+
moreLoading: false,
8899
};
89100
},
90101
computed: {
@@ -142,39 +153,44 @@
142153
...ancestorsLinks,
143154
];
144155
},
156+
showMoreLabel() {
157+
// eslint-disable-next-line kolibri/vue-no-undefined-string-uses
158+
return showMoreTranslator.$tr('showMore');
159+
},
145160
},
146161
watch: {
147-
topicId(parent) {
162+
topicId(newTopicId, oldTopicId) {
163+
if (newTopicId !== oldTopicId && newTopicId) {
164+
this.loadData();
165+
}
166+
},
167+
},
168+
created() {
169+
this.loadData();
170+
},
171+
methods: {
172+
...mapActions('contentNode', ['loadChildren', 'loadAncestors', 'loadContentNodes']),
173+
loadData() {
148174
this.loading = true;
149-
return this.loadChildren({
150-
parent,
175+
const params = {
151176
complete: true,
152-
}).then(() => {
177+
};
178+
const channelListType = this.$route.query.channel_list || ChannelListTypes.PUBLIC;
179+
if (channelListType === ChannelListTypes.PUBLIC) {
180+
// TODO: load from public API instead
181+
// TODO: challenging because of node_id->id and root_id->channel_id
182+
params.published = true;
183+
}
184+
185+
return Promise.all([
186+
this.loadChildren({ parent: this.topicId, ...params }).then(childrenResponse => {
187+
this.more = childrenResponse.more || null;
188+
}),
189+
this.loadAncestors({ id: this.topicId }),
190+
]).then(() => {
153191
this.loading = false;
154192
});
155193
},
156-
},
157-
mounted() {
158-
this.loading = true;
159-
const params = {
160-
complete: true,
161-
};
162-
const channelListType = this.$route.query.channel_list || ChannelListTypes.PUBLIC;
163-
if (channelListType === ChannelListTypes.PUBLIC) {
164-
// TODO: load from public API instead
165-
// TODO: challenging because of node_id->id and root_id->channel_id
166-
params.published = true;
167-
}
168-
169-
return Promise.all([
170-
this.loadChildren({ parent: this.topicId, ...params }),
171-
this.loadAncestors({ id: this.topicId }),
172-
]).then(() => {
173-
this.loading = false;
174-
});
175-
},
176-
methods: {
177-
...mapActions('contentNode', ['loadChildren', 'loadAncestors']),
178194
// @public
179195
scrollToNode(nodeId) {
180196
const ref = this.$refs[nodeId];
@@ -187,6 +203,15 @@
187203
toggleSelected(node) {
188204
this.$emit('change_selected', { nodes: [node], isSelected: !this.isSelected(node) });
189205
},
206+
loadMore() {
207+
if (this.more && !this.moreLoading) {
208+
this.moreLoading = true;
209+
this.loadContentNodes(this.more).then(response => {
210+
this.more = response.more || null;
211+
this.moreLoading = false;
212+
});
213+
}
214+
},
190215
},
191216
$trs: {
192217
allChannelsLabel: 'Channels',

contentcuration/contentcuration/frontend/channelEdit/views/TreeView/TreeViewBase.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@
390390
this.currentChannel.publishing ||
391391
!this.isChanged ||
392392
!this.currentChannel.language ||
393-
(this.rootNode && !this.rootNode.total_count)
393+
(this.rootNode && !this.rootNode.resource_count)
394394
);
395395
},
396396
publishButtonTooltip() {

0 commit comments

Comments
 (0)