Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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<string|number>|import('vue').Ref<Array<string|number>>} permissionIds
* A list (or ref to a list) of special-permissions license IDs to fetch.
* @param {string|number|import('vue').Ref<string|number>|null} channelVersionId
* The ChannelVersion ID to fetch special permissions for via ManyToMany relationship.
*
* @returns {{
* permissions: import('vue').Ref<Array<Object>>,
Expand All @@ -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);
Expand All @@ -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 = [];
Expand All @@ -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 },
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,9 @@
:licenses="includedLicenses"
/>
<SpecialPermissionsList
v-if="licenseAuditIsFinished && specialPermissions.length > 0"
v-if="licenseAuditIsFinished && channelVersionId"
v-model="checkedSpecialPermissions"
:channel-version-id="versionDetail && versionDetail.id"
:permission-ids="specialPermissions"
:channel-version-id="channelVersionId"
@update:allChecked="allSpecialPermissionsChecked = $event"
/>
<div class="country-area">
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -574,6 +576,7 @@
isCurrentVersionAlreadySubmitted,
canBeEdited,
displayedVersion,
channelVersionId,
canBeSubmitted,
publishedDataIsLoading,
publishedDataIsFinished,
Expand All @@ -582,7 +585,6 @@
licenseAuditIsLoading,
licenseAuditIsFinished,
invalidLicenses,
specialPermissions,
includedLicenses,
onSubmit,
// Translation functions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
totalPages,
nextPage,
previousPage,
} = useSpecialPermissions(props.channelVersionId, props.permissionIds);
} = useSpecialPermissions(props.channelVersionId);

function togglePermission(permissionId) {
const currentChecked = [...props.value];
Expand Down Expand Up @@ -133,11 +133,6 @@
required: false,
default: null,
},
permissionIds: {
type: Array,
required: false,
default: () => [],
},
value: {
type: Array,
required: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
),
),
]
7 changes: 5 additions & 2 deletions contentcuration/contentcuration/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down