Skip to content

Commit

Permalink
Merge pull request #32 from theodi/rotated-model
Browse files Browse the repository at this point in the history
Rotated model
  • Loading branch information
davetaz authored Oct 1, 2024
2 parents 5e71912 + f741b99 commit 0615c79
Show file tree
Hide file tree
Showing 15 changed files with 9,242 additions and 5,053 deletions.
3 changes: 2 additions & 1 deletion controllers/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ async function createProject(projectData, userId) {

// Clone the dimensions of the assessment into the project's assessmentData field
projectData.assessmentData = {
dimensions: assessment.dimensions
dimensions: assessment.dimensions,
levels: assessment.levels
};
// Create a new project instance
const project = new Project(projectData);
Expand Down
5 changes: 2 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ db.once('open', function() {
const logger = require('morgan');
app.use(logger('dev'));

// Middleware for parsing incoming requests
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ limit: '10mb', extended: true }));

// Other middleware and setup code...

Expand Down
208 changes: 48 additions & 160 deletions lib/docxBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ function createHeatmapTable(data, levelKeys, title = "Dimension") {
children: [
new Paragraph({
children: [
new TextRun( {
new TextRun({
text: level,
color: "FFFFFF",
verticalAlign: "center",
Expand All @@ -399,7 +399,7 @@ function createHeatmapTable(data, levelKeys, title = "Dimension") {
if (Array.isArray(data.dimensions)) {
// Handle dimensions
data.dimensions.forEach((dimension) => {
if (dimension.userProgress && Array.isArray(dimension.userProgress.levelCoveragePercent)) {
if (dimension.userProgress && typeof dimension.userProgress.levelCoveragePercent === 'object') {
const rowCells = [
new TableCell({
children: [
Expand All @@ -414,8 +414,8 @@ function createHeatmapTable(data, levelKeys, title = "Dimension") {
fill: colors.lightGrey,
},
}),
...dimension.userProgress.levelCoveragePercent.map((levelObject, index) => {
const percentage = levelObject[index + 1] || 0;
...levelKeys.map((_, index) => {
const percentage = dimension.userProgress.levelCoveragePercent[index + 1] || 0;
let cellContent = `${percentage}%`;
let shadingColor = colors.lightGrey;

Expand Down Expand Up @@ -452,7 +452,7 @@ function createHeatmapTable(data, levelKeys, title = "Dimension") {
);
}
});
} else if (data.userProgress && Array.isArray(data.userProgress.levelCoveragePercent)) {
} else if (data.userProgress && typeof data.userProgress.levelCoveragePercent === 'object') {
// Handle a single activity or dimension
const rowCells = [
new TableCell({
Expand All @@ -468,8 +468,8 @@ function createHeatmapTable(data, levelKeys, title = "Dimension") {
fill: colors.lightGrey,
},
}),
...data.userProgress.levelCoveragePercent.map((levelObject, index) => {
const percentage = levelObject[index + 1] || 0;
...levelKeys.map((_, index) => {
const percentage = data.userProgress.levelCoveragePercent[index + 1] || 0;
let cellContent = `${percentage}%`;
let shadingColor = colors.lightGrey;

Expand Down Expand Up @@ -568,24 +568,16 @@ function createActivityQuestionsTables(activity, levelKeys) {

const paddingSize = 100; // Size in twips (1/20 of a point)

const createTableRows = (statements) => {
return statements.map(statement => {
const level = statement.associatedLevel;
const levelColor = levelColors[level] || colors.lightGrey; // Default to light grey if no level color
const createTableRows = (questions) => {
return questions.map(question => {
console.log(question);
const level = question.userAnswer?.level || 0;
const levelColor = levelColors[level] || colors.lightGrey;

const cells = [
// Question Column
new TableCell({
children: [new Paragraph({
children: [
new TextRun( {
text: levelKeys[level - 1],
color: "FFFFFF",
})
],
})],
shading: {
fill: levelColor,
},
children: [new Paragraph(question.text)],
margins: {
top: paddingSize,
bottom: paddingSize,
Expand All @@ -594,8 +586,13 @@ function createActivityQuestionsTables(activity, levelKeys) {
},
verticalAlign: "center",
}),
// User Answer Column
new TableCell({
children: [new Paragraph(statement.text)],
children: [new Paragraph({
text: question.userAnswer?.text
? question.userAnswer.text
: "No answer",
})],
margins: {
top: paddingSize,
bottom: paddingSize,
Expand All @@ -604,25 +601,26 @@ function createActivityQuestionsTables(activity, levelKeys) {
},
verticalAlign: "center",
}),
// Level Column
new TableCell({
children: [
new Paragraph({
text: statement.userAnswer
? (statement.userAnswer.answer === statement.positive ? "✔" : "✗")
: "-",
alignment: AlignmentType.CENTER, // Center the text in the paragraph
}),
],
children: [new Paragraph({
text: level ? levelKeys[level - 1] : 'No Level',
color: "FFFFFF",
})],
shading: {
fill: levelColor,
},
margins: {
top: paddingSize,
bottom: paddingSize,
left: paddingSize,
right: paddingSize,
},
verticalAlign: "center", // Ensure the content is vertically centered
verticalAlign: "center",
}),
// Notes Column
new TableCell({
children: [new Paragraph(statement.userAnswer && statement.userAnswer.notes ? statement.userAnswer.notes : "-")],
children: [new Paragraph(question.userAnswer?.notes || "-")],
margins: {
top: paddingSize,
bottom: paddingSize,
Expand All @@ -637,7 +635,6 @@ function createActivityQuestionsTables(activity, levelKeys) {
});
};

// Function to create a complete table with a heading and rows
const createTableWithHeading = (headingText, rows) => {
const heading = new Paragraph({
text: headingText,
Expand All @@ -649,8 +646,8 @@ function createActivityQuestionsTables(activity, levelKeys) {
new TableCell({
children: [
new Paragraph({
text: "Level",
alignment: AlignmentType.CENTER, // Center the text in the paragraph
text: "Question",
alignment: AlignmentType.CENTER,
}),
],
shading: {
Expand All @@ -661,8 +658,8 @@ function createActivityQuestionsTables(activity, levelKeys) {
new TableCell({
children: [
new Paragraph({
text: "Question",
alignment: AlignmentType.CENTER, // Center the text in the paragraph
text: "Answer",
alignment: AlignmentType.CENTER,
}),
],
shading: {
Expand All @@ -673,8 +670,8 @@ function createActivityQuestionsTables(activity, levelKeys) {
new TableCell({
children: [
new Paragraph({
text: "Achieved",
alignment: AlignmentType.CENTER, // Center the text in the paragraph
text: "Level",
alignment: AlignmentType.CENTER,
}),
],
shading: {
Expand All @@ -686,7 +683,7 @@ function createActivityQuestionsTables(activity, levelKeys) {
children: [
new Paragraph({
text: "Notes",
alignment: AlignmentType.CENTER, // Center the text in the paragraph
alignment: AlignmentType.CENTER,
}),
],
shading: {
Expand All @@ -708,25 +705,14 @@ function createActivityQuestionsTables(activity, levelKeys) {
return [heading, table];
};

// Filter statements by level
const currentLevelStatements = activity.statements.filter(statement => statement.associatedLevel === activity.userProgress.achievedLevel);
const nextLevelStatements = activity.statements.filter(statement => statement.associatedLevel === activity.userProgress.achievedLevel + 1);
const higherLevelStatements = activity.statements.filter(statement =>
statement.associatedLevel > activity.userProgress.achievedLevel + 1 &&
(statement.userAnswer && (statement.userAnswer.answer !== undefined || statement.userAnswer.notes))
);
// Generate table rows for all questions in the activity
const questionRows = createTableRows(activity.questions);

// Create tables for each level
const currentLevelTable = createTableWithHeading("Current state at achieved level", createTableRows(currentLevelStatements));
const nextLevelTable = createTableWithHeading("Progress towards next level", createTableRows(nextLevelStatements));
const higherLevelTable = createTableWithHeading("Answers/Notes from higher levels", createTableRows(higherLevelStatements));
// Create a table with heading for the questions and answers
const questionTable = createTableWithHeading("Activity Questions and Answers", questionRows);

// Return all tables combined
return [
...currentLevelTable,
...nextLevelTable,
...higherLevelTable,
];
// Return the table as the output
return questionTable;
}

function checkFileExists(filePath) {
Expand Down Expand Up @@ -775,6 +761,10 @@ function getPublicationYear() {

async function generateDocxReport(projectData,owner,template = "template") {
let levelKeys = ["Initial", "Repeatable", "Defined", "Managed", "Optimising"];
const assessmentData = projectData.assessmentData;
if (assessmentData.levels) {
levelKeys = assessmentData.levels;
}

// Create sections
const metadataSection = createMetadataSection(projectData);
Expand Down Expand Up @@ -857,106 +847,4 @@ async function generateDocxReport(projectData,owner,template = "template") {
}
}

/*
// Combine all sections into one document
const doc = new Document({
styles: {
paragraphStyles: [
{
id: "Title",
name: "Title",
basedOn: "Normal",
next: "Normal",
quickFormat: true,
run: {
font: "Helvetica",
size: 48, // 24pt
bold: false,
color: colors.darkblue,
},
paragraph: {
alignment: AlignmentType.CENTER,
spacing: { after: 400 },
},
},
{
id: "Heading1",
name: "Heading 1",
basedOn: "Normal",
next: "Normal",
quickFormat: true,
run: {
font: "Helvetica",
size: 36, // 18pt
bold: true,
color: colors.darkblue,
},
paragraph: {
spacing: { before: 500, after: 300 },
},
},
{
id: "Heading2",
name: "Heading 2",
basedOn: "Normal",
next: "Normal",
quickFormat: true,
run: {
font: "Helvetica",
size: 32, // 16pt
bold: true,
color: colors.darkblue,
},
paragraph: {
spacing: { before: 500, after: 300 },
},
},
{
id: "Heading2",
name: "Heading 2",
basedOn: "Normal",
next: "Normal",
quickFormat: true,
run: {
font: "Helvetica",
size: 28, // 16pt
bold: true,
color: colors.darkblue,
},
paragraph: {
spacing: { before: 300, after: 200 },
},
},
{
id: "Normal",
name: "Normal",
quickFormat: true,
run: {
font: "Helvetica",
size: 24, // 12pt
},
paragraph: {
spacing: { before: 200, after: 200 },
},
},
],
},
sections: [
{
properties: {},
children: [
...metadataSection,
...maturitySection,
...heatmapSection,
...dimensionSections,
],
},
],
});
return doc;
}
*/

module.exports = { generateDocxReport };
22 changes: 15 additions & 7 deletions models/assessment.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,26 @@ const statementSchema = new mongoose.Schema({
}],
associatedLevel: {
type: Number
},
positive: {
type: Boolean
}
}, { _id: false });

// Define the question schema
const questionSchema = new mongoose.Schema({
text: {
type: String
},
context: {
type: String
},
statements: [statementSchema]
}, { _id: false });

// Define the activity schema
const activitySchema = new mongoose.Schema({
title: {
type: String
},
statements: [statementSchema],
questions: {
type: mongoose.Schema.Types.Mixed
}
questions: [questionSchema] // Array of questions
}, { _id: false });

// Define the dimension schema
Expand Down Expand Up @@ -110,6 +115,9 @@ const assessmentSchema = new mongoose.Schema({
default: false, // Default value is false (not public)
required: true
},
levels: {
type: [String], // Array of strings representing levels
},
readOnly: {
type: Boolean,
default: false, // Default value is false (not public)
Expand Down
Loading

0 comments on commit 0615c79

Please sign in to comment.