Add new mutation for module and chapter highlights

This commit is contained in:
Ramon Wenger 2024-02-21 21:55:34 +01:00
parent 9e536e0224
commit 092a531d33
7 changed files with 123 additions and 12 deletions

View File

@ -56,6 +56,7 @@ class ModuleNode(DjangoObjectType):
level = graphene.Field(ModuleLevelNode) level = graphene.Field(ModuleLevelNode)
category = graphene.Field(ModuleCategoryNode) category = graphene.Field(ModuleCategoryNode)
language = graphene.String() language = graphene.String()
highlights = graphene.List("notes.schema.HighlightNode")
def resolve_chapters(self, info, **kwargs): def resolve_chapters(self, info, **kwargs):
return Chapter.get_by_parent(self) return Chapter.get_by_parent(self)
@ -123,6 +124,10 @@ class ModuleNode(DjangoObjectType):
def resolve_language(parent: Module, info, **kwargs): def resolve_language(parent: Module, info, **kwargs):
return parent.locale.language_code return parent.locale.language_code
@staticmethod
def resolve_highlights(root: Module, info, **kwargs):
return root.highlights.filter(user=info.context.user)
class RecentModuleNode(DjangoObjectType): class RecentModuleNode(DjangoObjectType):
class Meta: class Meta:

View File

@ -17,10 +17,13 @@ class UpdateNoteArgument(InputObjectType):
class AddHighlightArgument(InputObjectType): class AddHighlightArgument(InputObjectType):
page = graphene.String(required=True) page = graphene.String(required=True)
content_index = graphene.Int(required=True)
content_uuid = graphene.UUID(required=True)
paragraph_index = graphene.Int(required=True) paragraph_index = graphene.Int(required=True)
text = graphene.String(required=True) text = graphene.String(required=True)
start_position = graphene.Int(required=True) start_position = graphene.Int(required=True)
selection_length = graphene.Int(required=True) selection_length = graphene.Int(required=True)
color = graphene.String(required=True) color = graphene.String(required=True)
class AddContentHighlightArgument(AddHighlightArgument):
content_index = graphene.Int(required=True)
content_uuid = graphene.UUID(required=True)

View File

@ -0,0 +1,22 @@
# Generated by Django 4.2.8 on 2024-02-21 14:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("notes", "0008_rename_content_block_highlight_page"),
]
operations = [
migrations.AlterField(
model_name="highlight",
name="content_index",
field=models.IntegerField(null=True),
),
migrations.AlterField(
model_name="highlight",
name="content_uuid",
field=models.UUIDField(null=True),
),
]

View File

