From 16dbc15c3c07c7fb0a043cb6823bcfa95ef4e5ae Mon Sep 17 00:00:00 2001 From: taoerman Date: Sun, 4 Jan 2026 19:34:20 -0800 Subject: [PATCH 01/10] Use channelVersion objects instead of special permission ids --- .../composables/useSpecialPermissions.js | 36 ++++++++----------- .../index.vue | 13 +++++-- .../licenseCheck/SpecialPermissionsList.vue | 7 +--- .../frontend/shared/styles/main.scss | 2 +- 4 files changed, 27 insertions(+), 31 deletions(-) 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..3eeb898e7f 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,24 @@ 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.map(permission => ({ + id: permission.id, + description: permission.description, + distributable: permission.distributable, + })); + } } catch (err) { error.value = err; permissions.value = []; @@ -84,9 +78,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..a6e6b11f37 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,6 +430,13 @@ return channelVersion; }); + const channelVersionId = computed(() => { + if (versionDetail.value?.id) { + return versionDetail.value.id; + } + return null; + }); + const { isLoading: licenseAuditIsLoading, isFinished: licenseAuditIsFinished, @@ -574,6 +580,7 @@ isCurrentVersionAlreadySubmitted, canBeEdited, displayedVersion, + channelVersionId, canBeSubmitted, publishedDataIsLoading, publishedDataIsFinished, 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/frontend/shared/styles/main.scss b/contentcuration/contentcuration/frontend/shared/styles/main.scss index 763eaf873a..401fc5d0c5 100644 --- a/contentcuration/contentcuration/frontend/shared/styles/main.scss +++ b/contentcuration/contentcuration/frontend/shared/styles/main.scss @@ -1,5 +1,5 @@ @import '~material-icons/iconfont/material-icons.css'; -@import '~kolibri-design-system/lib/styles/common'; +@import '~kolibri-design-system/lib/styles/definitions'; @font-face { font-family: 'Noto Sans'; From ef6bbf321dee99eeeb5e1702962cef8255cb637f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 03:39:20 +0000 Subject: [PATCH 02/10] [pre-commit.ci lite] apply automatic fixes --- .../composables/useSpecialPermissions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3eeb898e7f..6e27eedcbe 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/composables/useSpecialPermissions.js +++ b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/composables/useSpecialPermissions.js @@ -79,7 +79,7 @@ export function useSpecialPermissions(channelVersionId) { watch( () => unref(channelVersionId), - (versionId) => { + versionId => { fetchPermissions(versionId); }, { immediate: true }, From 154ccb86d050304af1245752908005eeeaeda891 Mon Sep 17 00:00:00 2001 From: taoerman Date: Sun, 4 Jan 2026 19:50:28 -0800 Subject: [PATCH 03/10] fix linting --- .../sidePanels/SubmitToCommunityLibrarySidePanel/index.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue index a6e6b11f37..557e1455db 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue @@ -441,7 +441,6 @@ isLoading: licenseAuditIsLoading, isFinished: licenseAuditIsFinished, invalidLicenses, - specialPermissions, includedLicenses, checkAndTriggerAudit: checkAndTriggerLicenseAudit, } = useLicenseAudit(props.channel, currentChannelVersion); @@ -589,7 +588,6 @@ licenseAuditIsLoading, licenseAuditIsFinished, invalidLicenses, - specialPermissions, includedLicenses, onSubmit, // Translation functions From 0f6513b7d16a1e4ff638c8775f18b360913606a9 Mon Sep 17 00:00:00 2001 From: taoerman Date: Mon, 19 Jan 2026 09:27:31 -0800 Subject: [PATCH 04/10] fix code --- .../composables/useSpecialPermissions.js | 6 +----- .../sidePanels/SubmitToCommunityLibrarySidePanel/index.vue | 5 +---- .../contentcuration/frontend/shared/styles/main.scss | 2 +- contentcuration/contentcuration/models.py | 4 ++-- 4 files changed, 5 insertions(+), 12 deletions(-) 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 6e27eedcbe..306ce4d83c 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/composables/useSpecialPermissions.js +++ b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/composables/useSpecialPermissions.js @@ -51,11 +51,7 @@ export function useSpecialPermissions(channelVersionId) { distributable: false, }); - permissions.value = response.map(permission => ({ - id: permission.id, - description: permission.description, - distributable: permission.distributable, - })); + permissions.value = response; } } catch (err) { error.value = err; diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue index 557e1455db..dcfe5b3e6a 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue @@ -431,10 +431,7 @@ }); const channelVersionId = computed(() => { - if (versionDetail.value?.id) { - return versionDetail.value.id; - } - return null; + return versionDetail.value?.id; }); const { diff --git a/contentcuration/contentcuration/frontend/shared/styles/main.scss b/contentcuration/contentcuration/frontend/shared/styles/main.scss index 401fc5d0c5..763eaf873a 100644 --- a/contentcuration/contentcuration/frontend/shared/styles/main.scss +++ b/contentcuration/contentcuration/frontend/shared/styles/main.scss @@ -1,5 +1,5 @@ @import '~material-icons/iconfont/material-icons.css'; -@import '~kolibri-design-system/lib/styles/definitions'; +@import '~kolibri-design-system/lib/styles/common'; @font-face { font-family: 'Noto Sans'; diff --git a/contentcuration/contentcuration/models.py b/contentcuration/contentcuration/models.py index dfd9fd12d1..e0d179e86e 100644 --- a/contentcuration/contentcuration/models.py +++ b/contentcuration/contentcuration/models.py @@ -1400,12 +1400,12 @@ 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] + return licenses.choices 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): From 70778ea243bf12b9ebc67579890b3a9ca5bf5483 Mon Sep 17 00:00:00 2001 From: taoerman Date: Mon, 19 Jan 2026 09:38:15 -0800 Subject: [PATCH 05/10] fix code --- .../migrations/0161_auto_20260119_1737.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py diff --git a/contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py b/contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py new file mode 100644 index 0000000000..07818f84d5 --- /dev/null +++ b/contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py @@ -0,0 +1,29 @@ +# Generated by Django 3.2.24 on 2026-01-19 17:37 + +import django.contrib.postgres.fields +from django.db import migrations, 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=[('CC BY', 'CC BY'), ('CC BY-SA', 'CC BY-SA'), ('CC BY-ND', 'CC BY-ND'), ('CC BY-NC', 'CC BY-NC'), ('CC BY-NC-SA', 'CC BY-NC-SA'), ('CC BY-NC-ND', 'CC BY-NC-ND'), ('All Rights Reserved', 'All Rights Reserved'), ('Public Domain', 'Public Domain'), ('Special Permissions', '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=[('CC BY', 'CC BY'), ('CC BY-SA', 'CC BY-SA'), ('CC BY-ND', 'CC BY-ND'), ('CC BY-NC', 'CC BY-NC'), ('CC BY-NC-SA', 'CC BY-NC-SA'), ('CC BY-NC-ND', 'CC BY-NC-ND'), ('All Rights Reserved', 'All Rights Reserved'), ('Public Domain', 'Public Domain'), ('Special Permissions', 'Special Permissions')]), blank=True, null=True, size=None), + ), + ] From a61be92d4453d94fd0020992ca69ef19bfca5932 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 17:40:40 +0000 Subject: [PATCH 06/10] [pre-commit.ci lite] apply automatic fixes --- .../migrations/0161_auto_20260119_1737.py | 128 ++++++++++++++++-- 1 file changed, 116 insertions(+), 12 deletions(-) diff --git a/contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py b/contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py index 07818f84d5..ca09abfbb5 100644 --- a/contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py +++ b/contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py @@ -1,29 +1,133 @@ # Generated by Django 3.2.24 on 2026-01-19 17:37 - import django.contrib.postgres.fields -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): dependencies = [ - ('contentcuration', '0160_add_channel_version_model'), + ("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), + 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=[('CC BY', 'CC BY'), ('CC BY-SA', 'CC BY-SA'), ('CC BY-ND', 'CC BY-ND'), ('CC BY-NC', 'CC BY-NC'), ('CC BY-NC-SA', 'CC BY-NC-SA'), ('CC BY-NC-ND', 'CC BY-NC-ND'), ('All Rights Reserved', 'All Rights Reserved'), ('Public Domain', 'Public Domain'), ('Special Permissions', 'Special Permissions')]), blank=True, null=True, size=None), + model_name="channelversion", + name="included_licenses", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.IntegerField( + choices=[ + ("CC BY", "CC BY"), + ("CC BY-SA", "CC BY-SA"), + ("CC BY-ND", "CC BY-ND"), + ("CC BY-NC", "CC BY-NC"), + ("CC BY-NC-SA", "CC BY-NC-SA"), + ("CC BY-NC-ND", "CC BY-NC-ND"), + ("All Rights Reserved", "All Rights Reserved"), + ("Public Domain", "Public Domain"), + ("Special Permissions", "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=[('CC BY', 'CC BY'), ('CC BY-SA', 'CC BY-SA'), ('CC BY-ND', 'CC BY-ND'), ('CC BY-NC', 'CC BY-NC'), ('CC BY-NC-SA', 'CC BY-NC-SA'), ('CC BY-NC-ND', 'CC BY-NC-ND'), ('All Rights Reserved', 'All Rights Reserved'), ('Public Domain', 'Public Domain'), ('Special Permissions', 'Special Permissions')]), blank=True, null=True, size=None), + model_name="channelversion", + name="non_distributable_licenses_included", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.IntegerField( + choices=[ + ("CC BY", "CC BY"), + ("CC BY-SA", "CC BY-SA"), + ("CC BY-ND", "CC BY-ND"), + ("CC BY-NC", "CC BY-NC"), + ("CC BY-NC-SA", "CC BY-NC-SA"), + ("CC BY-NC-ND", "CC BY-NC-ND"), + ("All Rights Reserved", "All Rights Reserved"), + ("Public Domain", "Public Domain"), + ("Special Permissions", "Special Permissions"), + ] + ), + blank=True, + null=True, + size=None, + ), ), ] From 5f9a2d7705593bd7d6cff63da63e4b00f96f6143 Mon Sep 17 00:00:00 2001 From: taoerman Date: Mon, 19 Jan 2026 09:46:16 -0800 Subject: [PATCH 07/10] fix code --- ...uto_20260119_1737.py => 0161_update_channelversion_choices.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contentcuration/contentcuration/migrations/{0161_auto_20260119_1737.py => 0161_update_channelversion_choices.py} (100%) diff --git a/contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py b/contentcuration/contentcuration/migrations/0161_update_channelversion_choices.py similarity index 100% rename from contentcuration/contentcuration/migrations/0161_auto_20260119_1737.py rename to contentcuration/contentcuration/migrations/0161_update_channelversion_choices.py From 7299a84332b271700fa91b1f566aaf0c60a1ef25 Mon Sep 17 00:00:00 2001 From: taoerman Date: Mon, 19 Jan 2026 10:35:07 -0800 Subject: [PATCH 08/10] fix code --- contentcuration/contentcuration/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contentcuration/contentcuration/models.py b/contentcuration/contentcuration/models.py index e0d179e86e..9b420478c3 100644 --- a/contentcuration/contentcuration/models.py +++ b/contentcuration/contentcuration/models.py @@ -1400,7 +1400,8 @@ def validate_language_code(value): def get_license_choices(): """Helper function to get license choices for ArrayField.""" - return licenses.choices + license_labels = dict(licenses.choices) + return [(lic.id, license_labels.get(lic.name, lic.name)) for lic in licenses.LICENSELIST] def get_categories_choices(): From a89d2dca615c53f5c5a36f8f6f0649184b7f9b75 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 18:37:41 +0000 Subject: [PATCH 09/10] [pre-commit.ci lite] apply automatic fixes --- contentcuration/contentcuration/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contentcuration/contentcuration/models.py b/contentcuration/contentcuration/models.py index 9b420478c3..ad06723f08 100644 --- a/contentcuration/contentcuration/models.py +++ b/contentcuration/contentcuration/models.py @@ -1401,7 +1401,9 @@ def validate_language_code(value): def get_license_choices(): """Helper function to get license choices for ArrayField.""" license_labels = dict(licenses.choices) - return [(lic.id, license_labels.get(lic.name, lic.name)) for lic in licenses.LICENSELIST] + return [ + (lic.id, license_labels.get(lic.name, lic.name)) for lic in licenses.LICENSELIST + ] def get_categories_choices(): From 13abc92771d36c5e1da6e1e5d498b643c8345b1f Mon Sep 17 00:00:00 2001 From: taoerman Date: Mon, 19 Jan 2026 10:58:55 -0800 Subject: [PATCH 10/10] fix code --- .../0161_update_channelversion_choices.py | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/contentcuration/contentcuration/migrations/0161_update_channelversion_choices.py b/contentcuration/contentcuration/migrations/0161_update_channelversion_choices.py index ca09abfbb5..edeb70afec 100644 --- a/contentcuration/contentcuration/migrations/0161_update_channelversion_choices.py +++ b/contentcuration/contentcuration/migrations/0161_update_channelversion_choices.py @@ -92,15 +92,15 @@ class Migration(migrations.Migration): field=django.contrib.postgres.fields.ArrayField( base_field=models.IntegerField( choices=[ - ("CC BY", "CC BY"), - ("CC BY-SA", "CC BY-SA"), - ("CC BY-ND", "CC BY-ND"), - ("CC BY-NC", "CC BY-NC"), - ("CC BY-NC-SA", "CC BY-NC-SA"), - ("CC BY-NC-ND", "CC BY-NC-ND"), - ("All Rights Reserved", "All Rights Reserved"), - ("Public Domain", "Public Domain"), - ("Special Permissions", "Special Permissions"), + (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, @@ -114,15 +114,15 @@ class Migration(migrations.Migration): field=django.contrib.postgres.fields.ArrayField( base_field=models.IntegerField( choices=[ - ("CC BY", "CC BY"), - ("CC BY-SA", "CC BY-SA"), - ("CC BY-ND", "CC BY-ND"), - ("CC BY-NC", "CC BY-NC"), - ("CC BY-NC-SA", "CC BY-NC-SA"), - ("CC BY-NC-ND", "CC BY-NC-ND"), - ("All Rights Reserved", "All Rights Reserved"), - ("Public Domain", "Public Domain"), - ("Special Permissions", "Special Permissions"), + (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,