|
|
(3 intermediate revisions by the same user not shown) |
Line 5: |
Line 5: |
| <includeonly> | | <includeonly> |
| <script> | | <script> |
| // Wait for the other scripts to be ready because we need jQuery
| | var username = "<!--{$userName}-->".toLowerCase(); |
| window.addEventListener('load', function () {
| | var sessionID = "<!--{$sessionID}-->"; |
|
| | window.addEventListener('load', (event) => { |
| /**
| | merlinProficiencyProgress(username, sessionID); |
| * Add a row to a table
| |
| *
| |
| * @param {jQuery} $table The jQuery object for the table element
| |
| * @param {Array} cells An array of cells to add to the table
| |
| * @param {Object} attrs Any attributes to set on the row
| |
| * @return {jQuery} The row jQuery object
| |
| */
| |
| function addRowToTable($table, cells, attrs = {}) {
| |
| // Figure out tbody
| |
| const $tbody = $table.find('tbody');
| |
|
| |
| // Create an empty row
| |
| let $row = $(`<tr></tr>`);
| |
| | |
| // Iterate over each cell
| |
| for (let i = 0; i < cells.length; i++) {
| |
| // Get the cell
| |
| const cell = cells[i];
| |
|
| |
| let $cell = null;
| |
|
| |
| // Check if it should be a th or td
| |
| if (cell.header) {
| |
| $cell = $('<th scope="row"></th>');
| |
| } else {
| |
| $cell = $('<td></td>');
| |
| }
| |
|
| |
| // Set any necessary attributes
| |
| if (cell.attributes && (typeof cell.attributes == 'object')) {
| |
| for (let [key, value] of Object.entries(cell.attributes)) {
| |
| // Combine into a string if needed
| |
| if (Array.isArray(value)) {
| |
| value = value.join(' ');
| |
| }
| |
|
| |
| // Set the attribute
| |
| $cell.attr(key, value);
| |
| }
| |
| }
| |
|
| |
| // Set the cell data
| |
| $cell.html(cell.data);
| |
|
| |
| // Add to the cell to the row
| |
| $row.append($cell);
| |
| }
| |
| | |
| // Add attributes to the row
| |
| for (const [key, value] of Object.entries(attrs)) {
| |
| $row.attr(key, value);
| |
| }
| |
|
| |
| $tbody.append($row);
| |
| | |
| return $row;
| |
| }
| |
| | |
| // Fetch and process the data
| |
| async function getData() {
| |
| // Staging or production
| |
| let baseUrl = "https://" + (window.location.hostname == 'www.codermerlin.com' ? 'api-server.codermerlin.com' : 'api-server-stg.codermerlin.com');
| |
| | |
| // Add the path
| |
| const username = "<!--{$userName}-->".toLowerCase();
| |
| const sessionId = "<!--{$sessionID}-->";
| |
| const path = `/mission-manager/users/${username}/mastery-progress/programs`;
| |
| | |
| // Development
| |
| let json;
| |
| if (window.location.hostname == "") {
| |
| } else {
| |
| // Request the data
| |
| json = await $.ajax(baseUrl + path, {
| |
| headers: {
| |
| username: username,
| |
| sessionId: sessionId
| |
| },
| |
| dataType: "json"
| |
| });
| |
| }
| |
| | |
| let rawData = json;
| |
| | |
| // Re-order everything by the sequence
| |
| const orderKey = 'masteryProgramTopicSequence';
| |
| | |
| rawData.rows.sort(function(a, b) {
| |
| if (a[orderKey] > b[orderKey]) {
| |
| return -1;
| |
| } else if (a[orderKey] < b[orderKey]) {
| |
| return 1;
| |
| } else {
| |
| return 0;
| |
| }
| |
| });
| |
| | |
| let data = [];
| |
| | |
| const stages = ['Inevident', 'Emerging', 'Developing', 'Proficient', 'Exemplary'];
| |
| | |
| for (let i = 0; i < rawData.rows.length; i++) {
| |
| // Get the row
| |
| let row = rawData.rows[i];
| |
| | |
| // Extract the necessary info
| |
| const points = row['pointsEarned'];
| |
| let dataRow = {};
| |
| | |
| dataRow['topic'] = row['masteryProgramTopicName'];
| |
| dataRow['data'] = [];
| |
|
| |
| // Iterate over the stages
| |
| for (let j = 0; j < stages.length; j++) {
| |
| // Build the key for the minimum points to get to a stage
| |
| let stageKey = stages[j].toLowerCase() + 'MinimumPoints';
| |
| | |
| // The minimum points
| |
| const minPoints = row[stageKey];
| |
| | |
| // Calculate the percentage complete
| |
| let pct = points / minPoints;
| |
| | |
| // If the last stage isn't complete, the next one can't be either
| |
| if (j > 0 && dataRow['data'][j - 1]['pct'] < 1.0) {
| |
| pct = 0.0;
| |
| }
| |
| | |
| let formattedPct = (pct > 0) ? Math.round(pct * 100) + '%' : '';
| |
| | |
| dataRow['data'].push({
| |
| date: (points >= minPoints) ? 'Passed' : formattedPct,
| |
| pct: pct
| |
| });
| |
| }
| |
| | |
| data.push(dataRow);
| |
| }
| |
| | |
| | |
| return data;
| |
| } | |
| | |
| // Wait for the DOM
| |
| $(function () {
| |
| // Get a table instance
| |
| let $table = $('table#mastery-progress-table');
| |
|
| |
| // Fetch the data
| |
| let $rows = [];
| |
| getData().then(async function (data) {
| |
| // Iterate over each topic
| |
| for (let i = 0; i < data.length; i++) {
| |
| let topic = data[i];
| |
| | |
| let cells = [];
| |
| | |
| // Set the first row to the title
| |
| cells.push({
| |
| header: true,
| |
| data: topic.topic,
| |
| attributes: {
| |
| style: `background-color: ${topic.data[0].date ? 'lightgreen' : 'lightgray'};`
| |
| }
| |
| });
| |
| | |
| // Iterate over the rest of the data
| |
| for (let j = 0; j < topic.data.length; j++) {
| |
| let stage = topic.data[j];
| |
| | |
| // Calculate the RGB green value
| |
| const m = 15;
| |
| const greenColor = ((j + 1) * m) + (240 - (m * topic.data.length));
| |
| | |
| // Get the percentage rounded to 2 decimal places
| |
| // 4 because a percentage is a decimal anyways
| |
| const pct = parseFloat(stage.pct).toFixed(4);
| |
| | |
| // Background color for the cell
| |
| let backgroundColor = `rgb(0, ${greenColor}, 0)`;
| |
| | |
| // If not complete, the background should be blue
| |
| if (pct < 1.0) {
| |
| backgroundColor = "rgb(0, 167, 225)";
| |
| }
| |
|
| |
| // Append
| |
| cells.push({
| |
| header: false,
| |
| data: stage.date,
| |
| attributes: {
| |
| //style: `background-color: ${(stage.date) ? `rgb(0, ${greenColor}, 0)` : 'lightgray'}; text-align: center;`,
| |
| style: `background-image: linear-gradient(to right, ${backgroundColor} ${pct * 100}%, lightgray 0%); text-align: center;`
| |
| }
| |
| });
| |
| }
| |
| | |
| // Add to the table
| |
| let $row = addRowToTable($table, cells, {style: 'opacity: 0.0;'});
| |
| | |
| $rows.push($row);
| |
| }
| |
| | |
| for (let i = 0; i < $rows.length; i++) {
| |
| let $row = $rows[i];
| |
| | |
| // Animate
| |
| const animationTime = 200;
| |
| | |
| $row.animate({opacity: 1.0}, animationTime);
| |
| | |
| // Wait for half of the animation
| |
| await (new Promise(resolve => setTimeout(resolve, animationTime / 5)));
| |
| }
| |
| });
| |
| });
| |
| }); | | }); |
| </script> | | </script> |
| </includeonly> | | </includeonly> |