diff --git a/packages/frontend/.lint-todo b/packages/frontend/.lint-todo index 2080df9e80..ad10ac59ba 100644 --- a/packages/frontend/.lint-todo +++ b/packages/frontend/.lint-todo @@ -1,75 +1,75 @@ -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/new-directory-user.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|4|4|4|5d93dc162628c4faaa7bce9ef9bfba305f14ce38|1719360000000|1734915600000|1750464000000|app/components/unassigned-students-summary.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|4|5|4|5f7f17419fe451673ab74fb58778311bc01912c0|1719360000000|1734915600000|1750464000000|app/components/unassigned-students-summary.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|4|5|4|ddf86727990ead62165fe28c6dff53552a4d49b7|1719360000000|1734915600000|1750464000000|app/components/user-menu.hbs -add|ember-template-lint|no-at-ember-render-modifiers|28|43|28|43|5c127b0b8124a93b18177d7580bcc47dbb8ebbff|1719360000000|1734915600000|1750464000000|app/components/user-menu.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/user-profile-bio.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|f53982efe02d2bef9e7f12b5b862288c594579c2|1719360000000|1734915600000|1750464000000|app/components/user-profile-bio.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|cb63b416987d7c877a388fbd8e02681fb5571202|1719360000000|1734915600000|1750464000000|app/components/user-profile-cohorts.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/user-profile-roles.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|e5120f87b74c5ae8e4c76b9089e0b4a4504c6e3c|1719360000000|1734915600000|1750464000000|app/components/user-profile-roles.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|1fb0566922ce4f066916e5e2931f650f69d7cfba|1719360000000|1734915600000|1750464000000|app/components/visualizer-program-year-objectives.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|38e65b45b56fdfd4160d3b0884114b6643e3a036|1719360000000|1734915600000|1750464000000|app/components/visualizer-program-year-objectives.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|4|4|4|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/courses/new.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/new-report.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/new-sequence-block.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|77e3831e4ae1b00caee1f808711f2e26ab452a23|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/new-sequence-block.hbs -add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|ec3a02c7de9a846320bb33eb702a742de00e56bd|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/report-header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|708f3a1a4359e7d1bd669262535d882c49469947|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/report-header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/report-overview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/report-rollover.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|5e634ade97cc174a33ee6f2fdce6c42465ec31e3|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/report-rollover.hbs -add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/reports.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|7f75978f3cd895409aab8b335e6816db689c6155|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/reports.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|c34ed16d221405a625e5c23907f49fd55e6ba231|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/sequence-block-header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|6|2|6|2|6236d751dee8e47f88ffd257c6bfcec223f2b91c|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/sequence-block-header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|e65bc0e9138a1521733c31ef990721569f51eb20|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/sequence-block-overview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|bd1419d59d5caf1243719b72f63702d3b5bebc07|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/sequence-block-overview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/sequence-block-session-manager.hbs -add|ember-template-lint|no-at-ember-render-modifiers|6|2|6|2|394d8c8b6b1bc28f48ede0d39dcbfbb4dcd8261e|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/sequence-block-session-manager.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|62efc8d35f68e3f08387ec86aefd237a3165b683|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|5e634ade97cc174a33ee6f2fdce6c42465ec31e3|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|12|6|12|6|6b0fce6c690e7738c0a5c4d7c948aa33081989d9|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|63|6|63|6|b6db22ec9563ff51f1de52c44e83cbf68cbcba25|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|68|6|68|6|8d3d1b46c14db7639ed115e00e82558c82c47ef6|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|79|6|79|6|cf9fc0a5f1656f4a0d6a6b3193f15996466a1c72|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|90|6|90|6|b363c92a92a834938ea231382d1b1db885d2a558|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|100|6|100|6|7e8a296e37ffe138e13632833a23de0e7a69964a|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|111|6|111|6|b432d5e6ea21f6bf8c201d4453c8bea767d9a928|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|122|6|122|6|7888b1986f039c99dbc62e306f5d5bc34c90ae39|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|133|6|133|6|4d6c3374c9f845e60bda3b640ec49a3be3ee6fbb|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|144|6|144|6|e49fa902e44c371593d62096c490244ec75a9083|1719360000000|1734915600000|1750464000000|app/components/curriculum-inventory/verification-preview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|7312526529ca39ed820819d1478d8e1b8f555279|1719360000000|1734915600000|1750464000000|app/components/instructor-group/header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|10c85f1f7f9cf2d05a7f36c4618679ea04c51154|1719360000000|1734915600000|1750464000000|app/components/instructor-group/header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|7312526529ca39ed820819d1478d8e1b8f555279|1719360000000|1734915600000|1750464000000|app/components/learner-group/header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|c33c821719fcbe918954f20b45e0959a3a40c62b|1719360000000|1734915600000|1750464000000|app/components/learner-group/header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|cb6d7acb9879902b89ad1575846d290a564ffbae|1719360000000|1734915600000|1750464000000|app/components/learner-group/instructor-manager.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|2bdc98d02ac5ea2a4bd5bac6a0f9e880abafdcbe|1719360000000|1734915600000|1750464000000|app/components/learner-group/instructor-manager.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|4|4|4|170987df2d1e4c134a0ac459fc0bdd8dd91b9929|1719360000000|1734915600000|1750464000000|app/components/learner-group/root.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|4|5|4|7c59a55b95fd159dd99afa6b20e5f05b5b68def0|1719360000000|1734915600000|1750464000000|app/components/learner-group/root.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|4|4|4|66fe3cf991d61995cda5f5935874230700b5e21f|1719360000000|1734915600000|1750464000000|app/components/program/header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|4|5|4|0bcfaa7865c6a954a5b5226ffe44ddc6c63945ba|1719360000000|1734915600000|1750464000000|app/components/program/header.hbs -add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|66fe3cf991d61995cda5f5935874230700b5e21f|1719360000000|1734915600000|1750464000000|app/components/program/overview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|0bcfaa7865c6a954a5b5226ffe44ddc6c63945ba|1719360000000|1734915600000|1750464000000|app/components/program/overview.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|12f77ac1f8c43640397b771ba2c9830dd2041f23|1719360000000|1734915600000|1750464000000|app/components/program-year/collapsed-objectives.hbs -add|ember-template-lint|no-at-ember-render-modifiers|6|2|6|2|87dcba868bd23c9305b095ffbda9e90ab5b4918e|1719360000000|1734915600000|1750464000000|app/components/program-year/collapsed-objectives.hbs -add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|b759467cf4c3dc1d7e39d4bed1d085d51090d363|1719360000000|1734915600000|1750464000000|app/components/program-year/objective-list-item-expanded.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|c4f87a15e0dbf28e3a3b95d7b8259a419f93b29d|1719360000000|1734915600000|1750464000000|app/components/program-year/objective-list-item-expanded.hbs -add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|fc55335d86e2b3d97a0614f6c046ba360820801c|1719360000000|1734915600000|1750464000000|app/components/program-year/objective-list-item.hbs -add|ember-template-lint|no-at-ember-render-modifiers|6|2|6|2|12443b4ba50f603e3c3af3d9e10ce840e7b67d9e|1719360000000|1734915600000|1750464000000|app/components/program-year/objective-list-item.hbs -add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|286929067e02096dda5597efc45c876218621874|1719360000000|1734915600000|1750464000000|app/components/program-year/objectives.hbs -add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|f37fd8ee0b117114a09137593ed6f113b2c80806|1719360000000|1734915600000|1750464000000|app/components/program-year/objectives.hbs -add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/academic-year.hbs -add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/academic-year.hbs -add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/competency.hbs -add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/competency.hbs -add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/instructor-group.hbs -add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/instructor-group.hbs -add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/program-year.hbs -add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/program-year.hbs -add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/program.hbs -add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/program.hbs -add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/session-type.hbs -add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/session-type.hbs -add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/term.hbs -add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1719360000000|1734915600000|1750464000000|app/components/reports/subject/new/term.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/new-directory-user.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|4|4|4|5d93dc162628c4faaa7bce9ef9bfba305f14ce38|1721088000000|1723680000000|1726272000000|app/components/unassigned-students-summary.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|4|5|4|5f7f17419fe451673ab74fb58778311bc01912c0|1721088000000|1723680000000|1726272000000|app/components/unassigned-students-summary.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|4|5|4|ddf86727990ead62165fe28c6dff53552a4d49b7|1721088000000|1723680000000|1726272000000|app/components/user-menu.hbs +add|ember-template-lint|no-at-ember-render-modifiers|28|43|28|43|5c127b0b8124a93b18177d7580bcc47dbb8ebbff|1721088000000|1723680000000|1726272000000|app/components/user-menu.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/user-profile-bio.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|f53982efe02d2bef9e7f12b5b862288c594579c2|1721088000000|1723680000000|1726272000000|app/components/user-profile-bio.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|cb63b416987d7c877a388fbd8e02681fb5571202|1721088000000|1723680000000|1726272000000|app/components/user-profile-cohorts.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/user-profile-roles.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|e5120f87b74c5ae8e4c76b9089e0b4a4504c6e3c|1721088000000|1723680000000|1726272000000|app/components/user-profile-roles.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|1fb0566922ce4f066916e5e2931f650f69d7cfba|1721088000000|1723680000000|1726272000000|app/components/visualizer-program-year-objectives.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|38e65b45b56fdfd4160d3b0884114b6643e3a036|1721088000000|1723680000000|1726272000000|app/components/visualizer-program-year-objectives.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|4|4|4|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/courses/new.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/new-report.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/new-sequence-block.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|77e3831e4ae1b00caee1f808711f2e26ab452a23|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/new-sequence-block.hbs +add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|ec3a02c7de9a846320bb33eb702a742de00e56bd|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/report-header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|708f3a1a4359e7d1bd669262535d882c49469947|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/report-header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/report-overview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/report-rollover.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|5e634ade97cc174a33ee6f2fdce6c42465ec31e3|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/report-rollover.hbs +add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/reports.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|7f75978f3cd895409aab8b335e6816db689c6155|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/reports.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|c34ed16d221405a625e5c23907f49fd55e6ba231|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/sequence-block-header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|6|2|6|2|6236d751dee8e47f88ffd257c6bfcec223f2b91c|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/sequence-block-header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|e65bc0e9138a1521733c31ef990721569f51eb20|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/sequence-block-overview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|bd1419d59d5caf1243719b72f63702d3b5bebc07|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/sequence-block-overview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/sequence-block-session-manager.hbs +add|ember-template-lint|no-at-ember-render-modifiers|6|2|6|2|394d8c8b6b1bc28f48ede0d39dcbfbb4dcd8261e|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/sequence-block-session-manager.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|62efc8d35f68e3f08387ec86aefd237a3165b683|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|5e634ade97cc174a33ee6f2fdce6c42465ec31e3|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|12|6|12|6|6b0fce6c690e7738c0a5c4d7c948aa33081989d9|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|63|6|63|6|b6db22ec9563ff51f1de52c44e83cbf68cbcba25|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|68|6|68|6|8d3d1b46c14db7639ed115e00e82558c82c47ef6|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|79|6|79|6|cf9fc0a5f1656f4a0d6a6b3193f15996466a1c72|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|90|6|90|6|b363c92a92a834938ea231382d1b1db885d2a558|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|100|6|100|6|7e8a296e37ffe138e13632833a23de0e7a69964a|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|111|6|111|6|b432d5e6ea21f6bf8c201d4453c8bea767d9a928|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|122|6|122|6|7888b1986f039c99dbc62e306f5d5bc34c90ae39|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|133|6|133|6|4d6c3374c9f845e60bda3b640ec49a3be3ee6fbb|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|144|6|144|6|e49fa902e44c371593d62096c490244ec75a9083|1721088000000|1723680000000|1726272000000|app/components/curriculum-inventory/verification-preview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|7312526529ca39ed820819d1478d8e1b8f555279|1721088000000|1723680000000|1726272000000|app/components/instructor-group/header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|10c85f1f7f9cf2d05a7f36c4618679ea04c51154|1721088000000|1723680000000|1726272000000|app/components/instructor-group/header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|7312526529ca39ed820819d1478d8e1b8f555279|1721088000000|1723680000000|1726272000000|app/components/learner-group/header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|c33c821719fcbe918954f20b45e0959a3a40c62b|1721088000000|1723680000000|1726272000000|app/components/learner-group/header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|cb6d7acb9879902b89ad1575846d290a564ffbae|1721088000000|1723680000000|1726272000000|app/components/learner-group/instructor-manager.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|2bdc98d02ac5ea2a4bd5bac6a0f9e880abafdcbe|1721088000000|1723680000000|1726272000000|app/components/learner-group/instructor-manager.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|4|4|4|170987df2d1e4c134a0ac459fc0bdd8dd91b9929|1721088000000|1723680000000|1726272000000|app/components/learner-group/root.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|4|5|4|7c59a55b95fd159dd99afa6b20e5f05b5b68def0|1721088000000|1723680000000|1726272000000|app/components/learner-group/root.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|4|4|4|66fe3cf991d61995cda5f5935874230700b5e21f|1721088000000|1723680000000|1726272000000|app/components/program/header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|4|5|4|0bcfaa7865c6a954a5b5226ffe44ddc6c63945ba|1721088000000|1723680000000|1726272000000|app/components/program/header.hbs +add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|66fe3cf991d61995cda5f5935874230700b5e21f|1721088000000|1723680000000|1726272000000|app/components/program/overview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|0bcfaa7865c6a954a5b5226ffe44ddc6c63945ba|1721088000000|1723680000000|1726272000000|app/components/program/overview.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|12f77ac1f8c43640397b771ba2c9830dd2041f23|1721088000000|1723680000000|1726272000000|app/components/program-year/collapsed-objectives.hbs +add|ember-template-lint|no-at-ember-render-modifiers|6|2|6|2|87dcba868bd23c9305b095ffbda9e90ab5b4918e|1721088000000|1723680000000|1726272000000|app/components/program-year/collapsed-objectives.hbs +add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|b759467cf4c3dc1d7e39d4bed1d085d51090d363|1721088000000|1723680000000|1726272000000|app/components/program-year/objective-list-item-expanded.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|c4f87a15e0dbf28e3a3b95d7b8259a419f93b29d|1721088000000|1723680000000|1726272000000|app/components/program-year/objective-list-item-expanded.hbs +add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|fc55335d86e2b3d97a0614f6c046ba360820801c|1721088000000|1723680000000|1726272000000|app/components/program-year/objective-list-item.hbs +add|ember-template-lint|no-at-ember-render-modifiers|6|2|6|2|12443b4ba50f603e3c3af3d9e10ce840e7b67d9e|1721088000000|1723680000000|1726272000000|app/components/program-year/objective-list-item.hbs +add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|286929067e02096dda5597efc45c876218621874|1721088000000|1723680000000|1726272000000|app/components/program-year/objectives.hbs +add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|f37fd8ee0b117114a09137593ed6f113b2c80806|1721088000000|1723680000000|1726272000000|app/components/program-year/objectives.hbs +add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/academic-year.hbs +add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/academic-year.hbs +add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/competency.hbs +add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/competency.hbs +add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/instructor-group.hbs +add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/instructor-group.hbs +add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/program-year.hbs +add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/program-year.hbs +add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/program.hbs +add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/program.hbs +add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/session-type.hbs +add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/session-type.hbs +add|ember-template-lint|no-at-ember-render-modifiers|10|6|10|6|d919d2af254f782c01fe2ba15416673e52e91124|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/term.hbs +add|ember-template-lint|no-at-ember-render-modifiers|11|6|11|6|940005188b476a060b0e5d3f05baea24ba178878|1721088000000|1723680000000|1726272000000|app/components/reports/subject/new/term.hbs diff --git a/packages/frontend/config/environment.js b/packages/frontend/config/environment.js index 3987f9e425..031f27ebca 100644 --- a/packages/frontend/config/environment.js +++ b/packages/frontend/config/environment.js @@ -47,6 +47,11 @@ module.exports = function (environment) { visualNoiseLevel: 1, }, }, + 'ember-local-storage': { + namespace: true, + keyDelimiter: '/', + includeEmberDataSupport: false, + }, fontawesome: { enableExperimentalBuildTimeTransform: false, defaultPrefix: 'fas', diff --git a/packages/frontend/tests/acceptance/dashboard/calendar-test.js b/packages/frontend/tests/acceptance/dashboard/calendar-test.js index 19a7f07b2d..4139df4f09 100644 --- a/packages/frontend/tests/acceptance/dashboard/calendar-test.js +++ b/packages/frontend/tests/acceptance/dashboard/calendar-test.js @@ -1,19 +1,10 @@ -import { - click, - findAll, - find, - currentURL, - currentRouteName, - visit, - triggerEvent, -} from '@ember/test-helpers'; -import { isEmpty } from '@ember/utils'; +import { currentURL, currentRouteName } from '@ember/test-helpers'; import { DateTime } from 'luxon'; import { module, test } from 'qunit'; import { setupAuthentication, freezeDateAt, unfreezeDate } from 'ilios-common'; import { setupApplicationTest } from 'frontend/tests/helpers'; -import { map } from 'rsvp'; import page from 'ilios-common/page-objects/dashboard-calendar'; +import resetStorages from 'ember-local-storage/test-support/reset-storage'; import percySnapshot from '@percy/ember'; module('Acceptance | Dashboard Calendar', function (hooks) { @@ -89,6 +80,10 @@ module('Acceptance | Dashboard Calendar', function (hooks) { hooks.afterEach(() => { unfreezeDate(); + if (window.localStorage) { + window.localStorage.clear(); + } + resetStorages(); }); test('load month calendar', async function (assert) { @@ -117,11 +112,10 @@ module('Acceptance | Dashboard Calendar', function (hooks) { endDate: endOfMonth.plus({ hour: 1 }).toJSDate(), lastModified: today.minus({ year: 1 }), }); - await visit('/dashboard/calendar?view=month'); + await page.visit({ view: 'month' }); await percySnapshot(assert); assert.strictEqual(currentRouteName(), 'dashboard.calendar'); - const events = findAll('[data-test-ilios-calendar-event]'); - assert.strictEqual(events.length, 2); + assert.strictEqual(page.calendar.calendar.monthly.events.length, 2); const startOfMonthStartFormat = this.intl.formatTime(startOfMonth.toJSDate(), { hour: '2-digit', minute: '2-digit', @@ -130,9 +124,10 @@ module('Acceptance | Dashboard Calendar', function (hooks) { hour: '2-digit', minute: '2-digit', }); - assert - .dom(events[0]) - .hasText(`${startOfMonthStartFormat} - ${startOfMonthEndFormat} : start of month`); + assert.strictEqual( + page.calendar.calendar.monthly.events[0].text, + `${startOfMonthStartFormat} - ${startOfMonthEndFormat} : start of month`, + ); const endOfMonthStartFormat = this.intl.formatTime(endOfMonth.toJSDate(), { hour: 'numeric', minute: 'numeric', @@ -141,9 +136,10 @@ module('Acceptance | Dashboard Calendar', function (hooks) { hour: 'numeric', minute: 'numeric', }); - assert - .dom(events[1]) - .hasText(`${endOfMonthStartFormat} - ${endOfMonthEndFormat} : end of month`); + assert.strictEqual( + page.calendar.calendar.monthly.events[1].text, + `${endOfMonthStartFormat} - ${endOfMonthEndFormat} : end of month`, + ); }); test('load week calendar', async function (assert) { @@ -187,18 +183,18 @@ module('Acceptance | Dashboard Calendar', function (hooks) { await percySnapshot(assert); assert.strictEqual(currentRouteName(), 'dashboard.calendar'); - assert.strictEqual(page.calendar.weeklyCalendar.dayHeadings.length, 7); - assert.ok(page.calendar.weeklyCalendar.dayHeadings[0].isFirstDayOfWeek); + assert.strictEqual(page.calendar.calendar.weekly.dayHeadings.length, 7); + assert.ok(page.calendar.calendar.weekly.dayHeadings[0].isFirstDayOfWeek); assert.strictEqual( - page.calendar.weeklyCalendar.dayHeadings[0].text, + page.calendar.calendar.weekly.dayHeadings[0].text, `Sunday Sun ${longDayHeading} ${shortDayHeading}`, ); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - assert.ok(page.calendar.weeklyCalendar.events[0].isFirstDayOfWeek); - assert.strictEqual(page.calendar.weeklyCalendar.events[0].name, 'start of week'); - assert.ok(page.calendar.weeklyCalendar.events[1].isSeventhDayOfWeek); - assert.strictEqual(page.calendar.weeklyCalendar.events[1].name, 'end of week'); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + assert.ok(page.calendar.calendar.weekly.events[0].isFirstDayOfWeek); + assert.strictEqual(page.calendar.calendar.weekly.events[0].name, 'start of week'); + assert.ok(page.calendar.calendar.weekly.events[1].isSeventhDayOfWeek); + assert.strictEqual(page.calendar.calendar.weekly.events[1].name, 'end of week'); }); test('load week calendar on Sunday', async function (assert) { @@ -242,22 +238,22 @@ module('Acceptance | Dashboard Calendar', function (hooks) { await page.visit({ show: 'calendar' }); assert.strictEqual(currentRouteName(), 'dashboard.calendar'); - assert.strictEqual(page.calendar.weeklyCalendar.dayHeadings.length, 7); - assert.ok(page.calendar.weeklyCalendar.dayHeadings[0].isFirstDayOfWeek); + assert.strictEqual(page.calendar.calendar.weekly.dayHeadings.length, 7); + assert.ok(page.calendar.calendar.weekly.dayHeadings[0].isFirstDayOfWeek); assert.strictEqual( - page.calendar.weeklyCalendar.dayHeadings[0].text, + page.calendar.calendar.weekly.dayHeadings[0].text, `Sunday Sun ${longDayHeading} ${shortDayHeading}`, ); assert.strictEqual( - page.calendar.weeklyCalendar.title.longWeekOfYear, + page.calendar.calendar.weekly.title.longWeekOfYear, 'Week of October 9, 2022', ); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - assert.ok(page.calendar.weeklyCalendar.events[0].isFirstDayOfWeek); - assert.strictEqual(page.calendar.weeklyCalendar.events[0].name, 'start of week'); - assert.ok(page.calendar.weeklyCalendar.events[1].isSeventhDayOfWeek); - assert.strictEqual(page.calendar.weeklyCalendar.events[1].name, 'end of week'); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + assert.ok(page.calendar.calendar.weekly.events[0].isFirstDayOfWeek); + assert.strictEqual(page.calendar.calendar.weekly.events[0].name, 'start of week'); + assert.ok(page.calendar.calendar.weekly.events[1].isSeventhDayOfWeek); + assert.strictEqual(page.calendar.calendar.weekly.events[1].name, 'end of week'); }); test('load day calendar', async function (assert) { @@ -293,12 +289,12 @@ module('Acceptance | Dashboard Calendar', function (hooks) { endDate: yesterday.plus({ hour: 1 }).toJSDate(), lastModified: today.minus({ year: 1 }), }); - await visit('/dashboard/calendar?view=day'); + await page.visit({ view: 'day' }); await percySnapshot(assert); assert.strictEqual(currentRouteName(), 'dashboard.calendar'); - assert.strictEqual(page.calendar.dailyCalendar.events.length, 1); - assert.strictEqual(page.calendar.dailyCalendar.events[0].name, 'today'); + assert.strictEqual(page.calendar.calendar.daily.events.length, 1); + assert.strictEqual(page.calendar.calendar.daily.events[0].name, 'today'); }); test('invalid date loads today #5342', async function (assert) { @@ -310,9 +306,9 @@ module('Acceptance | Dashboard Calendar', function (hooks) { day: 24, }).toJSDate(), ); - await visit('/dashboard/calendar?view=day&date=somethinginvalid'); + await page.visit({ view: 'day', date: 'somethinginvalid' }); assert.strictEqual(currentRouteName(), 'dashboard.calendar'); - assert.strictEqual(page.calendar.dailyCalendar.title.longDayOfWeek, 'Friday, June 24, 2005'); + assert.strictEqual(page.calendar.calendar.daily.title.longDayOfWeek, 'Friday, June 24, 2005'); }); test('click month day number and go to day', async function (assert) { @@ -323,8 +319,8 @@ module('Acceptance | Dashboard Calendar', function (hooks) { startDate: aDayInTheMonth.toJSDate(), endDate: aDayInTheMonth.plus({ hour: 1 }).toJSDate(), }); - await visit('/dashboard/calendar?view=month'); - await click(`[data-test-day-button="${aDayInTheMonth.day}"]`); + await page.visit({ view: 'month' }); + await page.calendar.calendar.monthly.days[aDayInTheMonth.day - 1].selectDay(); assert.strictEqual( currentURL(), '/dashboard/calendar?date=' + aDayInTheMonth.toFormat('y-MM-dd') + '&view=day', @@ -346,11 +342,11 @@ module('Acceptance | Dashboard Calendar', function (hooks) { endDate: june24th2005.plus({ hour: 1 }).toJSDate(), }); await page.visit({ show: 'calendar', view: 'week' }); - assert.strictEqual(page.calendar.weeklyCalendar.dayHeadings.length, 7); - await page.calendar.weeklyCalendar.dayHeadings[0].selectDay(); + assert.strictEqual(page.calendar.calendar.weekly.dayHeadings.length, 7); + await page.calendar.calendar.weekly.dayHeadings[0].selectDay(); assert.strictEqual(currentURL(), '/dashboard/calendar?date=2005-06-19&view=day'); await page.visit({ show: 'calendar', view: 'week' }); - await page.calendar.weeklyCalendar.dayHeadings[5].selectDay(); + await page.calendar.calendar.weekly.dayHeadings[5].selectDay(); assert.strictEqual(currentURL(), '/dashboard/calendar?date=2005-06-24&view=day'); }); @@ -362,8 +358,8 @@ module('Acceptance | Dashboard Calendar', function (hooks) { startDate: today.toJSDate(), endDate: today.plus({ hour: 1 }).toJSDate(), }); - await visit('/dashboard/calendar?view=day'); - await click('.calendar-time-picker li:nth-of-type(3) a'); + await page.visit({ view: 'day' }); + await page.calendar.calendar.goForward.click(); assert.strictEqual( currentURL(), '/dashboard/calendar?date=' + today.plus({ day: 1 }).toFormat('y-MM-dd') + '&view=day', @@ -378,8 +374,8 @@ module('Acceptance | Dashboard Calendar', function (hooks) { startDate: today.toJSDate(), endDate: today.plus({ hour: 1 }).toJSDate(), }); - await visit('/dashboard/calendar?view=week'); - await click('.calendar-time-picker li:nth-of-type(3) a'); + await page.visit({ view: 'week' }); + await page.calendar.calendar.goForward.click(); assert.strictEqual( currentURL(), '/dashboard/calendar?date=' + today.plus({ week: 1 }).toFormat('y-MM-dd'), @@ -394,9 +390,8 @@ module('Acceptance | Dashboard Calendar', function (hooks) { startDate: today.toJSDate(), endDate: today.plus({ hour: 1 }).toJSDate(), }); - await visit('/dashboard/calendar?view=month'); - await click('.calendar-time-picker li:nth-of-type(3) a'); - await click(findAll('.calendar-time-picker li')[2]); + await page.visit({ view: 'month' }); + await page.calendar.calendar.goForward.click(); assert.strictEqual( currentURL(), '/dashboard/calendar?date=' + today.plus({ month: 1 }).toFormat('y-MM-dd') + '&view=month', @@ -411,8 +406,8 @@ module('Acceptance | Dashboard Calendar', function (hooks) { startDate: today.toJSDate(), endDate: today.plus({ hour: 1 }).toJSDate(), }); - await visit('/dashboard/calendar?view=day'); - await click('.calendar-time-picker li:nth-of-type(1) a'); + await page.visit({ view: 'day' }); + await page.calendar.calendar.goBack.click(); assert.strictEqual( currentURL(), '/dashboard/calendar?date=' + today.minus({ day: 1 }).toFormat('y-MM-dd') + '&view=day', @@ -427,8 +422,8 @@ module('Acceptance | Dashboard Calendar', function (hooks) { startDate: today.toJSDate(), endDate: today.plus({ hour: 1 }).toJSDate(), }); - await visit('/dashboard/calendar?view=week'); - await click('.calendar-time-picker li:nth-of-type(1) a'); + await page.visit({ view: 'week' }); + await page.calendar.calendar.goBack.click(); assert.strictEqual( currentURL(), '/dashboard/calendar?date=' + today.minus({ week: 1 }).toFormat('y-MM-dd'), @@ -443,8 +438,8 @@ module('Acceptance | Dashboard Calendar', function (hooks) { startDate: today.toJSDate(), endDate: today.plus({ hour: 1 }).toJSDate(), }); - await visit('/dashboard/calendar?view=month'); - await click('.calendar-time-picker li:nth-of-type(1) a'); + await page.visit({ view: 'month' }); + await page.calendar.calendar.goBack.click(); assert.strictEqual( currentURL(), '/dashboard/calendar?date=' + today.minus({ month: 1 }).toFormat('y-MM-dd') + '&view=month', @@ -476,12 +471,9 @@ module('Acceptance | Dashboard Calendar', function (hooks) { }); await page.visit({ show: 'calendar' }); await percySnapshot(assert); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); }); - const chooseSchoolEvents = async function () { - return await click(find(findAll('.togglemyschedule label')[1])); - }; test('show school events', async function (assert) { assert.expect(1); const day = DateTime.fromObject({ @@ -506,18 +498,164 @@ module('Acceptance | Dashboard Calendar', function (hooks) { offering: 2, }); await page.visit(); - await chooseSchoolEvents(); + await page.calendar.controls.mySchedule.toggle.secondLabel.click(); await percySnapshot(assert); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); }); - const showFilters = async function () { - return await click('.showfilters label:nth-of-type(2)'); - }; + test('user context filters are not present on student-only user calendar', async function (assert) { + assert.expect(1); + await page.visit({ show: 'calendar' }); + assert.notOk(page.calendar.controls.userContextFilter.isPresent); + }); - const pickSessionType = async function (i) { - return await click(find(`.sessiontypefilter li:nth-of-type(${i}) [data-test-target]`)); - }; + test('user context filters are present on user calendar for privileged users', async function (assert) { + assert.expect(1); + await setupAuthentication({ school: this.school }, true); + await page.visit({ show: 'calendar' }); + await percySnapshot(assert); + assert.ok(page.calendar.controls.userContextFilter.isPresent); + }); + + test('user context filters are not present on school calendar', async function (assert) { + assert.expect(2); + await setupAuthentication({ school: this.school }, true); + await page.visit({ show: 'calendar' }); + assert.ok(page.calendar.controls.userContextFilter.isPresent); + await page.calendar.controls.mySchedule.toggle.secondLabel.click(); + await percySnapshot(assert); + assert.notOk(page.calendar.controls.userContextFilter.isPresent); + }); + + test('test user context filters', async function (assert) { + assert.expect(11); + this.user = await setupAuthentication({ school: this.school }, true); + const day = DateTime.fromObject({ + month: 4, + day: 4, + year: 2004, + hour: 4, + minute: 0, + second: 7, + }); + freezeDateAt(day.toJSDate()); + this.server.create('userevent', { + user: this.user.id, + startDate: day.toJSDate(), + endDate: day.plus({ hour: 1 }).toJSDate(), + offering: 1, + userContexts: ['learner'], + }); + this.server.create('userevent', { + user: this.user.id, + startDate: day.plus({ hour: 1 }).toJSDate(), + endDate: day.plus({ hour: 2 }).toJSDate(), + offering: 2, + userContexts: ['instructor'], + }); + this.server.create('userevent', { + user: this.user.id, + startDate: day.plus({ hour: 2 }).toJSDate(), + endDate: day.plus({ hour: 3 }).toJSDate(), + offering: 3, + userContexts: ['course director'], + }); + await page.visit({ show: 'calendar' }); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 3); + assert.strictEqual(page.calendar.calendar.weekly.events[0].text, '04:00 AM event 0'); + assert.strictEqual(page.calendar.calendar.weekly.events[1].text, '05:00 AM event 1'); + assert.strictEqual(page.calendar.calendar.weekly.events[2].text, '06:00 AM event 2'); + await page.calendar.controls.userContextFilter.learning.toggle(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); + assert.strictEqual(page.calendar.calendar.weekly.events[0].text, '04:00 AM event 0'); + await page.calendar.controls.userContextFilter.instructing.toggle(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); + assert.strictEqual(page.calendar.calendar.weekly.events[0].text, '05:00 AM event 1'); + await page.calendar.controls.userContextFilter.admin.toggle(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); + assert.strictEqual(page.calendar.calendar.weekly.events[0].text, '06:00 AM event 2'); + await page.calendar.controls.userContextFilter.admin.toggle(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 3); + }); + + test('user context filter selections persist across page reloads', async function (assert) { + assert.expect(27); + this.user = await setupAuthentication({ school: this.school }, true); + const day = DateTime.fromObject({ + month: 4, + day: 4, + year: 2004, + hour: 4, + minute: 0, + second: 7, + }); + freezeDateAt(day.toJSDate()); + this.server.create('userevent', { + user: this.user.id, + startDate: day.toJSDate(), + endDate: day.plus({ hour: 1 }).toJSDate(), + offering: 1, + userContexts: ['learner'], + }); + this.server.create('userevent', { + user: this.user.id, + startDate: day.plus({ hour: 1 }).toJSDate(), + endDate: day.plus({ hour: 2 }).toJSDate(), + offering: 2, + userContexts: ['instructor'], + }); + this.server.create('userevent', { + user: this.user.id, + startDate: day.plus({ hour: 2 }).toJSDate(), + endDate: day.plus({ hour: 3 }).toJSDate(), + offering: 3, + userContexts: ['course director'], + }); + await page.visit({ show: 'calendar' }); + assert.ok(page.calendar.controls.userContextFilter.learning.isActive); + assert.ok(page.calendar.controls.userContextFilter.instructing.isActive); + assert.ok(page.calendar.controls.userContextFilter.admin.isActive); + + await page.calendar.controls.userContextFilter.learning.toggle(); + assert.ok(page.calendar.controls.userContextFilter.learning.isActive); + assert.notOk(page.calendar.controls.userContextFilter.instructing.isActive); + assert.notOk(page.calendar.controls.userContextFilter.admin.isActive); + + await page.visit({ show: 'calendar' }); + assert.ok(page.calendar.controls.userContextFilter.learning.isActive); + assert.notOk(page.calendar.controls.userContextFilter.instructing.isActive); + assert.notOk(page.calendar.controls.userContextFilter.admin.isActive); + + await page.calendar.controls.userContextFilter.instructing.toggle(); + assert.notOk(page.calendar.controls.userContextFilter.learning.isActive); + assert.ok(page.calendar.controls.userContextFilter.instructing.isActive); + assert.notOk(page.calendar.controls.userContextFilter.admin.isActive); + + await page.visit({ show: 'calendar' }); + assert.notOk(page.calendar.controls.userContextFilter.learning.isActive); + assert.ok(page.calendar.controls.userContextFilter.instructing.isActive); + assert.notOk(page.calendar.controls.userContextFilter.admin.isActive); + + await page.calendar.controls.userContextFilter.admin.toggle(); + assert.notOk(page.calendar.controls.userContextFilter.learning.isActive); + assert.notOk(page.calendar.controls.userContextFilter.instructing.isActive); + assert.ok(page.calendar.controls.userContextFilter.admin.isActive); + + await page.visit({ show: 'calendar' }); + assert.notOk(page.calendar.controls.userContextFilter.learning.isActive); + assert.notOk(page.calendar.controls.userContextFilter.instructing.isActive); + assert.ok(page.calendar.controls.userContextFilter.admin.isActive); + + await page.calendar.controls.userContextFilter.admin.toggle(); + assert.ok(page.calendar.controls.userContextFilter.learning.isActive); + assert.ok(page.calendar.controls.userContextFilter.instructing.isActive); + assert.ok(page.calendar.controls.userContextFilter.admin.isActive); + + await page.visit({ show: 'calendar' }); + assert.ok(page.calendar.controls.userContextFilter.learning.isActive); + assert.ok(page.calendar.controls.userContextFilter.instructing.isActive); + assert.ok(page.calendar.controls.userContextFilter.admin.isActive); + }); test('test session type filter', async function (assert) { const today = DateTime.fromObject({ hour: 8, minute: 8, second: 8 }); @@ -534,26 +672,18 @@ module('Acceptance | Dashboard Calendar', function (hooks) { sessionTypeId: 2, }); await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - await pickSessionType(1); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 1); - await pickSessionType(2); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - - await pickSessionType(1); - await pickSessionType(2); - await pickSessionType(3); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 0); - }); - - const pickCourseLevel = async function (i) { - return await click(find(`.courselevelfilter li:nth-of-type(${i}) [data-test-target]`)); - }; - const clearCourseLevels = async function () { - const selected = findAll('.courselevelfilter [data-test-checked]'); - await map(selected, (e) => click(e)); - }; + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + await page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); + await page.calendar.controls.filters.sessionTypesFilter.sessionTypes[1].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + + await page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].click(); + await page.calendar.controls.filters.sessionTypesFilter.sessionTypes[1].click(); + await page.calendar.controls.filters.sessionTypesFilter.sessionTypes[2].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 0); + }); test('test course level filter', async function (assert) { const today = DateTime.fromObject({ hour: 8, minute: 8, second: 8 }); @@ -570,21 +700,15 @@ module('Acceptance | Dashboard Calendar', function (hooks) { courseLevel: 1, }); await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - await chooseDetailFilter(); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - await pickCourseLevel(1); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - await clearCourseLevels(); - await pickCourseLevel(3); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 0); - }); - - const pickCohort = async function (i) { - return await click( - find(`[data-test-cohort-calendar-filter] li:nth-of-type(${i}) [data-test-target]`), - ); - }; + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + await page.calendar.controls.showCourseFilters.toggle.secondLabel.click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + await page.calendar.controls.filters.courseLevelsFilter.courseLevels[0].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + await page.calendar.filterTags.clearAll.click(); + await page.calendar.controls.filters.courseLevelsFilter.courseLevels[1].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 0); + }); test('test cohort filter', async function (assert) { const today = DateTime.fromObject({ hour: 8, minute: 8, second: 8 }); @@ -601,30 +725,17 @@ module('Acceptance | Dashboard Calendar', function (hooks) { cohorts: [{ id: 1 }], }); await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - await chooseDetailFilter(); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - await pickCohort(2); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - - await pickCohort(1); - await pickCohort(2); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 0); - }); + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + await page.calendar.controls.showCourseFilters.toggle.secondLabel.click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); - const chooseDetailFilter = async function () { - return await click(find(findAll('.togglecoursefilters label')[1])); - }; + await page.calendar.controls.filters.cohortsFilter.cohorts[1].toggle(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); - const pickCourse = async function (i) { - return await click( - find(`[data-test-courses-calendar-filter] li:nth-of-type(${i}) [data-test-target]`), - ); - }; - const clearCourses = async function () { - const selected = findAll('[data-test-courses-calendar-filter] [data-test-checked]'); - await map(selected, (e) => click(e)); - }; + await page.calendar.controls.filters.cohortsFilter.cohorts[0].toggle(); + await page.calendar.controls.filters.cohortsFilter.cohorts[1].toggle(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 0); + }); test('test course filter', async function (assert) { const today = DateTime.fromObject({ hour: 8, minute: 8, second: 8 }); @@ -647,13 +758,13 @@ module('Acceptance | Dashboard Calendar', function (hooks) { course: 1, }); await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 3); - await pickCourse(1); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - await clearCourses(); - await pickCourse(2); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 1); + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 3); + await page.calendar.controls.filters.coursesFilter.years[0].courses[0].toggle(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + await page.calendar.controls.filters.coursesFilter.years[0].courses[0].toggle(); + await page.calendar.controls.filters.coursesFilter.years[0].courses[1].toggle(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); }); test('test course and session type filter together', async function (assert) { @@ -680,19 +791,19 @@ module('Acceptance | Dashboard Calendar', function (hooks) { sessionTypeId: 2, }); await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 3); - await pickCourse(1); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - await clearCourses(); - await pickCourse(1); - await pickSessionType(1); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 1); + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + + assert.strictEqual(page.calendar.calendar.weekly.events.length, 3); + await page.calendar.controls.filters.coursesFilter.years[0].courses[0].toggle(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + await page.calendar.controls.filters.coursesFilter.years[0].courses[0].toggle(); + await page.calendar.controls.filters.coursesFilter.years[0].courses[0].toggle(); + await page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); }); test('clear all filters', async function (assert) { - assert.expect(9); + assert.expect(18); const vocabulary = this.server.create('vocabulary', { school: this.school, }); @@ -700,98 +811,116 @@ module('Acceptance | Dashboard Calendar', function (hooks) { vocabulary, }); - const clearFilter = '.filters-clear-filters'; - const sessiontype = '.sessiontypefilter li:nth-of-type(1) input'; - const course = '[data-test-courses-calendar-filter] li:nth-of-type(1) input'; - const term = '.vocabularyfilter li:nth-of-type(1) input'; - await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - assert.ok(isEmpty(find(clearFilter)), 'clear filter button is inactive'); - - await click(sessiontype); - await click(course); - await click(term); + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + assert.notOk(page.calendar.filterTags.clearAll.isPresent); + assert.strictEqual(page.calendar.filterTags.tags.length, 0); + + await page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].click(); + assert.strictEqual(page.calendar.filterTags.tags.length, 1); + await page.calendar.controls.filters.coursesFilter.years[0].courses[0].toggle(); + assert.strictEqual(page.calendar.filterTags.tags.length, 2); + await page.calendar.controls.filters.vocabularyFilter.vocabularies[0].selectedTermTree.checkboxes[0].click(); + assert.strictEqual(page.calendar.filterTags.tags.length, 3); + + assert.ok(page.calendar.filterTags.clearAll.isPresent); + assert.strictEqual(page.calendar.filterTags.clearAll.text, 'Clear Filters'); + assert.strictEqual(page.calendar.filterTags.tags[0].text, '2015 course 0'); + assert.strictEqual(page.calendar.filterTags.tags[1].text, 'session type 0'); + assert.strictEqual(page.calendar.filterTags.tags[2].text, 'Vocabulary 1 > term 0'); + assert.ok(page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].isChecked); + assert.ok(page.calendar.controls.filters.coursesFilter.years[0].courses[0].isChecked); + assert.ok( + page.calendar.controls.filters.vocabularyFilter.vocabularies[0].selectedTermTree.checkboxes[0] + .isChecked, + ); - assert.dom(clearFilter).hasText('Clear Filters', 'clear filter button is active'); - assert.dom(sessiontype).isChecked('filter is checked'); - assert.dom(course).isChecked('filter is checked'); - assert.dom(term).isChecked('filter is checked'); + await page.calendar.filterTags.clearAll.click(); - await click(clearFilter); - assert.ok(isEmpty(find(clearFilter)), 'clear filter button is inactive'); - assert.dom(sessiontype).isNotChecked('filter is unchecked'); - assert.dom(course).isNotChecked('filter is unchecked'); - assert.dom(term).isNotChecked('filter is unchecked'); + assert.notOk(page.calendar.filterTags.clearAll.isPresent); + assert.strictEqual(page.calendar.filterTags.tags.length, 0); + assert.notOk(page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].isChecked); + assert.notOk(page.calendar.controls.filters.coursesFilter.years[0].courses[0].isChecked); + assert.notOk( + page.calendar.controls.filters.vocabularyFilter.vocabularies[0].selectedTermTree.checkboxes[0] + .isChecked, + ); }); test('clear all detail filters', async function (assert) { - const clearFilter = '.filters-clear-filters'; - const sessiontype = '.sessiontypefilter li:nth-of-type(1) input'; - const courselevel = '.courselevelfilter li:nth-of-type(1) input'; - const cohort = '[data-test-cohort-calendar-filter] li:nth-of-type(1) input'; - await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - await chooseDetailFilter(); - assert.ok(isEmpty(find(clearFilter)), 'clear filter button is inactive'); - - await click(sessiontype); - await click(courselevel); - await click(cohort); - - assert.dom(clearFilter).hasText('Clear Filters', 'clear filter button is active'); - assert.dom(sessiontype).isChecked('filter is checked'); - assert.dom(courselevel).isChecked('filter is checked'); - assert.dom(cohort).isChecked('filter is checked'); - - await click(clearFilter); - assert.ok(isEmpty(find(clearFilter)), 'clear filter button is inactive'); - assert.dom(sessiontype).isNotChecked('filter is unchecked'); - assert.dom(courselevel).isNotChecked('filter is unchecked'); - assert.dom(cohort).isNotChecked('filter is unchecked'); + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + await page.calendar.controls.showCourseFilters.toggle.secondLabel.click(); + assert.notOk(page.calendar.filterTags.clearAll.isPresent); + + await page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].click(); + assert.strictEqual(page.calendar.filterTags.tags.length, 1); + await page.calendar.controls.filters.courseLevelsFilter.courseLevels[0].click(); + assert.strictEqual(page.calendar.filterTags.tags.length, 2); + await page.calendar.controls.filters.cohortsFilter.cohorts[0].toggle(); + assert.strictEqual(page.calendar.filterTags.tags.length, 3); + + assert.ok(page.calendar.filterTags.clearAll.isPresent); + assert.strictEqual(page.calendar.filterTags.tags[0].text, 'cohort 1 program 0'); + assert.strictEqual(page.calendar.filterTags.tags[1].text, 'Course Level 1'); + assert.strictEqual(page.calendar.filterTags.tags[2].text, 'session type 0'); + assert.ok(page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].isChecked); + assert.ok(page.calendar.controls.filters.courseLevelsFilter.courseLevels[0].isChecked); + assert.ok(page.calendar.controls.filters.cohortsFilter.cohorts[0].isChecked); + + await page.calendar.filterTags.clearAll.click(); + + assert.notOk(page.calendar.filterTags.clearAll.isPresent); + assert.notOk(page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].isChecked); + assert.notOk(page.calendar.controls.filters.courseLevelsFilter.courseLevels[0].isChecked); + assert.notOk(page.calendar.controls.filters.cohortsFilter.cohorts[0].isChecked); }); test('filter tags work properly', async function (assert) { - const sessiontype = '.sessiontypefilter li:nth-of-type(1) [data-test-target]'; - const courselevel = '.courselevelfilter li:nth-of-type(1) [data-test-target]'; - const cohort = '[data-test-cohort-calendar-filter] li:nth-of-type(2) [data-test-target]'; - - const filtersList = '.filters-list'; - const clearFilter = '.filters-clear-filters'; - - function getTagText(n) { - return find(`.filter-tag:nth-of-type(${n + 1})`).textContent.trim(); - } - - async function clickTag(n) { - return await click(`.filter-tag:nth-of-type(${n + 1})`); - } - await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - await chooseDetailFilter(); - assert.ok(isEmpty(find(filtersList)), 'filter tags list is inactive'); - - await click(sessiontype); - await click(courselevel); - await click(cohort); - assert.strictEqual(getTagText(0), 'cohort 0 program 0', 'filter tag is active'); - assert.strictEqual(getTagText(1), 'Course Level 1', 'filter tag is active'); - assert.strictEqual(getTagText(2), 'session type 0', 'filter tag is active'); - - await clickTag(1); - assert.dom(courselevel).isNotChecked('filter is unchecked'); - assert.strictEqual(getTagText(0), 'cohort 0 program 0', 'filter tag is active'); - assert.strictEqual(getTagText(1), 'session type 0', 'filter tag is active'); - - await clickTag(0); - assert.strictEqual(getTagText(0), 'session type 0', 'filter tag is active'); - - await click(clearFilter); - assert.ok(isEmpty(find(filtersList)), 'filter tags list is inactive'); - assert.dom(sessiontype).isNotChecked('filter is unchecked'); - assert.dom(cohort).isNotChecked('filter is unchecked'); + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + await page.calendar.controls.showCourseFilters.toggle.secondLabel.click(); + assert.notOk(page.calendar.filterTags.clearAll.isPresent); + + await page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].click(); + await page.calendar.controls.filters.courseLevelsFilter.courseLevels[0].click(); + await page.calendar.controls.filters.cohortsFilter.cohorts[0].toggle(); + + assert.ok(page.calendar.filterTags.clearAll.isPresent); + assert.strictEqual(page.calendar.filterTags.tags.length, 3); + assert.strictEqual(page.calendar.filterTags.tags[0].text, 'cohort 1 program 0'); + assert.strictEqual(page.calendar.filterTags.tags[1].text, 'Course Level 1'); + assert.strictEqual(page.calendar.filterTags.tags[2].text, 'session type 0'); + assert.ok(page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].isChecked); + assert.ok(page.calendar.controls.filters.courseLevelsFilter.courseLevels[0].isChecked); + assert.ok(page.calendar.controls.filters.cohortsFilter.cohorts[0].isChecked); + + await page.calendar.filterTags.tags[0].click(); + + assert.ok(page.calendar.filterTags.clearAll.isPresent); + assert.strictEqual(page.calendar.filterTags.tags.length, 2); + assert.strictEqual(page.calendar.filterTags.tags[0].text, 'Course Level 1'); + assert.strictEqual(page.calendar.filterTags.tags[1].text, 'session type 0'); + assert.ok(page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].isChecked); + assert.ok(page.calendar.controls.filters.courseLevelsFilter.courseLevels[0].isChecked); + assert.notOk(page.calendar.controls.filters.cohortsFilter.cohorts[0].isChecked); + + await page.calendar.filterTags.tags[0].click(); + + assert.ok(page.calendar.filterTags.clearAll.isPresent); + assert.strictEqual(page.calendar.filterTags.tags.length, 1); + assert.strictEqual(page.calendar.filterTags.tags[0].text, 'session type 0'); + assert.ok(page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].isChecked); + assert.notOk(page.calendar.controls.filters.courseLevelsFilter.courseLevels[0].isChecked); + assert.notOk(page.calendar.controls.filters.cohortsFilter.cohorts[0].isChecked); + + await page.calendar.filterTags.tags[0].click(); + + assert.notOk(page.calendar.filterTags.clearAll.isPresent); + assert.strictEqual(page.calendar.filterTags.tags.length, 0); + assert.notOk(page.calendar.controls.filters.sessionTypesFilter.sessionTypes[0].isChecked); + assert.notOk(page.calendar.controls.filters.courseLevelsFilter.courseLevels[0].isChecked); + assert.notOk(page.calendar.controls.filters.cohortsFilter.cohorts[0].isChecked); }); test('calendar is active in dashboard navigation', async function (assert) { @@ -801,53 +930,6 @@ module('Acceptance | Dashboard Calendar', function (hooks) { assert.notOk(page.navigation.week.isActive); }); - test('week summary displays the whole week', async function (assert) { - assert.expect(3); - const startOfTheWeek = DateTime.fromJSDate( - this.owner.lookup('service:locale-days').firstDayOfThisWeek, - ).set({ minute: 2 }); - const endOfTheWeek = DateTime.fromJSDate( - this.owner.lookup('service:locale-days').lastDayOfThisWeek, - ).set({ hour: 22, minute: 5 }); - - this.server.create('userevent', { - user: this.user.id, - startDate: startOfTheWeek.toJSDate(), - endDate: startOfTheWeek.plus({ hour: 1 }).toJSDate(), - offering: 1, - isPublished: true, - }); - this.server.create('userevent', { - user: this.user.id, - startDate: endOfTheWeek.toJSDate(), - endDate: endOfTheWeek.plus({ hour: 1 }).toJSDate(), - offering: 2, - isPublished: true, - }); - const dashboard = '.dashboard-week'; - const events = `${dashboard} .event`; - - await visit('/dashboard/week'); - - const eventBLocks = findAll(events); - assert.strictEqual(eventBLocks.length, 2); - const options = { - weekday: 'long', - hour: 'numeric', - minute: 'numeric', - }; - assert - .dom(eventBLocks[0]) - .hasText('event 0 ' + this.intl.formatTime(startOfTheWeek.toJSDate(), options)); - assert - .dom(eventBLocks[1]) - .hasText('event 1 ' + this.intl.formatTime(endOfTheWeek.toJSDate(), options)); - }); - - const pickTerm = async function (i) { - return await click(find(`.vocabularyfilter [data-test-filter-checkbox-target-id="${i}"]`)); - }; - test('test term filter', async function (assert) { const vocabulary = this.server.create('vocabulary', { school: this.school, @@ -873,13 +955,13 @@ module('Acceptance | Dashboard Calendar', function (hooks) { sessionTerms: [{ id: 1 }], }); await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - await pickTerm(1); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - await pickTerm(1); - await pickTerm(2); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 0); + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + await page.calendar.controls.filters.vocabularyFilter.vocabularies[0].selectedTermTree.checkboxes[0].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + await page.calendar.controls.filters.vocabularyFilter.vocabularies[0].selectedTermTree.checkboxes[0].click(); + await page.calendar.controls.filters.vocabularyFilter.vocabularies[0].selectedTermTree.checkboxes[1].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 0); }); test('clear vocab filter #3450', async function (assert) { @@ -903,23 +985,21 @@ module('Acceptance | Dashboard Calendar', function (hooks) { endDate: today.plus({ hour: 1 }).toJSDate(), sessionTerms: [], }); - const filters = '.filter-tags .filter-tag'; - const filter = `${filters}:nth-of-type(1)`; await page.visit({ show: 'calendar', view: 'week' }); - await showFilters(); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); - await pickTerm(1); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 1); - - assert.dom(filters).exists({ count: 1 }); - await click(filter); - assert.dom(filters).doesNotExist(); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 2); + await page.calendar.controls.showFilters.toggle.secondLabel.click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); + await page.calendar.controls.filters.vocabularyFilter.vocabularies[0].selectedTermTree.checkboxes[0].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); + + assert.strictEqual(page.calendar.filterTags.tags.length, 1); + await page.calendar.filterTags.tags[0].click(); + assert.strictEqual(page.calendar.filterTags.tags.length, 0); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 2); }); test('test tooltip', async function (assert) { - assert.expect(1); + assert.expect(2); const november11th = DateTime.fromObject({ month: 11, day: 11, hour: 8, minute: 8, second: 8 }); this.server.create('userevent', { user: this.user.id, @@ -928,9 +1008,11 @@ module('Acceptance | Dashboard Calendar', function (hooks) { offering: 1, }); await page.visit({ show: 'calendar', view: 'week', date: november11th.toFormat('yyyy-LL-dd') }); - await triggerEvent('[data-test-weekly-calendar-event]', 'mouseover'); + assert.notOk(page.calendar.calendar.weekly.events[0].tooltip.isPresent); + + await page.calendar.calendar.weekly.events[0].mouseOver(); await percySnapshot(assert); - assert.dom('[data-test-ilios-calendar-event-tooltip]').exists(); + assert.ok(page.calendar.calendar.weekly.events[0].tooltip.isPresent); }); test('visit with course filters open #5098', async function (assert) { @@ -947,7 +1029,7 @@ module('Acceptance | Dashboard Calendar', function (hooks) { showFilters: 'true', courseFilters: 'true', }); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 1); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); }); test('visit with detail filters open #5098', async function (assert) { @@ -964,7 +1046,7 @@ module('Acceptance | Dashboard Calendar', function (hooks) { showFilters: 'true', courseFilters: 'false', }); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 1); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); }); test('transition from weekly calendar to day calendar when multi-event is clicked', async function (assert) { @@ -985,13 +1067,13 @@ module('Acceptance | Dashboard Calendar', function (hooks) { offering: 1, }); await page.visit({ show: 'calendar', view: 'week' }); - assert.strictEqual(page.calendar.weeklyCalendar.events.length, 1); - await page.calendar.weeklyCalendar.events[0].click(); + assert.strictEqual(page.calendar.calendar.weekly.events.length, 1); + await page.calendar.calendar.weekly.events[0].click(); assert.strictEqual( currentURL(), `/dashboard/calendar?date=${today.toFormat('yyyy-MM-dd')}&view=day`, ); - assert.strictEqual(page.calendar.dailyCalendar.events.length, 2); + assert.strictEqual(page.calendar.calendar.daily.events.length, 2); }); test('transition from monthly calendar to day calendar when multi-event is clicked', async function (assert) { @@ -1012,12 +1094,12 @@ module('Acceptance | Dashboard Calendar', function (hooks) { offering: 1, }); await page.visit({ show: 'calendar', view: 'month' }); - assert.strictEqual(page.calendar.monthlyCalendar.events.length, 1); - await page.calendar.monthlyCalendar.events[0].click(); + assert.strictEqual(page.calendar.calendar.monthly.events.length, 1); + await page.calendar.calendar.monthly.events[0].click(); assert.strictEqual( currentURL(), `/dashboard/calendar?date=${today.toFormat('yyyy-MM-dd')}&view=day`, ); - assert.strictEqual(page.calendar.dailyCalendar.events.length, 2); + assert.strictEqual(page.calendar.calendar.daily.events.length, 2); }); }); diff --git a/packages/frontend/tests/acceptance/dashboard/week-test.js b/packages/frontend/tests/acceptance/dashboard/week-test.js index 626fd9cfe8..8a59c2c55d 100644 --- a/packages/frontend/tests/acceptance/dashboard/week-test.js +++ b/packages/frontend/tests/acceptance/dashboard/week-test.js @@ -1,4 +1,4 @@ -import { currentRouteName } from '@ember/test-helpers'; +import { currentRouteName, findAll } from '@ember/test-helpers'; import { DateTime } from 'luxon'; import { module, test } from 'qunit'; import { setupAuthentication, freezeDateAt, unfreezeDate } from 'ilios-common'; @@ -9,9 +9,11 @@ import percySnapshot from '@percy/ember'; module('Acceptance | Dashboard Week at a Glance', function (hooks) { setupApplicationTest(hooks); + const today = DateTime.fromObject({ hour: 8 }); hooks.beforeEach(async function () { + this.intl = this.owner.lookup('service:intl'); this.school = this.server.create('school'); this.user = await setupAuthentication({ school: this.school }); }); @@ -133,6 +135,51 @@ module('Acceptance | Dashboard Week at a Glance', function (hooks) { assert.ok(true, 'no a11y errors found!'); }); + test('week summary displays the whole week', async function (assert) { + assert.expect(3); + const startOfTheWeek = DateTime.fromJSDate( + this.owner.lookup('service:locale-days').firstDayOfThisWeek, + ).set({ minute: 2 }); + const endOfTheWeek = DateTime.fromJSDate( + this.owner.lookup('service:locale-days').lastDayOfThisWeek, + ).set({ hour: 22, minute: 5 }); + + this.server.create('userevent', { + user: this.user.id, + startDate: startOfTheWeek.toJSDate(), + endDate: startOfTheWeek.plus({ hour: 1 }).toJSDate(), + offering: 1, + isPublished: true, + }); + this.server.create('userevent', { + user: this.user.id, + startDate: endOfTheWeek.toJSDate(), + endDate: endOfTheWeek.plus({ hour: 1 }).toJSDate(), + offering: 2, + isPublished: true, + }); + const dashboard = '.dashboard-week'; + const events = `${dashboard} .event`; + + await page.visit(); + + const eventBLocks = findAll(events); + assert.strictEqual(eventBLocks.length, 2); + const options = { + weekday: 'long', + hour: 'numeric', + minute: 'numeric', + }; + assert.strictEqual( + page.week.weekGlance.events[0].text, + 'event 0 ' + this.intl.formatTime(startOfTheWeek.toJSDate(), options), + ); + assert.strictEqual( + page.week.weekGlance.events[1].text, + 'event 1 ' + this.intl.formatTime(endOfTheWeek.toJSDate(), options), + ); + }); + test('calendar is active in dashboard navigation', async function (assert) { await page.visit(); assert.notOk(page.navigation.calendar.isActive); diff --git a/packages/ilios-common/.lint-todo b/packages/ilios-common/.lint-todo index 223e453d84..d19123492d 100644 --- a/packages/ilios-common/.lint-todo +++ b/packages/ilios-common/.lint-todo @@ -77,8 +77,6 @@ add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628da add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1720137600000|1722729600000|1725321600000|addon/components/course/visualize-instructors.hbs add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1720137600000|1722729600000|1725321600000|addon/components/course/visualize-session-type.hbs add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1720137600000|1722729600000|1725321600000|addon/components/course/visualize-term.hbs -add|ember-template-lint|no-at-ember-render-modifiers|105|6|105|6|1e67fb6d3c62d7707918389c0b1b072c756afbd2|1720137600000|1722729600000|1725321600000|addon/components/dashboard/calendar.hbs -add|ember-template-lint|no-at-ember-render-modifiers|106|6|106|6|448d60c76fbd9ee5aeb7219dde978518fcba1aea|1720137600000|1722729600000|1725321600000|addon/components/dashboard/calendar.hbs add|ember-template-lint|no-at-ember-render-modifiers|3|2|3|2|9b56ba661238d88b20a82b6f8647d8e16a07b05f|1720137600000|1722729600000|1725321600000|addon/components/dashboard/courses-calendar-filter.hbs add|ember-template-lint|no-at-ember-render-modifiers|4|2|4|2|23cd787c79c34a628dadb6e96dd4004d42eebb79|1720137600000|1722729600000|1725321600000|addon/components/dashboard/courses-calendar-filter.hbs add|ember-template-lint|no-at-ember-render-modifiers|5|2|5|2|a90be151f45cd8ab32827e9247a9a9eb7f1baef2|1720137600000|1722729600000|1725321600000|addon/components/dashboard/courses-calendar-filter.hbs diff --git a/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/calendar-filters.js b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/calendar-filters.js new file mode 100644 index 0000000000..fc9e851de1 --- /dev/null +++ b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/calendar-filters.js @@ -0,0 +1,30 @@ +import { collection, create, text } from 'ember-cli-page-object'; +import c from './filter-checkbox'; +import cohortsFilter from './cohort-calendar-filter'; +import coursesFilter from './courses-calendar-filter'; +import selectedVocabulary from './selected-vocabulary'; + +const definition = { + scope: '[data-test-dashboard-calendar-filters]', + coursesFilter, + sessionTypesFilter: { + scope: '[data-test-session-type-filter]', + title: text('h5'), + sessionTypes: collection('li', c), + }, + vocabularyFilter: { + scope: '[data-test-vocabulary-filter]', + title: text('h5'), + sessionTypes: collection('li', c), + vocabularies: collection('[data-test-dashboard-selected-vocabulary]', selectedVocabulary), + }, + courseLevelsFilter: { + scope: '[data-test-course-level-filter]', + title: text('h5'), + courseLevels: collection('li', c), + }, + cohortsFilter, +}; + +export default definition; +export const component = create(definition); diff --git a/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/calendar.js b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/calendar.js index 4669ef895f..ed68fb6132 100644 --- a/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/calendar.js +++ b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/calendar.js @@ -1,15 +1,41 @@ -import { create } from 'ember-cli-page-object'; -import weeklyCalendar from './../weekly-calendar'; -import dailyCalendar from './../daily-calendar'; -import weekGlance from './../week-glance'; -import monthlyCalendar from './../monthly-calendar'; +import { collection, create, fillable, property } from 'ember-cli-page-object'; +import toggle from '../toggle-buttons'; +import userContextFilter from './user-context-filter'; +import filters from './calendar-filters'; +import filterTags from './filter-tags'; +import calendar from './../ilios-calendar'; const definition = { scope: '[data-test-dashboard-calendar]', - dailyCalendar, - weekGlance, - weeklyCalendar, - monthlyCalendar, + controls: { + scope: '[data-test-dashboard-calendar-controls]', + mySchedule: { + scope: '[data-test-myschedule]', + toggle, + }, + showFilters: { + scope: '[data-test-showfilters]', + toggle, + }, + showCourseFilters: { + scope: '[data-test-showcoursefilters]', + toggle, + }, + userContextFilter, + schoolPicker: { + scope: '[data-test-schoolpicker]', + select: { + scope: '[data-test-select-school]', + set: fillable(), + options: collection('option', { + isSelected: property('selected'), + }), + }, + }, + filters, + }, + filterTags, + calendar, }; export default definition; diff --git a/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/filter-tags.js b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/filter-tags.js new file mode 100644 index 0000000000..fdfad59863 --- /dev/null +++ b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/filter-tags.js @@ -0,0 +1,12 @@ +import { collection, create } from 'ember-cli-page-object'; + +const definition = { + scope: '[data-test-dashboard-filter-tags]', + tags: collection('[data-test-filter-tag]'), + clearAll: { + scope: '[data-test-clear-filters]', + }, +}; + +export default definition; +export const component = create(definition); diff --git a/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/user-context-filter.js b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/user-context-filter.js new file mode 100644 index 0000000000..631d4322db --- /dev/null +++ b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/dashboard/user-context-filter.js @@ -0,0 +1,32 @@ +import { attribute, clickable, create, hasClass, property, text } from 'ember-cli-page-object'; + +const definition = { + scope: '[data-test-dashboard-user-context-filter]', + instructing: { + isChecked: property('checked', '[data-test-instructing-input]'), + label: text('[data-test-instructing-label]'), + toggle: clickable('[data-test-instructing-label]'), + isActive: hasClass('active', '[data-test-instructing-label]'), + ariaDescription: attribute('aria-description', '[data-test-instructing-label]'), + title: attribute('title', '[data-test-instructing-label]'), + }, + learning: { + isChecked: property('checked', '[data-test-learning-input]'), + label: text('[data-test-learning-label]'), + toggle: clickable('[data-test-learning-label]'), + isActive: hasClass('active', '[data-test-learning-label]'), + ariaDescription: attribute('aria-description', '[data-test-learning-label]'), + title: attribute('title', '[data-test-learning-label]'), + }, + admin: { + isChecked: property('checked', '[data-test-admin-input]'), + label: text('[data-test-admin-label]'), + toggle: clickable('[data-test-admin-label]'), + isActive: hasClass('active', '[data-test-admin-label]'), + ariaDescription: attribute('aria-description', '[data-test-admin-label]'), + title: attribute('title', '[data-test-admin-label]'), + }, +}; + +export default definition; +export const component = create(definition); diff --git a/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/weekly-calendar-event.js b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/weekly-calendar-event.js index da4eb107e5..41a37e025b 100644 --- a/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/weekly-calendar-event.js +++ b/packages/ilios-common/addon-test-support/ilios-common/page-objects/components/weekly-calendar-event.js @@ -1,4 +1,4 @@ -import { attribute, create, hasClass, isPresent, text } from 'ember-cli-page-object'; +import { attribute, create, hasClass, isPresent, text, triggerable } from 'ember-cli-page-object'; const definition = { scope: '[data-test-weekly-calendar-event]', @@ -15,6 +15,11 @@ const definition = { isScheduled: isPresent('[data-test-scheduled-icon]'), isDraft: isPresent('[data-test-draft-icon]'), wasRecentlyUpdated: isPresent('[data-test-recently-updated-icon]'), + mouseOver: triggerable('mouseover'), + tooltip: { + scope: '[data-test-ilios-calendar-event-tooltip]', + resetScope: true, + }, }; export default definition; diff --git a/packages/ilios-common/addon/components/dashboard/calendar-filters.hbs b/packages/ilios-common/addon/components/dashboard/calendar-filters.hbs index 32b5258c53..6c6891aae2 100644 --- a/packages/ilios-common/addon/components/dashboard/calendar-filters.hbs +++ b/packages/ilios-common/addon/components/dashboard/calendar-filters.hbs @@ -1,116 +1,124 @@ -{{#if @courseFilters}} - -
-
- {{t "general.sessionTypes"}} -
-
- {{#if (is-array this.sessionTypes)}} -
    - {{#each this.sessionTypes as |type|}} -
  • - - {{type.title}} - -
  • - {{/each}} -
- {{else}} - - {{/if}} +
+ {{#if @courseFilters}} + +
+
+ {{t "general.sessionTypes"}} +
+
+ {{#if (is-array this.sessionTypes)}} +
    + {{#each this.sessionTypes as |type|}} +
  • + + {{type.title}} + +
  • + {{/each}} +
+ {{else}} + + {{/if}} +
-
-
-
- {{t "general.terms"}} -
-
- {{#if (is-array this.vocabularies)}} -
    - {{#each this.vocabularies as |vocabulary|}} - - {{/each}} -
- {{else}} - - {{/if}} +
+
+ {{t "general.terms"}} +
+
+ {{#if (is-array this.vocabularies)}} +
    + {{#each this.vocabularies as |vocabulary|}} + + {{/each}} +
+ {{else}} + + {{/if}} +
+
+ {{else}} +
+
+ {{t "general.sessionTypes"}} +
+
+ {{#if (is-array this.sessionTypes)}} +
    + {{#each this.sessionTypes as |type|}} +
  • + + {{type.title}} + +
  • + {{/each}} +
+ {{else}} + + {{/if}} +
-
-{{else}} -
-
- {{t "general.sessionTypes"}} -
-
- {{#if (is-array this.sessionTypes)}} +
+
+ {{t "general.courseLevels"}} +
+
    - {{#each this.sessionTypes as |type|}} + {{#each this.courseLevels as |level|}}
  • - {{type.title}} + {{level}}
  • {{/each}}
- {{else}} - - {{/if}} -
-
-
-
- {{t "general.courseLevels"}} -
-
-
    - {{#each this.courseLevels as |level|}} -
  • - - {{level}} - -
  • - {{/each}} -
+
-
- -{{/if}} + + {{/if}} +
\ No newline at end of file diff --git a/packages/ilios-common/addon/components/dashboard/calendar.hbs b/packages/ilios-common/addon/components/dashboard/calendar.hbs index bb0df9aeaa..70500ae104 100644 --- a/packages/ilios-common/addon/components/dashboard/calendar.hbs +++ b/packages/ilios-common/addon/components/dashboard/calendar.hbs @@ -3,8 +3,8 @@ data-test-dashboard-calendar >
-
-
+
+
-
+
{{#if @showFilters}} -
+
- {{#if this.showClearFilters}} - - {{/if}} {{/if}} - {{#unless @mySchedule}} -
+ {{#if @mySchedule}} + {{#if this.showUserContextFilters}} +
+ +
+ {{/if}} + {{else}} +
{{#if this.hasMoreThanOneSchool}} - {{#each (sort-by "title" @allSchools) as |school|}}
{{#if (is-array this.cohortProxies)}} {{/if}} -
+
[ - this.getCohortProxies.bind(this), - this.bestSelectedSchool, - ]); + @action + setUserContext(userContext) { + this.dashboardStorage?.set('userContext', userContext); + } + + @cached + get cohortProxiesData() { + return new TrackedAsyncData(this.getCohortProxies(this.bestSelectedSchool)); + } + + get cohortProxies() { + return this.cohortProxiesData.isResolved ? this.cohortProxiesData.value : []; + } + + get showUserContextFilters() { + return this.currentUser.performsNonLearnerFunction; + } get fromTimeStamp() { if ('week' === this.args.selectedView) { @@ -58,32 +72,63 @@ export default class DashboardCalendarComponent extends Component { return 1; } - constructor() { - super(...arguments); - this.setup.perform(); + @cached + get userData() { + return new TrackedAsyncData(this.currentUser.getModel()); + } + + get user() { + return this.userData.isResolved ? this.userData.value : null; + } + + @cached + get usersPrimarySchoolData() { + return new TrackedAsyncData(this.user?.school); + } + + get usersPrimarySchool() { + return this.usersPrimarySchoolData.isResolved ? this.usersPrimarySchoolData.value : null; } - setup = dropTask(async () => { - const user = await this.currentUser.getModel(); - this.usersPrimarySchool = await user.school; + get icsFeedKey() { + return this.user?.icsFeedKey; + } - const icsFeedKey = user.icsFeedKey; + get absoluteIcsUri() { + if (!this.icsFeedKey) { + return ''; + } const apiHost = this.iliosConfig.apiHost; const loc = window.location.protocol + '//' + window.location.hostname; const server = apiHost ? apiHost : loc; - this.absoluteIcsUri = server + '/ics/' + icsFeedKey; - }); + return server + '/ics/' + this.icsFeedKey; + } + + @cached + get eventsData() { + return new TrackedAsyncData( + this.loadEvents(this.bestSelectedSchool, this.fromTimeStamp, this.toTimeStamp), + ); + } + + get events() { + return this.eventsData.isResolved ? this.eventsData.value : []; + } + + get isLoadingEvents() { + return this.eventsData.isPending; + } - loadEvents = restartableTask(async (event, [school, fromTimeStamp, toTimeStamp]) => { + async loadEvents(school, fromTimeStamp, toTimeStamp) { if (!school || !fromTimeStamp || !toTimeStamp) { - return; + return []; } if (this.args.mySchedule) { - this.ourEvents = await this.userEvents.getEvents(fromTimeStamp, toTimeStamp); + return this.userEvents.getEvents(fromTimeStamp, toTimeStamp); } else { - this.ourEvents = await this.schoolEvents.getEvents(school.id, fromTimeStamp, toTimeStamp); + return this.schoolEvents.getEvents(school.id, fromTimeStamp, toTimeStamp); } - }); + } async getCohortProxies(school) { if (!school) { @@ -130,12 +175,13 @@ export default class DashboardCalendarComponent extends Component { 'eventsWithSelectedCohorts', 'eventsWithSelectedCourses', 'eventsWithSelectedTerms', + 'eventsWithSelectedUserContext', ]; const allFilteredEvents = eventTypes.map((name) => { return this[name]; }); - return this.ourEvents.filter((event) => { + return this.events.filter((event) => { return allFilteredEvents.every((arr) => { return arr.includes(event); }); @@ -156,30 +202,30 @@ export default class DashboardCalendarComponent extends Component { get eventsWithSelectedSessionTypes() { if (!this.args.selectedSessionTypeIds?.length) { - return this.ourEvents; + return this.events; } const selectedIds = this.args.selectedSessionTypeIds.map(Number); - return this.ourEvents.filter((event) => { + return this.events.filter((event) => { return selectedIds.includes(event.sessionTypeId); }); } get eventsWithSelectedCourseLevels() { if (!this.args.selectedCourseLevels?.length) { - return this.ourEvents; + return this.events; } const levels = this.args.selectedCourseLevels.map(Number); - return this.ourEvents.filter((event) => { + return this.events.filter((event) => { return levels.includes(event.courseLevel); }); } get eventsWithSelectedCohorts() { if (!this.args.selectedCohortIds?.length) { - return this.ourEvents; + return this.events; } const selectedIds = this.args.selectedCohortIds.map(Number); - return this.ourEvents.filter((event) => { + return this.events.filter((event) => { const matchingCohorts = event.cohorts.filter(({ id }) => selectedIds.includes(id)); return matchingCohorts.length > 0; }); @@ -187,26 +233,46 @@ export default class DashboardCalendarComponent extends Component { get eventsWithSelectedCourses() { if (!this.args.selectedCourseIds?.length) { - return this.ourEvents; + return this.events; } const selectedIds = this.args.selectedCourseIds.map(Number); - return this.ourEvents.filter((event) => { + return this.events.filter((event) => { return selectedIds.includes(event.course); }); } get eventsWithSelectedTerms() { if (!this.args.selectedTermIds?.length) { - return this.ourEvents; + return this.events; } const selectedIds = this.args.selectedTermIds.map(Number); - return this.ourEvents.filter((event) => { + return this.events.filter((event) => { const allTerms = mapBy([].concat(event.sessionTerms || [], event.courseTerms || []), 'id'); const matchingTerms = allTerms.filter((id) => selectedIds.includes(id)); return matchingTerms.length > 0; }); } + get eventsWithSelectedUserContext() { + if (!this.userContext) { + return this.events; + } + + return this.events.filter((event) => { + if ('administrator' === this.userContext) { + // TODO: Replace this with Set.intersect() once that becomes + // available in all browsers, or polyfill it. [ST 2024/06/20]. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/intersection + return ( + event.userContexts.includes('course administrator') || + event.userContexts.includes('course director') || + event.userContexts.includes('session administrator') + ); + } + return event.userContexts.includes(this.userContext); + }); + } + @action changeSchool(event) { this.args.changeSchool(event.target.value); diff --git a/packages/ilios-common/addon/components/dashboard/filter-tags.hbs b/packages/ilios-common/addon/components/dashboard/filter-tags.hbs index c65b0e18d6..c226e69679 100644 --- a/packages/ilios-common/addon/components/dashboard/filter-tags.hbs +++ b/packages/ilios-common/addon/components/dashboard/filter-tags.hbs @@ -3,6 +3,7 @@ class="filters-list" {{did-insert (perform this.load) this.activeFilters}} {{did-update (perform this.load) this.activeFilters}} + data-test-dashboard-filter-tags > {{#if this.filterTags}}
@@ -14,6 +15,7 @@ class="filter-tag {{tag.class}}" type="button" {{on "click" (fn tag.remove tag.id)}} + data-test-filter-tag > {{tag.name}} @@ -24,6 +26,7 @@ class="filters-clear-filters" type="button" {{on "click" @clearFilters}} + data-test-clear-filters > {{t "general.clearFilters"}} diff --git a/packages/ilios-common/addon/components/dashboard/user-context-filter.hbs b/packages/ilios-common/addon/components/dashboard/user-context-filter.hbs new file mode 100644 index 0000000000..c901581b64 --- /dev/null +++ b/packages/ilios-common/addon/components/dashboard/user-context-filter.hbs @@ -0,0 +1,75 @@ +
+ + + + + + +
\ No newline at end of file diff --git a/packages/ilios-common/addon/components/dashboard/user-context-filter.js b/packages/ilios-common/addon/components/dashboard/user-context-filter.js new file mode 100644 index 0000000000..b348658407 --- /dev/null +++ b/packages/ilios-common/addon/components/dashboard/user-context-filter.js @@ -0,0 +1,15 @@ +import Component from '@glimmer/component'; +import { action } from '@ember/object'; +import { guidFor } from '@ember/object/internals'; + +export default class DashboardUserContextFilterComponent extends Component { + get uniqueId() { + return guidFor(this); + } + + @action + toggle(context) { + const newUserContext = context === this.args.userContext ? null : context; + this.args.setUserContext(newUserContext); + } +} diff --git a/packages/ilios-common/addon/storages/dashboard.js b/packages/ilios-common/addon/storages/dashboard.js new file mode 100644 index 0000000000..74ef5bd9de --- /dev/null +++ b/packages/ilios-common/addon/storages/dashboard.js @@ -0,0 +1,3 @@ +import StorageObject from 'ember-local-storage/local/object'; + +export default class Storage extends StorageObject {} diff --git a/packages/ilios-common/app/components/dashboard/user-context-filter.js b/packages/ilios-common/app/components/dashboard/user-context-filter.js new file mode 100644 index 0000000000..3e8a16d8cb --- /dev/null +++ b/packages/ilios-common/app/components/dashboard/user-context-filter.js @@ -0,0 +1 @@ +export { default } from 'ilios-common/components/dashboard/user-context-filter'; diff --git a/packages/ilios-common/app/storages/dashboard.js b/packages/ilios-common/app/storages/dashboard.js new file mode 100644 index 0000000000..a137193c98 --- /dev/null +++ b/packages/ilios-common/app/storages/dashboard.js @@ -0,0 +1 @@ +export { default } from 'ilios-common/storages/dashboard'; diff --git a/packages/ilios-common/app/styles/ilios-common/components.scss b/packages/ilios-common/app/styles/ilios-common/components.scss index 312cd6ef71..602b004faa 100644 --- a/packages/ilios-common/app/styles/ilios-common/components.scss +++ b/packages/ilios-common/app/styles/ilios-common/components.scss @@ -15,6 +15,7 @@ @import "components/dashboard/courses-calendar-filter"; @import "components/dashboard/materials"; @import "components/dashboard/navigation"; +@import "components/dashboard/user-context-filter"; @import "components/dashboard/week"; @import "components/detail-cohort-manager"; @import "components/detail-cohorts"; diff --git a/packages/ilios-common/app/styles/ilios-common/components/dashboard/calendar.scss b/packages/ilios-common/app/styles/ilios-common/components/dashboard/calendar.scss index 447f30689b..80fca18c71 100644 --- a/packages/ilios-common/app/styles/ilios-common/components/dashboard/calendar.scss +++ b/packages/ilios-common/app/styles/ilios-common/components/dashboard/calendar.scss @@ -21,7 +21,7 @@ margin-top: 1.5em; } - .calendar-filters { + .dashboard-calendar-filters { clear: both; float: left; width: 100%; diff --git a/packages/ilios-common/app/styles/ilios-common/components/dashboard/user-context-filter.scss b/packages/ilios-common/app/styles/ilios-common/components/dashboard/user-context-filter.scss new file mode 100644 index 0000000000..6a58feea34 --- /dev/null +++ b/packages/ilios-common/app/styles/ilios-common/components/dashboard/user-context-filter.scss @@ -0,0 +1,11 @@ +@use "../../mixins" as m; +@use "../../colors" as c; + +.dashboard-user-context-filter { + @include m.multi-button; + + label.active { + background-color: c.$tealBlue; + color: c.$white; + } +} diff --git a/packages/ilios-common/app/styles/ilios-common/components/toggle-buttons.scss b/packages/ilios-common/app/styles/ilios-common/components/toggle-buttons.scss index c27d1e7fab..8983365851 100644 --- a/packages/ilios-common/app/styles/ilios-common/components/toggle-buttons.scss +++ b/packages/ilios-common/app/styles/ilios-common/components/toggle-buttons.scss @@ -1,40 +1,5 @@ -@use "../colors" as c; @use "../mixins" as m; .toggle-buttons { - display: flex; - - input { - @include m.ilios-off-screen; - } - - label { - background-color: c.$white; - color: c.$tealBlue; - border: 1px solid rgba(c.$black, 0.2); - display: inline-block; - @include m.font-size("small"); - font-weight: 600; - min-width: 3em; - padding: 0.25em 0.5em; - text-align: center; - text-shadow: none; - - &:hover { - cursor: pointer; - } - - &:first-of-type { - border-radius: 4px 0 0 4px; - } - - &:last-of-type { - border-radius: 0 4px 4px 0; - } - } - - input:checked + label { - background-color: c.$tealBlue; - color: c.$white; - } + @include m.multi-button; } diff --git a/packages/ilios-common/app/styles/ilios-common/mixins.scss b/packages/ilios-common/app/styles/ilios-common/mixins.scss index d03dc31377..398c8b174e 100644 --- a/packages/ilios-common/app/styles/ilios-common/mixins.scss +++ b/packages/ilios-common/app/styles/ilios-common/mixins.scss @@ -19,6 +19,7 @@ @forward "mixins/ilios-table"; @forward "mixins/ilios-textarea"; @forward "mixins/main-section"; +@forward "mixins/multi-button"; @forward "mixins/objectives"; @forward "mixins/sort-manager"; @forward "mixins/sessions-grid"; diff --git a/packages/ilios-common/app/styles/ilios-common/mixins/multi-button.scss b/packages/ilios-common/app/styles/ilios-common/mixins/multi-button.scss new file mode 100644 index 0000000000..fe54a77c87 --- /dev/null +++ b/packages/ilios-common/app/styles/ilios-common/mixins/multi-button.scss @@ -0,0 +1,41 @@ +@use "../colors" as c; +@use "ilios-off-screen"; +@use "font-size"; + +@mixin multi-button { + display: flex; + + input { + @include ilios-off-screen.ilios-off-screen; + } + + label { + background-color: c.$white; + color: c.$tealBlue; + border: 1px solid rgba(c.$black, 0.2); + display: inline-block; + @include font-size.font-size("small"); + font-weight: 600; + min-width: 3em; + padding: 0.25em 0.5em; + text-align: center; + text-shadow: none; + + &:hover { + cursor: pointer; + } + + &:first-of-type { + border-radius: 4px 0 0 4px; + } + + &:last-of-type { + border-radius: 0 4px 4px 0; + } + } + + input:checked + label { + background-color: c.$tealBlue; + color: c.$white; + } +} diff --git a/packages/ilios-common/package.json b/packages/ilios-common/package.json index 37804f1c98..31beec028c 100644 --- a/packages/ilios-common/package.json +++ b/packages/ilios-common/package.json @@ -51,6 +51,7 @@ "ember-in-viewport": "^4.0.0", "ember-inflector": "^4.0.2", "ember-intl": "^7.0.4", + "ember-local-storage": "^2.0.7", "ember-math-helpers": "^4.0.0", "ember-modifier": "^4.0.0", "ember-simple-auth": "^6.0.0", diff --git a/packages/ilios-common/translations/en-us.yaml b/packages/ilios-common/translations/en-us.yaml index 71bdfcc64f..e6e7e06254 100644 --- a/packages/ilios-common/translations/en-us.yaml +++ b/packages/ilios-common/translations/en-us.yaml @@ -4,6 +4,7 @@ general: activeFilters: Active Filters add: Add addNew: Add New + admin: Admin administratorCount: "There {count, plural, =1 {is 1 administrator} other {are # administrators}}" administrators: Administrators advancedOptions: Advanced Options @@ -156,6 +157,7 @@ general: independentLearning: Independent Learning independentLearningActivities: Independent Learning Activities inProgress: In Progress + instructing: Instructing instructionalNotes: Instructional Notes instructor: Instructor instructorGroupMembers: Instructor Group Members @@ -171,6 +173,7 @@ general: learnerGroupsManageTitle: Manage Learner Groups learners: Learners learnersAndLearnerGroups: Learners and Learner Groups + learning: Learning learnersAndLearnerGroupsWithCount: "Learners ({learnerCount}) and Learner Groups ({learnerGroupCount})" learningMaterialManageTitle: Manage Learning Material learningMaterials: Learning Materials @@ -310,6 +313,7 @@ general: sessionType: Session Type sessionTypes: Session Types sessionTypesFor: "Session Types for {subject}" + showAllMyActivities: Show all my activities showCalendar: Show Calendar showCourseMaterials: Show course materials showFilters: Show Filters @@ -318,6 +322,9 @@ general: showMore: Show more showNotesToStudents: Show Notes to Students showObjectives: Show objectives + showOnlyMyAdminActivities: Show only my admin activities + showOnlyMyInstructorActivities: Show only my instructor activities + showOnlyMyLearnerActivities: Show only my learner activities showSessionEvents: "Show all other ''{sessionTitle}'' events" showSessionMaterials: Show session materials smallGroupMessage: 'Please select at least one learner group to attach to your small group offering. If you wish to schedule this offering without groups, please select the "offering" button above.' diff --git a/packages/ilios-common/translations/es.yaml b/packages/ilios-common/translations/es.yaml index 85a0a5fe46..3bca23723f 100644 --- a/packages/ilios-common/translations/es.yaml +++ b/packages/ilios-common/translations/es.yaml @@ -4,6 +4,7 @@ general: activeFilters: Filtros Activos add: Agregue addNew: Agregue Nuevo + admin: Admin administratorCount: "Hay {count, plural, =1 {1 administrador} other {# administradores}}" administrators: Administradores advancedOptions: Opciones Avanzadas @@ -156,6 +157,7 @@ general: independentLearning: Aprendizaje Independiente independentLearningActivities: Aprendizaje Independiente Actividades inProgress: En Progreso + instructing: Instruyendo instructionalNotes: Notes para la Instrucción instructor: Instructor instructorGroupMembers: Miembros del grupo instructor @@ -172,6 +174,7 @@ general: learners: Aprendedores learnersAndLearnerGroups: Aprendedores y Grupos de Aprendedores learnersAndLearnerGroupsWithCount: "Aprendedores ({learnerCount}) y Grupos de Aprendedores ({learnerGroupCount})" + learning: Aprendiendo learningMaterialManageTitle: Administrar Materiales de Aprendizaje learningMaterials: Materiales de Aprendizaje learningMaterialsSummary: Resumen de Materiales de Aprendizaje @@ -310,6 +313,7 @@ general: sessionType: Tipo de Sesión sessionTypes: Tipos de Sesiones sessionTypesFor: "Tipos de Sesiones para {subject}" + showAllMyActivities: Mostrar todas mis actividades showCalendar: Muestre Calendario showCourseMaterials: Mostrar materiales del curso showFilters: Enseñe Filtros @@ -323,6 +327,9 @@ general: smallGroupMessage: 'Por favor seleccione al menos un grupo de alumnos para adjuntar a su ofrecimiento de grupos pequeños. Si usted desea programar este ofrecimiento sin grupos, favor de seleccionar el botón de "ofrecimiento" de arriba.' smallGroups: Grupos Pequeños sortMaterials: Clasificar los materiales + showOnlyMyAdminActivities: Mostrar solo mis actividades de administrador + showOnlyMyInstructorActivities: Mostrar solo las actividades de mi instructor + showOnlyMyLearnerActivities: Mostrar solo mis actividades de aprendizaje sortObjectives: Clasificar los objetivos specialAttireIs_Required_: "Se ''require'' vestimenta especial" specialAttireRequired: Vestimenta Especial Requerido diff --git a/packages/ilios-common/translations/fr.yaml b/packages/ilios-common/translations/fr.yaml index c92cee2347..c62456a641 100644 --- a/packages/ilios-common/translations/fr.yaml +++ b/packages/ilios-common/translations/fr.yaml @@ -2,6 +2,7 @@ general: accessAllMaterialsForThisCourse: "Accéder à tout le matériel d'étude pour ce cours" actions: Actions activeFilters: Filtres actifs + admin: Admin add: Ajouté addNew: Ajouté Neuf administratorCount: "Il y a {count, plural, =1 { un administrateur} other {# administrateurs}}" @@ -158,6 +159,7 @@ general: inProgress: En Cours instructionalNotes: Notes Didactiques instructor: Instructeur + instructing: Enseignement instructorGroupMembers: "Membres du groupe d'instructeurs" instructorGroups: Groupes des Instructeurs instructors: Instructeurs @@ -172,6 +174,7 @@ general: learners: Étudiants learnersAndLearnerGroups: "Étudiants et Groupes d'Étudiants" learnersAndLearnerGroupsWithCount: "Étudiants ({learnerCount}) et Groupes d'Étudiants ({learnerGroupCount})" + learning: Apprentissages learningMaterialManageTitle: "Manager Matériels d'Étude" learningMaterials: "Matériels d'Étude" learningMaterialsSummary: "Résumé Matériels d'Étude" @@ -310,6 +313,7 @@ general: sessionType: Type de Séance sessionTypes: Types de Séance sessionTypesFor: "Types de Séance par {subject}" + showAllMyActivities: Afficher toutes mes activités showCalendar: Afficher Calendrier showCourseMaterials: Afficher les supports de cours showFilters: Montrez les Filtres @@ -318,6 +322,9 @@ general: showMore: Afficher plus showNotesToStudents: Afficher notes aux étudiantes showObjectives: Afficher les objectifs + showOnlyMyAdminActivities: Afficher uniquement mes activités d'administrateur + showOnlyMyInstructorActivities: Afficher uniquement mes activités d'instructeur + showOnlyMyLearnerActivities: Afficher uniquement mes activités d'apprenant showSessionEvents: "Montrez tous les autres ''{sessionTitle}'' événements" showSessionMaterials: Afficher les supports de session smallGroupMessage: 'S''il vous plaît choisir au moins un groupe d''apprenants à joindre à votre offrande de "small groups". Si vous souhaitez programmer cette offrande sans groupes, s''il vous plaît choisir le bouton "offre" au-dessus.' diff --git a/packages/lti-dashboard/config/environment.js b/packages/lti-dashboard/config/environment.js index 51ed07fd2e..646b716539 100644 --- a/packages/lti-dashboard/config/environment.js +++ b/packages/lti-dashboard/config/environment.js @@ -19,6 +19,11 @@ module.exports = function (environment) { authorizationPrefix: 'Token ', refreshLeeway: 300, }, + 'ember-local-storage': { + namespace: true, + keyDelimiter: '/', + includeEmberDataSupport: false, + }, i18n: { defaultLocale: 'en', }, diff --git a/packages/test-app/tests/integration/components/dashboard/user-context-filter-test.js b/packages/test-app/tests/integration/components/dashboard/user-context-filter-test.js new file mode 100644 index 0000000000..3c223931f5 --- /dev/null +++ b/packages/test-app/tests/integration/components/dashboard/user-context-filter-test.js @@ -0,0 +1,117 @@ +import { module, test } from 'qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; +import { setupRenderingTest } from 'test-app/tests/helpers'; +import { setupMirage } from 'test-app/tests/test-support/mirage'; +import { a11yAudit } from 'ember-a11y-testing/test-support'; +import { component } from 'ilios-common/page-objects/components/dashboard/user-context-filter'; + +module('Integration | Component | dashboard/user-context-filter', function (hooks) { + setupRenderingTest(hooks); + setupMirage(hooks); + + test('it renders', async function (assert) { + await render(hbs``); + assert.strictEqual(component.instructing.label, 'Instructing'); + assert.strictEqual(component.instructing.ariaDescription, 'Show only my instructor activities'); + assert.strictEqual(component.instructing.title, 'Show only my instructor activities'); + assert.notOk(component.instructing.isChecked); + assert.ok(component.instructing.isActive); + assert.strictEqual(component.learning.label, 'Learning'); + assert.strictEqual(component.learning.ariaDescription, 'Show only my learner activities'); + assert.strictEqual(component.learning.title, 'Show only my learner activities'); + assert.notOk(component.learning.isChecked); + assert.ok(component.learning.isActive); + assert.strictEqual(component.admin.label, 'Admin'); + assert.strictEqual(component.admin.ariaDescription, 'Show only my admin activities'); + assert.strictEqual(component.admin.title, 'Show only my admin activities'); + assert.notOk(component.admin.isChecked); + assert.ok(component.admin.isActive); + await a11yAudit(this.element); + assert.ok(true, 'no a11y errors found!'); + }); + + test('selecting learning filter', async function (assert) { + assert.expect(2); + this.set('setUserContext', (context) => { + assert.strictEqual(context, 'learner'); + }); + await render(hbs``); + assert.notOk(component.learning.isChecked); + await component.learning.toggle(); + }); + + test('de-selecting learning filter', async function (assert) { + assert.expect(7); + this.set('userContext', 'learner'); + this.set('setUserContext', (context) => { + assert.strictEqual(context, null); + }); + await render( + hbs``, + ); + assert.strictEqual(component.learning.ariaDescription, 'Show all my activities'); + assert.strictEqual(component.learning.title, 'Show all my activities'); + assert.ok(component.learning.isChecked); + assert.notOk(component.instructing.isActive); + assert.ok(component.learning.isActive); + assert.notOk(component.admin.isActive); + await component.learning.toggle(); + }); + + test('selecting instructing filter', async function (assert) { + assert.expect(2); + this.set('setUserContext', (context) => { + assert.strictEqual(context, 'instructor'); + }); + await render(hbs``); + assert.notOk(component.instructing.isChecked); + await component.instructing.toggle(); + }); + + test('de-selecting instructing filter', async function (assert) { + assert.expect(7); + this.set('userContext', 'instructor'); + this.set('setUserContext', (context) => { + assert.strictEqual(context, null); + }); + await render( + hbs``, + ); + assert.strictEqual(component.instructing.ariaDescription, 'Show all my activities'); + assert.strictEqual(component.instructing.title, 'Show all my activities'); + assert.ok(component.instructing.isChecked); + assert.ok(component.instructing.isActive); + assert.notOk(component.learning.isActive); + assert.notOk(component.admin.isActive); + await component.instructing.toggle(); + }); + + test('selecting admin filter', async function (assert) { + assert.expect(2); + this.set('setUserContext', (context) => { + assert.strictEqual(context, 'administrator'); + }); + await render(hbs``); + assert.notOk(component.admin.isChecked); + await component.admin.toggle(); + }); + + test('de-selecting admin filter', async function (assert) { + assert.expect(7); + this.set('userContext', 'administrator'); + this.set('setUserContext', (context) => { + assert.strictEqual(context, null); + }); + await render( + hbs``, + ); + assert.strictEqual(component.admin.ariaDescription, 'Show all my activities'); + assert.strictEqual(component.admin.title, 'Show all my activities'); + assert.ok(component.admin.isChecked); + assert.notOk(component.instructing.isActive); + assert.notOk(component.learning.isActive); + assert.ok(component.admin.isActive); + await component.admin.toggle(); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e742d162cd..773d82f556 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -450,6 +450,9 @@ importers: ember-intl: specifier: ^7.0.4 version: 7.0.4(webpack@5.93.0) + ember-local-storage: + specifier: ^2.0.7 + version: 2.0.7(@babel/core@7.24.9) ember-math-helpers: specifier: ^4.0.0 version: 4.0.0(ember-source@5.9.0(@babel/core@7.24.9)(@glimmer/component@1.1.2(@babel/core@7.24.9))(rsvp@4.8.5)(webpack@5.93.0)) @@ -3761,6 +3764,9 @@ packages: blank-object@1.0.2: resolution: {integrity: sha512-kXQ19Xhoghiyw66CUiGypnuRpWlbHAzY/+NyvqTEdTfhfQGH1/dbEMYiXju7fYKIFePpzp/y9dsu5Cu/PkmawQ==} + blob-polyfill@7.0.20220408: + resolution: {integrity: sha512-oD8Ydw+5lNoqq+en24iuPt1QixdPpe/nUF8azTHnviCZYu9zUC+TwdzIp5orpblJosNlgNbVmmAb//c6d6ImUQ==} + bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} @@ -5254,6 +5260,10 @@ packages: resolution: {integrity: sha512-6GaN0eEDZT9SEUSZBxWzZMlvxjcGKXFTJNjv30LVXTTOxozE5IBmIxiDAEq0udi0UpWUGHLYQBgnANn4jdll7w==} engines: {node: '>= 16.*'} + ember-copy@2.0.1: + resolution: {integrity: sha512-N/XFvZszrzyyX4IcNoeK4mJvIItNuONumhPLqi64T8NDjJkxBj4Pq61rvMkJx/9eZ8alzE4I8vYKOLxT0FvRuQ==} + engines: {node: 10.* || >= 12} + ember-could-get-used-to-this@1.0.1: resolution: {integrity: sha512-+BXc8NbJJ/DoUXZk4e3qeRvADw9ThMEW7jm+Nz+QX9jRY/5QYodnFeUEfsC4Sw3Ti2m1+RzI2Lyq0QWpgOqFYg==} engines: {node: 8.* || >= 10.*} @@ -5348,6 +5358,10 @@ packages: resolution: {integrity: sha512-CYR+U/wRxLbrfYN3dh+0Tb6mFaxJKfdyz+wNql6cqTrA0BBi9k6J3AaKXj273TqvEpyyXegQFFkZEiuZdYtgJw==} engines: {node: 6.* || 8.* || >= 10.*} + ember-local-storage@2.0.7: + resolution: {integrity: sha512-EPvxH/27mIzrX/EEgng+FG6HD0ri/God9OH/9mhmgPSXrgMNq/614Z3NMnooM4QKIEBAvr0p+p1UL2DgrTTMNg==} + engines: {node: 12.* || 14.* || >= 16} + ember-math-helpers@4.0.0: resolution: {integrity: sha512-f83fUNp9/DbnPK6WWiYDLdxSePMC2YVxt7aZZPsDy3Zlwp75mhzUknbqd6wSCeKwJYJm+1xh0l/SygxzLvKgnw==} engines: {node: 14.* || 16.* || >= 18} @@ -14231,6 +14245,8 @@ snapshots: blank-object@1.0.2: {} + blob-polyfill@7.0.20220408: {} + bluebird@3.7.2: {} bn.js@4.12.0: {} @@ -16527,6 +16543,12 @@ snapshots: transitivePeerDependencies: - supports-color + ember-copy@2.0.1: + dependencies: + ember-cli-babel: 7.26.11 + transitivePeerDependencies: + - supports-color + ember-could-get-used-to-this@1.0.1: dependencies: ember-cli-babel: 7.26.11 @@ -16709,6 +16731,21 @@ snapshots: - '@babel/core' - supports-color + ember-local-storage@2.0.7(@babel/core@7.24.9): + dependencies: + blob-polyfill: 7.0.20220408 + broccoli-funnel: 3.0.8 + broccoli-merge-trees: 4.2.0 + broccoli-stew: 3.0.0 + ember-cli-babel: 7.26.11 + ember-cli-string-utils: 1.1.0 + ember-cli-version-checker: 5.1.2 + ember-copy: 2.0.1 + ember-destroyable-polyfill: 2.0.3(@babel/core@7.24.9) + transitivePeerDependencies: + - '@babel/core' + - supports-color + ember-math-helpers@4.0.0(ember-source@5.9.0(@babel/core@7.24.9)(@glimmer/component@1.1.2(@babel/core@7.24.9))(rsvp@4.8.5)(webpack@5.93.0)): dependencies: '@embroider/addon-shim': 1.8.9