complete code:
// Import lodash for deep property access
import _ from ‘lodash’;
export default defineComponent({
name: ‘Generate Reports’,
version: ‘0.0.1’,
key: ‘generate-reports’,
type: ‘action’,
async run({ steps, $ }) {
// Function to extract properties from a database item with data validation
const extractProperties = (item, schema) => {
const extracted = {};
for (const [key, path] of Object.entries(schema)) {
if (_.has(item, path)) { // Validate if the path exists in the item before extracting
const value = _.get(item, path);
if (value !== null && value !== undefined) {
extracted[key] = value;
}
}
}
return extracted;
};
_// Function to build the schema of an object_
**const** buildSchema = (obj, schema = {}) => {
**for** (**const** key **in** obj) {
**if** (**typeof** obj[key] === 'object' && obj[key] !== **null**) {
schema[key] = {};
buildSchema(obj[key], schema[key]);
} **else** {
schema[key] = **typeof** obj[key];
}
}
**return** schema;
};
_// Function to print the schema of an object_
**const** printSchema = (obj, indent = 0) => {
**for** (**const** key **in** obj) {
console.log(" ".repeat(indent) + key);
**if** (**typeof** obj[key] === 'object' && obj[key] !== **null**) {
printSchema(obj[key], indent + 2);
}
}
};
// Retrieve data from Notion databases
const taskDatabaseEntries = await steps?.retrieve_tasks_database?.$return_value || [];
const projectDatabaseEntries = await steps?.retrieve_projects_database?.$return_value || [];
const areaDatabaseEntries = await steps?.retrieve_areas_database?.$return_value || [];
// Initialize reports
let areaReports = {};
let projectReports = {};
let taskReports = {};
// Define schemas for extracting properties
const areaSchema = {
type: ‘properties.Type.select.name’,
projects: ‘properties.Projects.relation’,
name: ‘properties.Name.title[0].text.content’,
areaNotes: ‘properties[“Area Notes”].rich_text[0].text.content’,
resources: ‘properties.Resources.relation’,
subscriptions: ‘properties.Subscriptions.relation’,
goals: ‘properties.goals.relation’,
overview: ‘properties.Overview.rich_text[0].text.content’,
coverImageUrl: ‘cover.file.url’,
emoji: ‘icon.emoji’
};
const projectSchema = {
name: ‘properties.Name.title[0].text.content’,
status: ‘properties.Status.select.name’,
priority: ‘properties.Priority.checkbox’,
targetDeadlineType: ‘properties[“Target Deadline”].date’,
overdueTasks: ‘properties[“Overdue Tasks”].rollup.number’,
createdTime: ‘properties.Created.created_time’,
quarter: ‘properties.Quarter.formula.string’,
progress: ‘properties.Progress.formula.number’,
tasksDone: ‘properties[“Tasks Done”].rollup.number’,
goalRelation: ‘properties.Goal.relation’,
areaRelation: ‘properties.Area.relation’,
projectTasks: ‘properties[“Project Tasks”].rollup.number’,
pulledResourcesRelation: ‘properties[“Pulled Resources”].relation’,
notesRelation: ‘properties.Notes.relation’,
pulledNotesRelation: ‘properties[“Pulled Notes”].relation’,
summary: ‘properties.Summary.rich_text[0].text.content’,
reviewNotes: ‘properties[“Review Notes”].rich_text[0].text.content’,
meta: ‘properties.Meta.formula.string’,
completedDate: ‘properties.Completed.date’,
iconEmoji: ‘icon.emoji’,
coverUrl: ‘cover.file.url’,
url: ‘url’
};
const taskSchema = {
taskTitle: ‘properties.Task.title[0].text.content’,
priority: ‘properties.Priority.select.name’,
dueDate: ‘properties.Due.date’,
isDone: ‘properties.Done.checkbox’,
kanbanStatus: ‘properties[“Kanban Status”].select.name’,
summary: ‘properties.Summary.rich_text[0].text.content’,
assignee: ‘properties.Assignee.people’,
projectIds: ‘properties.Project.relation’,
startDate: ‘properties.Start.date’,
lastEditedTime: ‘properties.Edited.last_edited_time’,
parentTask: ‘properties[“Parent Task”].relation’,
subTaskCount: ‘properties[“Sub-Task Count”].rollup.type’,
type: ‘properties.Type.formula.string’,
kanbanTag: ‘properties[“Kanban - Tag”].select’,
recurUnit: ‘properties[“Recur Unit”].select’,
isCold: ‘properties.Cold.formula.boolean’,
note: ‘properties.Note.rich_text’,
emoji: ‘icon.emoji’,
createdBy: ‘properties[“Created By”].created_by.name’,
url: ‘url’
};
// Abstract the processing into helper functions
function processAreas(areas, schema) {
areas.forEach(area => {
const areaData = extractProperties(area, schema);
areaReports[area.id] = {
…areaData,
projects: []
};
});
}
function processProjects(projects, schema) {
projects.forEach(project => {
const projectData = extractProperties(project, schema);
projectReports[project.id] = {
…projectData,
tasks: []
};
const areaId = _.get(project, ‘properties.Area.relation[0].id’);
if (areaReports[areaId]) {
areaReports[areaId].projects.push(projectData);
}
});
}
function processTasks(tasks, schema) {
tasks.forEach(task => {
const taskData = extractProperties(task, schema);
taskReports[task.id] = taskData;
const projectId = _.get(task, ‘properties.Project.relation[0].id’);
if (projectReports[projectId]) {
projectReports[projectId].tasks.push(taskData);
}
});
}
// Call the helper functions
processAreas(areaDatabaseEntries, areaSchema);
processProjects(projectDatabaseEntries, projectSchema);
processTasks(taskDatabaseEntries, taskSchema);
// Move schema printing out
console.log(“Schema for areaReports:”);
printSchema(areaReports);
_// Generate JSON reports_
**const** areaReportsJSON = JSON.stringify(areaReports);
**const** projectReportsJSON = JSON.stringify(projectReports);
**const** taskReportsJSON = JSON.stringify(taskReports);
_// Print the schema of the reports_
console.log("Schema for areaReports:");
printSchema(areaReports);
console.log("Schema for projectReports:");
printSchema(projectReports);
console.log("Schema for taskReports:");
printSchema(taskReports);
// Build the schema of the reports
const areaReportsSchema = buildSchema(areaReports);
const projectReportsSchema = buildSchema(projectReports);
const taskReportsSchema = buildSchema(taskReports);
// Convert the schema to JSON
const areaReportsSchemaJSON = JSON.stringify(areaReportsSchema);
const projectReportsSchemaJSON = JSON.stringify(projectReportsSchema);
const taskReportsSchemaJSON = JSON.stringify(taskReportsSchema);
// Exports
return {
areaReports,
projectReports,
taskReports,
areaReportsJSON,
projectReportsJSON,
taskReportsJSON,
areaReportsSchema,
projectReportsSchema,
taskReportsSchema,
areaReportsSchemaJSON,
projectReportsSchemaJSON,
taskReportsSchemaJSON
};
},
});