diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/composables/useSpecialPermissions.js b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/composables/useSpecialPermissions.js index 977d26f10e..306ce4d83c 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/composables/useSpecialPermissions.js +++ b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/composables/useSpecialPermissions.js @@ -5,10 +5,10 @@ const ITEMS_PER_PAGE = 3; /** * Composable that fetches and paginates audited special-permissions licenses - * for a given set of permission IDs. + * for a given channel version ID. * - * @param {Array|import('vue').Ref>} permissionIds - * A list (or ref to a list) of special-permissions license IDs to fetch. + * @param {string|number|import('vue').Ref|null} channelVersionId + * The ChannelVersion ID to fetch special permissions for via ManyToMany relationship. * * @returns {{ * permissions: import('vue').Ref>, @@ -23,7 +23,7 @@ const ITEMS_PER_PAGE = 3; * Reactive state for the fetched, flattened permissions and pagination * helpers used by `SpecialPermissionsList.vue`. */ -export function useSpecialPermissions(channelVersionId, permissionIds) { +export function useSpecialPermissions(channelVersionId) { const permissions = ref([]); const isLoading = ref(false); const error = ref(null); @@ -39,30 +39,20 @@ export function useSpecialPermissions(channelVersionId, permissionIds) { return permissions.value.slice(start, end); }); - async function fetchPermissions(versionId, ids) { + async function fetchPermissions(versionId) { isLoading.value = true; error.value = null; permissions.value = []; try { - let response = []; if (versionId) { - response = await AuditedSpecialPermissionsLicense.fetchCollection({ + const response = await AuditedSpecialPermissionsLicense.fetchCollection({ channel_version: versionId, distributable: false, }); - } else if (ids && ids.length > 0) { - response = await AuditedSpecialPermissionsLicense.fetchCollection({ - by_ids: ids.join(','), - distributable: false, - }); - } - permissions.value = response.map(permission => ({ - id: permission.id, - description: permission.description, - distributable: permission.distributable, - })); + permissions.value = response; + } } catch (err) { error.value = err; permissions.value = []; @@ -84,9 +74,9 @@ export function useSpecialPermissions(channelVersionId, permissionIds) { } watch( - [() => unref(channelVersionId), () => unref(permissionIds)], - ([versionId, ids]) => { - fetchPermissions(versionId, ids); + () => unref(channelVersionId), + versionId => { + fetchPermissions(versionId); }, { immediate: true }, ); diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue index 6f21f15bcb..dcfe5b3e6a 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue @@ -161,10 +161,9 @@ :licenses="includedLicenses" />
@@ -431,11 +430,14 @@ return channelVersion; }); + const channelVersionId = computed(() => { + return versionDetail.value?.id; + }); + const { isLoading: licenseAuditIsLoading, isFinished: licenseAuditIsFinished, invalidLicenses, - specialPermissions, includedLicenses, checkAndTriggerAudit: checkAndTriggerLicenseAudit, } = useLicenseAudit(props.channel, currentChannelVersion); @@ -574,6 +576,7 @@ isCurrentVersionAlreadySubmitted, canBeEdited, displayedVersion, + channelVersionId, canBeSubmitted, publishedDataIsLoading, publishedDataIsFinished, @@ -582,7 +585,6 @@ licenseAuditIsLoading, licenseAuditIsFinished, invalidLicenses, - specialPermissions, includedLicenses, onSubmit, // Translation functions diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/licenseCheck/SpecialPermissionsList.vue b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/licenseCheck/SpecialPermissionsList.vue index 5bea675d1f..a66f9ea0b8 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/licenseCheck/SpecialPermissionsList.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/licenseCheck/SpecialPermissionsList.vue @@ -87,7 +87,7 @@ totalPages, nextPage, previousPage, - } = useSpecialPermissions(props.channelVersionId, props.permissionIds); + } = useSpecialPermissions(props.channelVersionId); function togglePermission(permissionId) { const currentChecked = [...props.value]; @@ -133,11 +133,6 @@ required: false, default: null, }, - permissionIds: { - type: Array, - required: false, - default: () => [], - }, value: { type: Array, required: false, diff --git a/contentcuration/contentcuration/migrations/0161_update_channelversion_choices.py b/contentcuration/contentcuration/migrations/0161_update_channelversion_choices.py new file mode 100644 index 0000000000..edeb70afec --- /dev/null +++ b/contentcuration/contentcuration/migrations/0161_update_channelversion_choices.py @@ -0,0 +1,133 @@ +# Generated by Django 3.2.24 on 2026-01-19 17:37 +import django.contrib.postgres.fields +from django.db import migrations +from django.db import models + + +class Migration(migrations.Migration): + + dependencies = [ + ("contentcuration", "0160_add_channel_version_model"), + ] + + operations = [ + migrations.AlterField( + model_name="channelversion", + name="included_categories", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField( + choices=[ + ("d&WXdXWF.qs0Xlaxq.0t5msbL5", "Algebra"), + ("d&WXdXWF.K80UMYnW.ViBlbQR&", "Anthropology"), + ("d&WXdXWF.qs0Xlaxq.nG96nHDc", "Arithmetic"), + ("d&WXdXWF.5QAjgfv7", "Arts"), + ("d&WXdXWF.i1IdaNwr.mjSF4QlF", "Astronomy"), + ("d&WXdXWF.i1IdaNwr.uErN4PdS", "Biology"), + ("d&WXdXWF.qs0Xlaxq.8rJ57ht6", "Calculus"), + ("d&WXdXWF.i1IdaNwr.#r5ocgid", "Chemistry"), + ("d&WXdXWF.K80UMYnW.F863vKiF", "Civic Education"), + ("d&WXdXWF.e#RTW9E#", "Computer Science"), + ("PbGoe2MV.J7CU1IxN", "Current Events"), + ("PbGoe2MV", "Daily Life"), + ("d&WXdXWF.5QAjgfv7.BUMJJBnS", "Dance"), + ("BCG3&slG.wZ3EAedB", "Digital Literacy"), + ("PbGoe2MV.EHcbjuKq", "Diversity"), + ("d&WXdXWF.5QAjgfv7.XsWznP4o", "Drama"), + ("d&WXdXWF.i1IdaNwr.zbDzxDE7", "Earth Science"), + ("PbGoe2MV.kyxTNsRS", "Entrepreneurship"), + ("PbGoe2MV.tS7WKnZ7", "Environment"), + ("PbGoe2MV.HGIc9sZq", "Financial Literacy"), + ("ziJ6PCuU", "For Teachers"), + ("BCG3&slG", "Foundations"), + ( + "BCG3&slG.0&d0qTqS", + "Foundations Logic And Critical Thinking", + ), + ("d&WXdXWF.qs0Xlaxq.lb7ELcK5", "Geometry"), + ("ziJ6PCuU.RLfhp37t", "Guides"), + ("d&WXdXWF.zWtcJ&F2", "History"), + ("l7DsPDlm.ISEXeZt&.pRvOzJTE", "Industry And Sector Specific"), + ("d&WXdXWF.JDUfJNXc", "Language Learning"), + ("BCG3&slG.fP2j70bj", "Learning Skills"), + ("ziJ6PCuU.lOBPr5ix", "Lesson Plans"), + ("BCG3&slG.HLo9TbNq", "Literacy"), + ("d&WXdXWF.kHKJ&PbV.DJLBbaEk", "Literature"), + ("d&WXdXWF.kHKJ&PbV.YMBXStib", "Logic And Critical Thinking"), + ("d&WXdXWF.qs0Xlaxq", "Mathematics"), + ("d&WXdXWF.e#RTW9E#.8ZoaPsVW", "Mechanical Engineering"), + ("PbGoe2MV.UOTL#KIV", "Media Literacy"), + ("PbGoe2MV.d8&gCo2N", "Mental Health"), + ("d&WXdXWF.5QAjgfv7.u0aKjT4i", "Music"), + ("BCG3&slG.Tsyej9ta", "Numeracy"), + ("d&WXdXWF.i1IdaNwr.r#wbt#jF", "Physics"), + ("d&WXdXWF.K80UMYnW.K72&pITr", "Political Science"), + ("l7DsPDlm.#N2VymZo", "Professional Skills"), + ("d&WXdXWF.e#RTW9E#.CfnlTDZ#", "Programming"), + ("PbGoe2MV.kivAZaeX", "Public Health"), + ("d&WXdXWF.kHKJ&PbV", "Reading And Writing"), + ("d&WXdXWF.kHKJ&PbV.r7RxB#9t", "Reading Comprehension"), + ("d&WXdXWF", "School"), + ("d&WXdXWF.i1IdaNwr", "Sciences"), + ("l7DsPDlm.ISEXeZt&.&1WpYE&n", "Skills Training"), + ("d&WXdXWF.K80UMYnW", "Social Sciences"), + ("d&WXdXWF.K80UMYnW.75WBu1ZS", "Sociology"), + ("d&WXdXWF.qs0Xlaxq.jNm15RLB", "Statistics"), + ("l7DsPDlm.ISEXeZt&", "Technical And Vocational Training"), + ("l7DsPDlm.ISEXeZt&.1JfIbP&N", "Tools And Software Training"), + ("d&WXdXWF.5QAjgfv7.4LskOFXj", "Visual Art"), + ("d&WXdXWF.e#RTW9E#.P7s8FxQ8", "Web Design"), + ("l7DsPDlm", "Work"), + ("d&WXdXWF.kHKJ&PbV.KFJOCr&6", "Writing"), + ], + max_length=100, + ), + blank=True, + null=True, + size=None, + ), + ), + migrations.AlterField( + model_name="channelversion", + name="included_licenses", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.IntegerField( + choices=[ + (1, "CC BY"), + (2, "CC BY-SA"), + (3, "CC BY-ND"), + (4, "CC BY-NC"), + (5, "CC BY-NC-SA"), + (6, "CC BY-NC-ND"), + (7, "All Rights Reserved"), + (8, "Public Domain"), + (9, "Special Permissions"), + ] + ), + blank=True, + null=True, + size=None, + ), + ), + migrations.AlterField( + model_name="channelversion", + name="non_distributable_licenses_included", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.IntegerField( + choices=[ + (1, "CC BY"), + (2, "CC BY-SA"), + (3, "CC BY-ND"), + (4, "CC BY-NC"), + (5, "CC BY-NC-SA"), + (6, "CC BY-NC-ND"), + (7, "All Rights Reserved"), + (8, "Public Domain"), + (9, "Special Permissions"), + ] + ), + blank=True, + null=True, + size=None, + ), + ), + ] diff --git a/contentcuration/contentcuration/models.py b/contentcuration/contentcuration/models.py index dfd9fd12d1..ad06723f08 100644 --- a/contentcuration/contentcuration/models.py +++ b/contentcuration/contentcuration/models.py @@ -1400,12 +1400,15 @@ def validate_language_code(value): def get_license_choices(): """Helper function to get license choices for ArrayField.""" - return [(lic[0], lic[1]) for lic in licenses.LICENSELIST] + license_labels = dict(licenses.choices) + return [ + (lic.id, license_labels.get(lic.name, lic.name)) for lic in licenses.LICENSELIST + ] def get_categories_choices(): """Helper function to get category choices for ArrayField.""" - return [(subj, subj) for subj in subjects.SUBJECTSLIST] + return subjects.choices class ChannelVersion(models.Model):