diff --git a/cypress/e2e/admin.cy.js b/cypress/e2e/admin.cy.js index 0125cb7b..9ff2c151 100644 --- a/cypress/e2e/admin.cy.js +++ b/cypress/e2e/admin.cy.js @@ -29,6 +29,19 @@ context('Admin: Generate Screenshots', () => { cy.snap('component-user_progress_table', '#mainContent2'); }) + it('Users Archive component', () => { + // projects page + cy.visit('/administrator/projects/movies/users') + cy.get('[data-cy="usersTable"] [data-p-index="0"] [data-pc-name="rowcheckbox"]').click() + cy.get('[data-cy="usersTable"] [data-p-index="1"] [data-pc-name="rowcheckbox"]').click() + cy.snap('component-users_table_ready_to_archive', '#mainContent2'); + cy.get('[data-cy="archiveUsersTableBtn"]').click() + + cy.get('[data-cy="userArchiveBtn"]').click() + cy.get('[data-cy="userArchiveTable"] [data-cy="skillsBTableTotalRows"]').should('have.text', '2') + cy.snap('component-users_archive', '#mainContent2'); + }) + it('Gen Projects pages - dark mode', () => { cy.request('POST', '/app/userInfo/settings', [{ 'settingGroup': 'user.prefs', @@ -215,8 +228,8 @@ context('Admin: Generate Screenshots', () => { it('Settings Page', () => { cy.visit('/administrator/projects/movies/settings') cy.contains('Discoverable'); - cy.get('[data-cy="customLabelsSwitch"]').click(); cy.snap('page-project-settings'); + cy.snap('component-project-settings', '#mainContent2'); }) it('Email notification pages', () => { diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 3dc3f48b..2e0f0e40 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -191,6 +191,7 @@ console.log(`Sidebar object:\n${JSON.stringify(sidebar, null, 2)}`); export default defineUserConfig({ bundler: viteBundler(), + port: 9999, lang: 'en-US', description: 'Innovative approach to application training!', head: [ diff --git a/docs/dashboard/user-guide/progress-and-ranking.md b/docs/dashboard/user-guide/progress-and-ranking.md index d7bc3c24..ab2c79af 100644 --- a/docs/dashboard/user-guide/progress-and-ranking.md +++ b/docs/dashboard/user-guide/progress-and-ranking.md @@ -81,7 +81,7 @@ A single quiz or survey attempt will display the results of that attempt. In the In the case of a quiz, there are a number of possible conditions based on the status of the attempt: - `Passed` Quiz: all the questions and answers are shown -- `Failed` Quiz: by default only manually graded (`Text Input`) answers are shown, `Single Choice` and `Multiple Choice` answers are not displayed; however if [Show Correct Answers On Failure](/dashboard/user-guide/quizzes-and-surveys.html#quiz-settings) setting is enabled then all the answers are displayed +- `Failed` Quiz: by default only manually graded (`Text Input`) answers are shown, `Multiple Answers` and `Multiple Choice` questions are not displayed; however if [Show Correct Answers On Failure](/dashboard/user-guide/quizzes-and-surveys.html#quiz-settings) setting is enabled then all the answers are displayed - `Needs Grading` Quiz: answers are not displayed ## Badges Page diff --git a/docs/dashboard/user-guide/projects.md b/docs/dashboard/user-guide/projects.md index 10b010f6..7c4f8bd4 100644 --- a/docs/dashboard/user-guide/projects.md +++ b/docs/dashboard/user-guide/projects.md @@ -43,7 +43,7 @@ The Dashboard user that creates a project is automatically granted the role of a To manage and view project-wide settings navigate to ``Project -> Settings``. -![Project Settings](../../screenshots/admin/page-project-settings.png) +![component-project-settings.png](../../screenshots/admin/component-project-settings.png) The following project-level settings are available: @@ -130,6 +130,20 @@ If this is the case, admins can customize the following labels displayed to user Toggle this setting to always show the group's descriptions in this project embedded Skills Display component and Progress and Ranking pages. +### Setting: Hide Group Info On Skill Pages + +By default, the skill page displays the group name and description when a skill is part of a Skill Group. Enabling this +setting will hide the group's information from the skill page. + +### Setting: Hide Achievement Celebration + +Trainee achievement celebrations are displayed throughout training displays when levels, badges, and skills are +achieved. These congratulatory messages can be hidden by enabling the `Hide Achievement Celebration` setting. + +### Setting: Project Deletion Protection + +When this setting is enabled, project deletion will be prevented, and the Delete button will be hidden. + ## Access The Project Access page supports adding or removing Project Administrators, Project Approvers, and inviting users to join a project if the project has been configured as an Invite Only project as well as revoking a user's access. @@ -223,6 +237,56 @@ The following training profile elements are **NOT** copied into a new project: Once a project has been copied, the new project is disconnected from the original such that changes to the original project will not be reflected in the copy ::: +## Copy Subject to Another Project + +A subject in its entirety can be easily copied from one project to another. To do this, navigate to the Subject page and +click the `Copy` button located on the top-left of the screen, right below the subject's name. Once the copy operation +is initiated, you will be guided through the destination project selection. + +The following subject's training profile elements are copied: +- Subject's attributes (icon, description, help URL) +- Skills definitions and their attributes (description, points, self-reporting, etc.) +- Skill Groups +- Configured display order of subject's skills + +::: tip +After copying a subject, the new subject becomes independent of the original, and any changes made to the original +subject will not affect the copied subject +::: + +The following elements are excluded from the subject copying process: +- Reused skills +- Imported catalog skills +- Levels: destination project's subject will be created with default level configuration +- Cross-project prerequisites + +::: warning +When copying a subject to another project, the destination project must meet the following requirements: + +* It must not have an existing subject with the same name or ID. +* It must not have any skills with IDs or names that match the copied subject's skills. +::: + +## Copy Skills to Another Project + +Skills can be copied individually or in batches from one project to another. To do so: + +* Navigate to the Subject page +* Select one or more skills +* Click the Actions drop-down button at the top-right of the skills' table +* Select "Copy to another Project" + +Once the copy operation is initiated, you will be guided through the process of selecting a destination project and subject or skill group. + +::: tip +After copying skills, the new skills become independent of the originals, and any changes made to the originals will not affect the copied skills. +::: + +::: warning +Note that the destination project must not have any subjects, badges, or skills with IDs or names that match the copied skills. +::: + + ## Share Project Public projects that are configured to be [discoverable](/dashboard/user-guide/projects.html#setting-visibility) can be easily shared with users so they can begin consuming the micro-learning gamified training! diff --git a/docs/dashboard/user-guide/quizzes-and-surveys.md b/docs/dashboard/user-guide/quizzes-and-surveys.md index 10fbeacf..d967e397 100644 --- a/docs/dashboard/user-guide/quizzes-and-surveys.md +++ b/docs/dashboard/user-guide/quizzes-and-surveys.md @@ -45,8 +45,8 @@ or can be executed independently. Associating a Quiz to an existing skill will r in order to earn the skill and its points. In the case of a quiz, then the quiz serves as the skill's knowledge check. Quizzes currently support two types of questions: -- ``Single Choice`` - question will only have 1 correct answer -- ``Mulitple Choice`` - question has 2 or more correct choices; all correct choices must be selected to get credit for the question +- ``Multiple Choice`` - question will only have 1 correct answer +- ``Multiple Answers`` - question has 2 or more correct choices; all correct choices must be selected to get credit for the question - ``Input Text`` - question for test-takers to provide a free-form text answer that will later be graded by a quiz administrator To administer a quiz click `Manage` button for that quiz on the `Quizzes and Surveys` page. @@ -59,12 +59,6 @@ To add a new question please click `Question +` button. The Question's text supports all the same features that the [Description Editor](/dashboard/user-guide/rich-text-editor.html) currently affords which includes a generous feature set including attaching or copy-and-pasting screenshots. -The two supported question's types and ``Single Choice`` and ``Mulitple Choice`` and are implicitly derived from the number of the selected correct answers. -A single selected correct answer implies ``Single Choice`` question type and when more than one corrected answers selected then ``Mulitple Choice`` is used. -::: tip -When multiple correct answers are selected users will be required to properly identify all of those correct answers in -order to receive the credit for the question -::: ::: tip Use the `Preview` button on the top left below the Quiz name in order to see what the quiz will look like to your users. @@ -148,8 +142,8 @@ When associated to a skill, the survey is a method to gather feedback about that pieces of important data related to the skill. A Survey currently supports four types of questions: -- ``Single Choice`` - question will only allow a single choice to be selected -- ``Mulitple Choice`` - one or more choices are required to be selected +- ``Multiple Choice`` - question will only allow a single choice to be selected +- ``Multiple Answers`` - one or more choices are required to be selected - ``Text Input`` - a freeform answer text is required - ``Rating`` - a star-based rating question with an ability configure between 3 and 10 stars @@ -163,7 +157,7 @@ To add a new question please click the `Question +` button. The Question's text supports all the same features that the [Description Editor](/dashboard/user-guide/rich-text-editor.html) currently affords which includes a generous feature set including attaching or copy-and-pasting screenshots. -Please use the Answer's dropdown to select the type, currently available options are ``Single Choice``, ``Mulitple Choice`` and ``Text Input``. +Please use the Answer's dropdown to select the type. ::: tip Use the `Preview` button on the top left below the Survey name in order to see what the survey will look like to your users. diff --git a/docs/dashboard/user-guide/skills.md b/docs/dashboard/user-guide/skills.md index 32afad2b..61d7a965 100644 --- a/docs/dashboard/user-guide/skills.md +++ b/docs/dashboard/user-guide/skills.md @@ -81,6 +81,14 @@ When captions are configured the video player will present an option to turn cap Captions utilize [Web Video Text Tracks Format (WebVTT)](https://developer.mozilla.org/en-US/docs/Web/API/WebVTT_API) format and its input form offers an ability to prefill an example in WebVTT format by clicking `Add Example` button above the `Captions` input field. +::: tip +Configure the video size by dragging the button on the bottom-right corner of the video. After resizing, click the +**Save Changes** button to persist the new dimensions. + +Trainees can also resize videos, and their personalized configurations will be automatically saved in the browser's +local storage and will take priority over the default. +::: + ### Achieve Skill By Watching the Video Once the video's settings are specified the skill can also be configured to be achieved after the trainee watched the entire video (>96%). diff --git a/docs/dashboard/user-guide/users.md b/docs/dashboard/user-guide/users.md index bc637f0d..65b86a22 100644 --- a/docs/dashboard/user-guide/users.md +++ b/docs/dashboard/user-guide/users.md @@ -32,6 +32,25 @@ Additionally, you can export the table data into an Excel file by clicking the E Note that the export will respect any currently applied filters. ::: +## Users Archive + +Users can be archived and restored in batches or individually. Archived users are excluded from project visualizations, metrics, and tables. + +To archive a user, follow these steps: + +- Navigate to the Users page under a project. +- Select one or more users in the users table. +- Click the Archive button. + +![component-users_table_ready_to_archive.png](../../screenshots/admin/component-users_table_ready_to_archive.png) + +The archive can be viewed by clicking the `User Archive` button, located on the top-right, above the users table's components. + +![component-users_archive.png](../../screenshots/admin/component-users_archive.png) + +To restore an archived user, simply click the `Restore` button for that user. + + ## User Roles ### Default User diff --git a/docs/release-notes/skills-service.md b/docs/release-notes/skills-service.md index b11d1072..fd6a03e6 100644 --- a/docs/release-notes/skills-service.md +++ b/docs/release-notes/skills-service.md @@ -8,9 +8,50 @@ To obtain deployable artifacts please visit [Distributions](/dashboard/install-g +## 3.3.0 +- Ability to [archive and restore users](/dashboard/user-guide/users.html#users-archive) in batch or individually, with archived users excluded from project visualizations, metrics, and tables +- Ability to copy training profile components between projects + - [Batch skill definition copying](/dashboard/user-guide/projects.html#copy-skills-to-another-project) from one project to another + - [Copying subject definitions](/dashboard/user-guide/projects.html#copy-subject-to-another-project), including all skills, from one project to another +- Trainee achievement celebrations with congratulatory messages displayed throughout training displays when levels, badges, and skills are achieved + - Added [project configuration option](/dashboard/user-guide/projects.html#setting-hide-achievement-celebration) to disable achievement celebrations +- Enhanced Project Deletion Protection + - Clear warning of permanent removal of users and definitions + - Requirement for multiple administrator acknowledgments before removal + - New project setting: [Project Deletion Protection](/dashboard/user-guide/projects.html#setting-project-deletion-protection) to prevent deletion when enabled +- Introduced "Points First Earned" column on users table for project, subject, skill, and badge administrative pages +- Self Reported skills enhancements + - Feedback provision to users when approving self-reported skills + - Historical display of self-reporting requests and responses + - Trainee access to submitted justification for self-reported skills +- Skills Group usage improvements + - Enhanced skill page display with group name and description + - Group name/description display can be [disabled/enabled by project administrators](/dashboard/user-guide/projects.html#setting-hide-group-info-on-skill-pages) + - Ability to collapse and expand all Skills Groups, with expansion state persisted in browser local storage +- Embedded video resizing + - Administrator configuration of default [video](/dashboard/user-guide/skills.html#videos) size + - Trainees can resize videos, and their personalized configurations are automatically persisted in the browser's local storage +- Enhanced the [result object](/skills-client/endpoints.html#endpoint-result-object) returned by the [Report Skill Endpoint](/skills-client/endpoints.html#report-skill-event-endpoint) to include information about the earned and available points for the skill. +- Improved terminology for Quiz and Survey Choice questions + + +## 3.2.5 +- Spring Boot Upgrade + +## 3.2.4 +- Bug Fixes + +## 3.2.3 +- Bug Fixes +## 3.2.2 +- Spring Boot Upgrade + +## 3.2.1 +- Bug Fixes + ## 3.2.0 -- Introduced the ability to manage project and quiz administrators in [groups](/dashboard/user-guide/admin-groups.html. +- Introduced the ability to manage project and quiz administrators in [groups](/dashboard/user-guide/admin-groups.html). - The new approach allows for simple creation and management of Admin Groups. - Admin groups can easily be assigned to multiple projects and/or quizzes. - Introduced a brand-new quiz question type: `Input Text` with a comprehensive grading mechanism. diff --git a/docs/screenshots/admin/component-project-settings.png b/docs/screenshots/admin/component-project-settings.png new file mode 100644 index 00000000..f8fe7977 Binary files /dev/null and b/docs/screenshots/admin/component-project-settings.png differ diff --git a/docs/screenshots/admin/component-user_progress_table.png b/docs/screenshots/admin/component-user_progress_table.png index f98764f9..367fdcd0 100644 Binary files a/docs/screenshots/admin/component-user_progress_table.png and b/docs/screenshots/admin/component-user_progress_table.png differ diff --git a/docs/screenshots/admin/component-users_archive.png b/docs/screenshots/admin/component-users_archive.png new file mode 100644 index 00000000..f5c23376 Binary files /dev/null and b/docs/screenshots/admin/component-users_archive.png differ diff --git a/docs/screenshots/admin/component-users_table_ready_to_archive.png b/docs/screenshots/admin/component-users_table_ready_to_archive.png new file mode 100644 index 00000000..257ec8ea Binary files /dev/null and b/docs/screenshots/admin/component-users_table_ready_to_archive.png differ diff --git a/docs/screenshots/admin/modal-new-question.png b/docs/screenshots/admin/modal-new-question.png index a12b16a0..f801b376 100644 Binary files a/docs/screenshots/admin/modal-new-question.png and b/docs/screenshots/admin/modal-new-question.png differ diff --git a/docs/skills-client/endpoints.md b/docs/skills-client/endpoints.md index 3d8bad00..bf6a6b46 100644 --- a/docs/skills-client/endpoints.md +++ b/docs/skills-client/endpoints.md @@ -76,6 +76,9 @@ Here is an example of an event that (1) was successfully applied, (2) completed/ "skillId":"ImportantSkill", "name":"Important Skill", "pointsEarned": 15, + "totalPointsEarned": 30, + "totalPoints": 30, + "numOccurrencesToCompletion": 2, "skillApplied":true, "explanation":"Skill event was applied", "completed":[{ @@ -94,20 +97,23 @@ Here is an example of an event that (1) was successfully applied, (2) completed/ Here is a reference table for result fields and their meaning: -| Field | Type | Explanation | -| :------- | :----------- | :----------- | -| success | *boolean* | ``true`` if there were no issues reporting the skill, ``false`` if there was a server side failure - this could happen if the service is down or you stumbled on a bug | -| projectId | *string* | the projectId that the report skill belongs to | -| skillId | *string* | the skillId of the report skill | -| name | *string* | the display name of the report skill | -| pointsEarned | *number* | number of points earned by this request | -| skillApplied | *boolean* | ``true`` if this event contributed points to the skill; ``false`` if the event didn't contribute points - ``explanation`` field will tell you why (see examples below) | -| explanation | *string* | human readable explanation about how this skill event was handled; this field will explain why an event wasn't able to contribute points (see examples below) | -| completed | *list* | metadata of a completed item if this event caused user to level-up, complete a skill or earn a badge/gem (just to mention a few) | -| completed.type | *string* | type of the completed item, will be one of these well-known values: ``Overall``, ``Subject``, ``Skill``, ``Badge``. ``Overall`` indicates that the user leveled-up for the entire project, ``Subject`` indicates that the user leveled-up for a specific subject, ``Skill`` indicates that this skill is fully accomplished, ``Badge`` indicates that a badge/gem was earned. | -| completed.level | *int* | indicates which level the user achieved via this skill event; only applicable to ``Overall`` and ``Subject`` types | -| completed.id | *string* | id of the completed item, in the case of ``Skill`` type this will be skill id, in the case of ``Subject`` type it will be subject id and so on... | -| completed.name | *string* | human friendly name of the event and can be used to display to the end user | +| Field | Type | Explanation | +|:--------------------------------------------------------------------------------------------|:----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| success | *boolean* | ``true`` if there were no issues reporting the skill, ``false`` if there was a server side failure - this could happen if the service is down or you stumbled on a bug | +| projectId | *string* | the projectId that the report skill belongs to | +| skillId | *string* | the skillId of the report skill | +| name | *string* | the display name of the report skill | +| pointsEarned | *number* | number of points earned by this request | +| totalPointsEarned | *number* | total points earned by this user for this skill | +| totalPoints | *number* | total points defined by an administrator for this skill | +| numOccurrencesToCompletion | *number* | number of times skill needs to be performed to earn all its points | +| skillApplied | *boolean* | ``true`` if this event contributed points to the skill; ``false`` if the event didn't contribute points - ``explanation`` field will tell you why (see examples below) | +| explanation | *string* | human readable explanation about how this skill event was handled; this field will explain why an event wasn't able to contribute points (see examples below) | +| completed | *list* | metadata of a completed item if this event caused user to level-up, complete a skill or earn a badge/gem (just to mention a few) | +| completed.type | *string* | type of the completed item, will be one of these well-known values: ``Overall``, ``Subject``, ``Skill``, ``Badge``. ``Overall`` indicates that the user leveled-up for the entire project, ``Subject`` indicates that the user leveled-up for a specific subject, ``Skill`` indicates that this skill is fully accomplished, ``Badge`` indicates that a badge/gem was earned. | +| completed.level | *int* | indicates which level the user achieved via this skill event; only applicable to ``Overall`` and ``Subject`` types | +| completed.id | *string* | id of the completed item, in the case of ``Skill`` type this will be skill id, in the case of ``Subject`` type it will be subject id and so on... | +| completed.name | *string* | human friendly name of the event and can be used to display to the end user | Here is an example where the skill event did not contribute any points because it's already fully accomplished: ```json @@ -117,6 +123,9 @@ Here is an example where the skill event did not contribute any points because i "skillId":"ImportantSkill", "name":"Important Skill", "pointsEarned": 0, + "totalPointsEarned": 200, + "totalPoints": 200, + "numOccurrencesToCompletion": 2, "skillApplied":false, "explanation":"This skill reached its maximum points", "completed":[] @@ -131,6 +140,9 @@ Here is an example where the skill event did not contribute any points because i "skillId":"ImportantSkill", "name":"Important Skill", "pointsEarned": 0, + "totalPointsEarned": 0, + "totalPoints": 200, + "numOccurrencesToCompletion": 2, "skillApplied":false, "explanation":"Not all dependent skills have been achieved. Missing achievements for 1 out of 1. Waiting on completion of [FirstProject:skill1Skill].", "completed":[] @@ -145,6 +157,9 @@ Below is an example where the skill contributed points but did not complete anyt "skillId":"ImportantSkill", "name":"Important Skill", "pointsEarned": 15, + "totalPointsEarned": 30, + "totalPoints": 45, + "numOccurrencesToCompletion": 3, "skillApplied":true, "explanation":"Skill event was applied", "completed":[] diff --git a/package.json b/package.json index 0979d8b7..1fc68075 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,10 @@ "@vuepress/plugin-register-components": "2.0.0-rc.66", "@vuepress/plugin-search": "2.0.0-rc.70", "@vuepress/theme-default": "2.0.0-rc.69", + "cypress": "13.17.0", + "cypress-real-events": "1.13.0", "license-checker": "25.0.1", - "sass-embedded": "1.83.1", + "sass-embedded": "1.83.4", "vuepress": "2.0.0-rc.19" } }