Skip to content

Commit

Permalink
Add getPracticeChallenges
Browse files Browse the repository at this point in the history
  • Loading branch information
oriooctopus committed May 12, 2022
1 parent d47a4c1 commit 35c3218
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ module.exports = {
const challengeMeta = event.result.challengeMeta;
if (challengeMeta) {
/**
* This is a temporary hack u
* This is a temporary hack until
* https://github.com/strapi/strapi/issues/13216 gets resolved
*/
await handleInternalLabel({
Expand Down
8 changes: 7 additions & 1 deletion src/api/playground/content-types/playground/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@
"type": "text"
},
"prompt": {
"type": "richtext"
"type": "richtext",
"required": true
},
"editorMeta": {
"type": "component",
"repeatable": false,
"component": "misc.editor-meta"
},
"challengeMeta": {
"type": "component",
"repeatable": false,
"component": "challenge.challenge-meta"
}
}
}
71 changes: 71 additions & 0 deletions src/extensions/users-permissions/content-types/user/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"kind": "collectionType",
"collectionName": "up_users",
"info": {
"name": "user",
"description": "",
"singularName": "user",
"pluralName": "users",
"displayName": "User"
},
"options": {
"draftAndPublish": false,
"timestamps": true
},
"attributes": {
"username": {
"type": "string",
"minLength": 3,
"unique": true,
"configurable": false,
"required": true
},
"email": {
"type": "email",
"minLength": 6,
"configurable": false,
"required": true
},
"provider": {
"type": "string",
"configurable": false
},
"password": {
"type": "password",
"minLength": 6,
"configurable": false,
"private": true
},
"resetPasswordToken": {
"type": "string",
"configurable": false,
"private": true
},
"confirmationToken": {
"type": "string",
"configurable": false,
"private": true
},
"confirmed": {
"type": "boolean",
"default": false,
"configurable": false
},
"blocked": {
"type": "boolean",
"default": false,
"configurable": false
},
"role": {
"type": "relation",
"relation": "manyToOne",
"target": "plugin::users-permissions.role",
"inversedBy": "users",
"configurable": false
},
"challengeCompletions": {
"type": "json",
"required": true
}
}
}
71 changes: 27 additions & 44 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"use strict";
const getPracticeChallenges = require("./resolvers/getPracticeChallenges");
const nextLessonSlug = require("./resolvers/nextLessonSlug");