@ -57,8 +57,8 @@ class Highlight(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
page = models.ForeignKey(Page, on_delete=models.CASCADE, related_name="highlights") page = models.ForeignKey(Page, on_delete=models.CASCADE, related_name="highlights")
# see highlight.ts for comments # see highlight.ts for comments
content_index = models.IntegerField() content_index = models.IntegerField(null=True)
content_uuid = models.UUIDField() content_uuid = models.UUIDField(null=True)
paragraph_index = models.IntegerField() paragraph_index = models.IntegerField()
start_position = models.IntegerField() start_position = models.IntegerField()
selection_length = models.IntegerField() selection_length = models.IntegerField()

View File

@ -8,7 +8,13 @@ from books.models import Chapter, ContentBlock, Module
from django.db import IntegrityError from django.db import IntegrityError
from graphene import relay from graphene import relay
from graphql_relay import from_global_id from graphql_relay import from_global_id
from notes.inputs import AddHighlightArgument, AddNoteArgument, UpdateNoteArgument from core.logger import get_logger
from notes.inputs import (
AddContentHighlightArgument,
AddHighlightArgument,
AddNoteArgument,
UpdateNoteArgument,
)
from notes.models import ( from notes.models import (
ChapterBookmark, ChapterBookmark,
ContentBlockBookmark, ContentBlockBookmark,
@ -19,6 +25,8 @@ from notes.models import (
) )
from notes.schema import HighlightNode, NoteNode from notes.schema import HighlightNode, NoteNode
logger = get_logger(__name__)
class UpdateContentBookmark(relay.ClientIDMutation): class UpdateContentBookmark(relay.ClientIDMutation):
class Input: class Input:
@ -285,6 +293,53 @@ class AddHighlight(relay.ClientIDMutation):
if highlight is None: if highlight is None:
raise Exception("No highlight provided, should not happen") raise Exception("No highlight provided, should not happen")
page_id = highlight.get("page")
paragraph_index = highlight.get("paragraph_index")
text = highlight.get("text")
start_position = highlight.get("start_position")
selection_length = highlight.get("selection_length")
color = highlight.get("color")
page_type, page_id = from_global_id(page_id)
if page_type == "ModuleNode":
page = Module.objects.get(id=page_id)
elif page_type == "ChapterNode":
page = Chapter.objects.get(id=page_id)
else:
raise Exception("wrong type")
logger.debug(page)
new_highlight = Highlight.objects.create(
page=page,
user=user,
paragraph_index=paragraph_index,
text=text,
start_position=start_position,
selection_length=selection_length,
color=color,
)
logger.debug(new_highlight)
logger.debug(new_highlight.page)
return cls(highlight=new_highlight)
class AddContentHighlight(relay.ClientIDMutation):
class Input:
highlight = graphene.Argument(AddContentHighlightArgument)
highlight = graphene.Field(HighlightNode)
@classmethod
def mutate_and_get_payload(cls, root, info, **kwargs):
user = info.context.user
highlight = kwargs.get("highlight")
if highlight is None:
raise Exception("No highlight provided, should not happen")
logger.debug(highlight)
page_id = highlight.get("page") page_id = highlight.get("page")
content_index = highlight.get("content_index") content_index = highlight.get("content_index")
content_uuid = highlight.get("content_uuid") content_uuid = highlight.get("content_uuid")
@ -320,6 +375,7 @@ class AddHighlight(relay.ClientIDMutation):
class NoteMutations: class NoteMutations:
add_note = AddNote.Field() add_note = AddNote.Field()
add_highlight = AddHighlight.Field() add_highlight = AddHighlight.Field()
add_content_highlight = AddContentHighlight.Field()
delete_highlight = DeleteHighlight.Field() delete_highlight = DeleteHighlight.Field()
update_highlight = UpdateHighlight.Field() update_highlight = UpdateHighlight.Field()
update_note = UpdateNote.Field() update_note = UpdateNote.Field()

View File

@ -1,8 +1,10 @@
import graphene import graphene
from basicknowledge.queries import InstrumentNode from basicknowledge.queries import InstrumentNode
from books.schema.nodes.content import ContentBlockNode from books.schema.nodes import ContentBlockNode, ModuleNode
from graphene import relay from graphene import relay
from graphene_django import DjangoObjectType from graphene_django import DjangoObjectType
from books.schema.nodes.chapter import ChapterNode
from core.logger import get_logger
from notes.models import ( from notes.models import (
ChapterBookmark, ChapterBookmark,
ContentBlockBookmark, ContentBlockBookmark,
@ -12,6 +14,8 @@ from notes.models import (
Note, Note,
) )
logger = get_logger(__name__)
class NoteNode(DjangoObjectType): class NoteNode(DjangoObjectType):
pk = graphene.Int() pk = graphene.Int()
@ -67,7 +71,7 @@ class InstrumentBookmarkNode(DjangoObjectType):
class HighlightableNode(graphene.Union): class HighlightableNode(graphene.Union):
class Meta: class Meta:
types = (ContentBlockNode, InstrumentNode) types = (ContentBlockNode, InstrumentNode, ModuleNode, ChapterNode)
class HighlightNode(DjangoObjectType): class HighlightNode(DjangoObjectType):

View File

@ -128,6 +128,7 @@ type ModuleNode implements ModuleInterface {
myChapterBookmarks(offset: Int, before: String, after: String, first: Int, last: Int): ChapterBookmarkNodeConnection myChapterBookmarks(offset: Int, before: String, after: String, first: Int, last: Int): ChapterBookmarkNodeConnection
snapshots: [SnapshotNode] snapshots: [SnapshotNode]
language: String language: String
highlights: [HighlightNode]
} }
interface ModuleInterface { interface ModuleInterface {
@ -624,8 +625,8 @@ type HighlightNode implements Node {
id: ID! id: ID!
user: PrivateUserNode! user: PrivateUserNode!
page: HighlightableNode page: HighlightableNode
contentIndex: Int! contentIndex: Int
contentUuid: UUID! contentUuid: UUID
paragraphIndex: Int! paragraphIndex: Int!
startPosition: Int! startPosition: Int!
selectionLength: Int! selectionLength: Int!
@ -634,7 +635,7 @@ type HighlightNode implements Node {
color: String! color: String!
} }
union HighlightableNode = ContentBlockNode | InstrumentNode union HighlightableNode = ContentBlockNode | InstrumentNode | ModuleNode | ChapterNode
type SnapshotObjectiveGroupNode implements Node { type SnapshotObjectiveGroupNode implements Node {
"""The ID of the object""" """The ID of the object"""
@ -1041,6 +1042,7 @@ type Mutation {
spellCheck(input: SpellCheckInput!): SpellCheckPayload spellCheck(input: SpellCheckInput!): SpellCheckPayload
addNote(input: AddNoteInput!): AddNotePayload addNote(input: AddNoteInput!): AddNotePayload
addHighlight(input: AddHighlightInput!): AddHighlightPayload addHighlight(input: AddHighlightInput!): AddHighlightPayload
addContentHighlight(input: AddContentHighlightInput!): AddContentHighlightPayload
deleteHighlight(input: DeleteHighlightInput!): DeleteHighlightPayload deleteHighlight(input: DeleteHighlightInput!): DeleteHighlightPayload
updateHighlight(input: UpdateHighlightInput!): UpdateHighlightPayload updateHighlight(input: UpdateHighlightInput!): UpdateHighlightPayload
updateNote(input: UpdateNoteInput!): UpdateNotePayload updateNote(input: UpdateNoteInput!): UpdateNotePayload
@ -1154,8 +1156,6 @@ input AddHighlightInput {
input AddHighlightArgument { input AddHighlightArgument {
page: String! page: String!
contentIndex: Int!
contentUuid: UUID!
paragraphIndex: Int! paragraphIndex: Int!
text: String! text: String!
startPosition: Int! startPosition: Int!
@ -1163,6 +1163,27 @@ input AddHighlightArgument {
color: String! color: String!
} }
type AddContentHighlightPayload {
highlight: HighlightNode
clientMutationId: String
}
input AddContentHighlightInput {
highlight: AddContentHighlightArgument
clientMutationId: String
}
input AddContentHighlightArgument {
page: String!
paragraphIndex: Int!
text: String!
startPosition: Int!
selectionLength: Int!
color: String!
contentIndex: Int!
contentUuid: UUID!
}
type DeleteHighlightPayload { type DeleteHighlightPayload {
success: Boolean! success: Boolean!
clientMutationId: String clientMutationId: String