From c1054b42fa8f1882ff09e2ba3e3e45079b849975 Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Tue, 12 May 2026 09:11:53 -0700 Subject: [PATCH 1/9] updated translated strings for Session Publish Review headings --- .../ilios-common/addon/components/publish-all-sessions.gjs | 4 ++-- packages/ilios-common/translations/en-us.yaml | 6 +++--- packages/ilios-common/translations/es.yaml | 4 ++-- packages/ilios-common/translations/fr.yaml | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/ilios-common/addon/components/publish-all-sessions.gjs b/packages/ilios-common/addon/components/publish-all-sessions.gjs index 795bbf41d9..063a6a6c31 100644 --- a/packages/ilios-common/addon/components/publish-all-sessions.gjs +++ b/packages/ilios-common/addon/components/publish-all-sessions.gjs @@ -306,7 +306,7 @@ export default class PublishAllSessionsComponent extends Component { data-test-title {{on "click" (fn @setExpandCompleteSessions (not @expandCompleteSessions))}} > - {{t "general.completeSessions"}} + {{t "general.publishedSessions"}} ({{this.publishableSessions.length}}) @@ -388,7 +388,7 @@ export default class PublishAllSessionsComponent extends Component {
- {{t "general.reviewSessions"}} + {{t "general.unPublishedSessions"}} ({{this.overridableSessions.length}})
diff --git a/packages/ilios-common/translations/en-us.yaml b/packages/ilios-common/translations/en-us.yaml index 61f49eddcf..74322e3040 100644 --- a/packages/ilios-common/translations/en-us.yaml +++ b/packages/ilios-common/translations/en-us.yaml @@ -57,7 +57,6 @@ general: collapseDetail: Hide Details competencies: Competencies complete: Complete - completeSessions: "Sessions Complete: ready to publish" confirmRemoveLearningMaterial: Are you sure you want to remove this learning material? This action cannot be undone. confirmRemoveObjective: Are you sure you want to delete this objective? This action cannot be undone. confirmRemoveSession: Are you sure you want to delete this session? This action cannot be undone. @@ -190,7 +189,7 @@ general: ilmDue: ILM - Due inactive: inactive include: Include - incompleteSessions: "Sessions Incomplete: cannot publish" + incompleteSessions: "Incomplete Sessions: cannot publish" independentLearning: Independent Learning inProgress: In Progress instructing: Instructing @@ -290,6 +289,7 @@ general: publishAsIs: Publish As-is publishCourse: Publish Course published: Published + publishedSessions: Published Sessions publishedSuccessfully: Published successfully publishSession: Publish Session remove: Remove @@ -298,7 +298,6 @@ general: resultsCount: "{count, plural, =1 {1 result} other {# results}}" returnToPreviousPage: Return to Previous Page reviewMissingItems: "Review {count} Missing Items" - reviewSessions: Sessions Requiring Review saturday: Saturday save: Save savedSuccessfully: saved successfully @@ -390,6 +389,7 @@ general: universalLocator: Universal Locator unlinkedObjectives: This course has unlinked objective(s) unPublishCourse: UnPublish Course + unPublishedSessions: Unpublished Sessions unPublishedSuccessfully: UnPublished successfully unPublishSession: UnPublish Session unusedObjectives: Unused Objectives diff --git a/packages/ilios-common/translations/es.yaml b/packages/ilios-common/translations/es.yaml index 24a57bb74f..7225620b7b 100644 --- a/packages/ilios-common/translations/es.yaml +++ b/packages/ilios-common/translations/es.yaml @@ -57,7 +57,6 @@ general: collapseDetail: Esconder Detalles competencies: Competencias complete: Completo - completeSessions: "Sesiónes Completas: Listo a Publicar" confirmRemoveLearningMaterial: ¿Está seguro que desea eliminar este material de aprendizaje? Esta acción no se puede deshacer. confirmRemoveObjective: ¿Está seguro que desea eliminar este objetivo? Esta acción no se puede deshacer. confirmRemoveSession: ¿Está seguro que desea eliminar este sessión? Esta acción no se puede deshacer. @@ -290,6 +289,7 @@ general: publishAsIs: Publique Como Es publishCourse: Publique Curso published: Publicado + publishedSessions: Sesiones Publicadas publishedSuccessfully: Publicado con éxito publishSession: Publique La Sesión remove: Remover @@ -298,7 +298,6 @@ general: resultsCount: "{count, plural, =1 {1 resultado} other {# resultados}}" returnToPreviousPage: Volver a la Página Anterior reviewMissingItems: "Revisar {count} Artículos Faltantes" - reviewSessions: Sesiónes a Revisar saturday: Sábado save: Guardar savedSuccessfully: ahorrado con éxito @@ -390,6 +389,7 @@ general: universalLocator: Localizador universal de unlinkedObjectives: Este curso tiene objetivo(s) no vinculados unPublishCourse: No Publique El Curso + unPublishedSessions: Sesiones No Publicadas unPublishedSuccessfully: No Publicado con éxito unPublishSession: No Publique La Sesión unusedObjectives: Objetivos no Utilizados diff --git a/packages/ilios-common/translations/fr.yaml b/packages/ilios-common/translations/fr.yaml index 2c8b936b98..9a7aa58168 100644 --- a/packages/ilios-common/translations/fr.yaml +++ b/packages/ilios-common/translations/fr.yaml @@ -57,7 +57,6 @@ general: collapseDetail: Masquer Détails competencies: Compétences complete: Accompli - completeSessions: "Séances complète: prêt à publier" confirmRemoveLearningMaterial: "Êtes-vous sûr vous voulez supprimer cette matériel d'étude? Ça action ne peut pas être défait." confirmRemoveObjective: Êtes vous sûr de vouloir supprimer cet objectif? Ça action ne peut pas être défait. confirmRemoveSession: Êtes vous sûr de vouloir supprimer cette séance? Ça action ne peut pas être défait. @@ -290,6 +289,7 @@ general: publishAsIs: 'Publier "as-is"' publishCourse: Publier Cours published: Publié + publishedSessions: Sessions Publiées publishedSuccessfully: Publié réussi publishSession: Publier Session remove: Supprîme @@ -298,7 +298,6 @@ general: resultsCount: "{count, plural, =1 {1 résultat} other {# résultats}}" returnToPreviousPage: Retour à la page précédente reviewMissingItems: "Examiner {count} objets manquants" - reviewSessions: Séances à faire réviser saturday: Samedi save: Enregistrer savedSuccessfully: enregistré avec succès @@ -390,6 +389,7 @@ general: universalLocator: Localisateur universel unlinkedObjectives: Ce cours comprend des objectifs non liés unPublishCourse: Faire à Dépublier Cours + unPublishedSessions: Sessiones Non Publiées unPublishedSuccessfully: Faire à Dépublier réussi unPublishSession: Faire à Dépublier Session unusedObjectives: Objectifs non Utilisés From 2076dd5a0c9c96846afee423995ddd60e94386a7 Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Mon, 1 Jun 2026 13:51:19 -0700 Subject: [PATCH 2/9] updated translation strings for Unpublished Sessions --- packages/ilios-common/translations/en-us.yaml | 2 +- packages/ilios-common/translations/es.yaml | 2 +- packages/ilios-common/translations/fr.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ilios-common/translations/en-us.yaml b/packages/ilios-common/translations/en-us.yaml index 74322e3040..88041e3d07 100644 --- a/packages/ilios-common/translations/en-us.yaml +++ b/packages/ilios-common/translations/en-us.yaml @@ -389,7 +389,7 @@ general: universalLocator: Universal Locator unlinkedObjectives: This course has unlinked objective(s) unPublishCourse: UnPublish Course - unPublishedSessions: Unpublished Sessions + unPublishedSessions: "Unpublished Sessions: for review" unPublishedSuccessfully: UnPublished successfully unPublishSession: UnPublish Session unusedObjectives: Unused Objectives diff --git a/packages/ilios-common/translations/es.yaml b/packages/ilios-common/translations/es.yaml index 7225620b7b..09f6490b6a 100644 --- a/packages/ilios-common/translations/es.yaml +++ b/packages/ilios-common/translations/es.yaml @@ -389,7 +389,7 @@ general: universalLocator: Localizador universal de unlinkedObjectives: Este curso tiene objetivo(s) no vinculados unPublishCourse: No Publique El Curso - unPublishedSessions: Sesiones No Publicadas + unPublishedSessions: "Sesiones No Publicadas: para revisión" unPublishedSuccessfully: No Publicado con éxito unPublishSession: No Publique La Sesión unusedObjectives: Objetivos no Utilizados diff --git a/packages/ilios-common/translations/fr.yaml b/packages/ilios-common/translations/fr.yaml index 9a7aa58168..b5706829ca 100644 --- a/packages/ilios-common/translations/fr.yaml +++ b/packages/ilios-common/translations/fr.yaml @@ -389,7 +389,7 @@ general: universalLocator: Localisateur universel unlinkedObjectives: Ce cours comprend des objectifs non liés unPublishCourse: Faire à Dépublier Cours - unPublishedSessions: Sessiones Non Publiées + unPublishedSessions: "Sessiones Non Publiées: à examiner" unPublishedSuccessfully: Faire à Dépublier réussi unPublishSession: Faire à Dépublier Session unusedObjectives: Objectifs non Utilisés From 034b57e18e80826a7935f02bf61620e27314ff77 Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Mon, 1 Jun 2026 17:18:53 -0700 Subject: [PATCH 3/9] all tables on session pub review now have sortable columns --- .../addon/components/publish-all-sessions.gjs | 246 ++++++++++++++++-- .../addon/controllers/course/publishall.js | 11 +- .../addon/templates/course/publishall.gjs | 6 + 3 files changed, 234 insertions(+), 29 deletions(-) diff --git a/packages/ilios-common/addon/components/publish-all-sessions.gjs b/packages/ilios-common/addon/components/publish-all-sessions.gjs index 063a6a6c31..75a79b4fca 100644 --- a/packages/ilios-common/addon/components/publish-all-sessions.gjs +++ b/packages/ilios-common/addon/components/publish-all-sessions.gjs @@ -7,7 +7,7 @@ import { task, timeout } from 'ember-concurrency'; import { TrackedAsyncData } from 'ember-async-data'; import { uniqueValues } from 'ilios-common/utils/array-helpers'; import { on } from '@ember/modifier'; -import { not } from 'ember-truth-helpers'; +import { eq, or, not } from 'ember-truth-helpers'; import t from 'ember-intl/helpers/t'; import FaIcon from '@fortawesome/ember-fontawesome/components/fa-icon'; import { LinkTo } from '@ember/routing'; @@ -17,6 +17,7 @@ import mapBy from 'ilios-common/helpers/map-by'; import SaveButton from 'ilios-common/components/save-button'; import perform from 'ember-concurrency/helpers/perform'; import scrollIntoView from 'ilios-common/modifiers/scroll-into-view'; +import SortableTh from 'ilios-common/components/sortable-th'; import { faLinkSlash, faCaretRight, faCaretDown } from '@fortawesome/free-solid-svg-icons'; export default class PublishAllSessionsComponent extends Component { @@ -111,12 +112,70 @@ export default class PublishAllSessionsComponent extends Component { }); } + get sortedPublishableSessions() { + if (this.args.sortCompleteBy.includes('offerings')) { + return this.publishableSessions.sort((a, b) => a.offerings.length - b.offerings.length); + } + + if (this.args.sortCompleteBy.includes('terms')) { + return this.publishableSessions.sort((a, b) => a.terms.length - b.terms.length); + } + + if (this.args.sortCompleteBy.includes('objectives')) { + return this.publishableSessions.sort( + (a, b) => a.sessionObjectives.length - b.sessionObjectives.length, + ); + } + + const locale = this.intl.get('primaryLocale'); + return this.publishableSessions.sort((a, b) => a.title.localeCompare(b.title, locale)); + } + + get sortedPublishableAscending() { + return this.args.sortCompleteBy.search(/desc/) === -1; + } + + get orderedPublishableSessions() { + return this.sortedPublishableAscending + ? this.sortedPublishableSessions + : this.sortedPublishableSessions.reverse(); + } + get unPublishableSessions() { return this.sessions.filter((session) => { return session.requiredPublicationIssues.length > 0; }); } + get sortedUnPublishableSessions() { + if (this.args.sortIncompleteBy.includes('offerings')) { + return this.unPublishableSessions.sort((a, b) => a.offerings.length - b.offerings.length); + } + + if (this.args.sortIncompleteBy.includes('terms')) { + return this.unPublishableSessions.sort((a, b) => a.terms.length - b.terms.length); + } + + if (this.args.sortIncompleteBy.includes('objectives')) { + return this.unPublishableSessions.sort( + (a, b) => a.sessionObjectives.length - b.sessionObjectives.length, + ); + } + + const locale = this.intl.get('primaryLocale'); + return this.unPublishableSessions.sort((a, b) => a.title.localeCompare(b.title, locale)); + } + + get sortedUnPublishableAscending() { + return this.args.sortIncompleteBy.search(/desc/) === -1; + } + + get orderedUnPublishableSessions() { + return this.sortedUnPublishableAscending + ? this.sortedUnPublishableSessions + : this.sortedUnPublishableSessions.reverse(); + } + get overridableSessions() { return this.sessions.filter((session) => { return ( @@ -126,6 +185,35 @@ export default class PublishAllSessionsComponent extends Component { }); } + get sortedOverridableSessions() { + if (this.args.sortUnpublishedBy.includes('offerings')) { + return this.overridableSessions.sort((a, b) => a.offerings.length - b.offerings.length); + } + + if (this.args.sortUnpublishedBy.includes('terms')) { + return this.overridableSessions.sort((a, b) => a.terms.length - b.terms.length); + } + + if (this.args.sortUnpublishedBy.includes('objectives')) { + return this.overridableSessions.sort( + (a, b) => a.sessionObjectives.length - b.sessionObjectives.length, + ); + } + + const locale = this.intl.get('primaryLocale'); + return this.overridableSessions.sort((a, b) => a.title.localeCompare(b.title, locale)); + } + + get sortedOverridableAscending() { + return this.args.sortUnpublishedBy.search(/desc/) === -1; + } + + get orderedOverridableSessions() { + return this.sortedOverridableAscending + ? this.sortedOverridableSessions + : this.sortedOverridableSessions.reverse(); + } + get publishCount() { return this.publishableSessions.length + this.sessionsToPublish.length; } @@ -165,6 +253,30 @@ export default class PublishAllSessionsComponent extends Component { this.userSelectedSessionsToSchedule = [...this.overridableSessions]; } + @action + setSortIncompleteBy(what) { + if (this.args.sortIncompleteBy === what) { + what += ':desc'; + } + this.args.setSortIncompleteBy(what); + } + + @action + setSortCompleteBy(what) { + if (this.args.sortCompleteBy === what) { + what += ':desc'; + } + this.args.setSortCompleteBy(what); + } + + @action + setSortUnpublishedBy(what) { + if (this.args.sortUnpublishedBy === what) { + what += ':desc'; + } + this.args.setSortUnpublishedBy(what); + } + async saveSomeSessions(sessions) { const chunk = sessions.splice(0, 6); @@ -226,22 +338,50 @@ export default class PublishAllSessionsComponent extends Component { - - - - + - {{#each this.unPublishableSessions as |session|}} + {{#each this.orderedUnPublishableSessions as |session|}}