module.exports = {
/**
Expand All @@ -11,64 +13,45 @@ module.exports = {
const extensionService = strapi.plugin("graphql").service("extension");

const extension = ({ nexus }) => ({
// Nexus
types: [
nexus.objectType({
name: "GetPracticeChallengesResponse",
description: "Custom object for getPracticeChallenges query",
definition(t) {
t.list.field("allChallenges", { type: "ChallengeUnion" });
t.list.int("recommendedChallenges");
},
}),
nexus.unionType({
name: "ChallengeUnion",
description: "All possible challenge types",
definition(t) {
t.members("CodeChallenge", "MultipleChoiceChallenge", "Playground");
},
resolveType(item) {
return item.challengeType;
},
}),
nexus.queryType({
definition(t) {
t.field("nextLessonSlug", {
type: "String",
args: {
currentLessonId: nexus.intArg(),
},
});
nextLessonSlug.queryDefinition({ nexus, t });
getPracticeChallenges.queryDefinition({ nexus, t });
},
}),
],
// GraphQL SDL
typeDefs: `
type Article {
name: String
}
`,
resolvers: {
Query: {
nextLessonSlug: {
async resolve(_context, { currentLessonId }) {
console.log("before");
const result = await strapi.db
.query("api::module.module")
.findOne({
where: {
id: 1,
},
populate: {
moduleLessons: {
populate: ["lesson"],
},
},
});
const { moduleLessons: lessons } = result;
const currentLessonIndex = lessons.findIndex(
({ lesson: { id } }) => id === currentLessonId
);

if (currentLessonIndex === -1) {
throw new Error(`Lesson of id ${currentLessonId} not found`);
}

if (currentLessonIndex === lessons.length - 1) {
return null;
}

return lessons[currentLessonIndex + 1].lesson.slug;
},
},
getPracticeChallenges: { resolve: getPracticeChallenges.resolve },
nextLessonSlug: { resolve: nextLessonSlug.resolve },
},
},
resolversConfig: {
"Query.nextLessonSlug": {
auth: false,
},
"Query.getPracticeChallenges": {
auth: false,
},
},
});
extensionService.use(extension);
Expand Down
49 changes: 49 additions & 0 deletions src/resolvers/getPracticeChallenges.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const { insertPropertiesIf } = require("../utils/general");
const getChallenges = require("../utils/getChallenges");

module.exports = {
queryDefinition: ({ nexus, t }) => {
t.field("getPracticeChallenges", {
type: "GetPracticeChallengesResponse",
args: {
lessonSlug: nexus.stringArg(),
sublessonId: nexus.intArg(),
},
});
},
async resolve(_context, { sublessonId, lessonSlug }) {
console.log("yoo?");
return {
allChallenges: (
await getChallenges({
strapi,
includeTypename: true,
parameters: {
populate: ["challengeMeta.sublesson", "challengeMeta.lesson"],
filters: {
challengeMeta: {
...insertPropertiesIf(sublessonId, {
sublesson: {
id: sublessonId,
},
}),
...insertPropertiesIf(lessonSlug, {
lesson: {
id: lessonSlug,
},
}),
},
},
},
})
).flat(),
recommendedChallenges: sublessonId
? await strapi.db.query("api::sublesson.sublesson").findOne({
where: {
id: sublessonId,
},
})
: [],
};
},
};
36 changes: 36 additions & 0 deletions src/resolvers/nextLessonSlug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module.exports = {
queryDefinition: ({ nexus, t }) => {
t.field("nextLessonSlug", {
type: "String",
args: {
currentLessonId: nexus.intArg(),
},
});
},
async resolve(_context, { currentLessonId }) {
const result = await strapi.db.query("api::module.module").findOne({
where: {
id: 1,
},
populate: {
moduleLessons: {
populate: ["lesson"],
},
},
});
const { moduleLessons: lessons } = result;
const currentLessonIndex = lessons.findIndex(
({ lesson: { id } }) => id === currentLessonId
);

if (currentLessonIndex === -1) {
throw new Error(`Lesson of id ${currentLessonId} not found`);
}

if (currentLessonIndex === lessons.length - 1) {
return null;
}

return lessons[currentLessonIndex + 1].lesson.slug;
},
};
5 changes: 5 additions & 0 deletions src/utils/general.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ const handleInternalLabel = async ({ sublesson, populateLesson = false }) => {
: `Unassigned - ${sublessonName}`;
};

function insertPropertiesIf(condition, properties) {
return condition ? properties : {};
}

module.exports = {
handleInternalLabel,
insertPropertiesIf,
};
34 changes: 34 additions & 0 deletions src/utils/getChallenges.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const challengeTypes = [
{
apiReference: "api::code-challenge.code-challenge",
typeName: "CodeChallenge",
},
{
apiReference: "api::multiple-choice-challenge.multiple-choice-challenge",
typeName: "MultipleChoiceChallenge",
},
{
apiReference: "api::playground.playground",
typeName: "Playground",
},
];

module.exports = async ({ strapi, parameters, includeTypename }) => {
const challengeGroups = await Promise.all(
challengeTypes.map(({ apiReference }) =>
strapi.entityService.findMany(apiReference, parameters)
)
);

const final = includeTypename
? challengeTypes.flatMap(({ typeName }, index) =>
challengeGroups[index].map((challenge) => {
return {
...challenge,
challengeType: typeName,
};
})
)
: t;
return final;
};

0 comments on commit 35c3218

Please sign in to comment.