Update project entry properties

This commit is contained in:
Ramon Wenger 2021-10-05 13:19:26 +02:00
parent 1f18f0feeb
commit 937c6cff2e
15 changed files with 124 additions and 65 deletions

View File

@ -51,6 +51,6 @@ describe('New project', () => {
cy.get('[data-cy=page-form-input-beschreibung]').should('exist').should('be.empty');
cy.get('[data-cy=page-form-input-ziele]').should('not.exist');
cy.get('[data-cy=save-project-button]').click();
cy.get('.project-widget:first').contains('random');
cy.getByDataCy('project').contains('random');
});
});

View File

@ -46,21 +46,14 @@ describe('Project Entry', () => {
},
'entriesCount': 1,
'__typename': 'ProjectNode',
'entries': {
'edges': [{
'node': {
'id': 'UHJvamVjdEVudHJ5Tm9kZTo2NQ==',
'activity': 'Kill Thanos',
'reflection': 'He sucks',
'nextSteps': 'Go for the head',
'documentUrl': '',
'__typename': 'ProjectEntryNode',
'created': '2020-01-20T15:20:31.262510+00:00',
},
'__typename': 'ProjectEntryNodeEdge',
}],
'__typename': 'ProjectEntryNodeConnection',
},
entries: [
{
id: 'UHJvamVjdEVudHJ5Tm9kZTo2NQ==',
description: 'Aktivität:\nKill Thanos\n\n\nReflexion:\nHe sucks\n\n\nNächste Schritte:\nGo for the head',
documentUrl: '',
created: '2020-01-20T15:20:31.262510+00:00',
},
],
},
},
AddProjectEntry: variables => ({

View File

@ -50,10 +50,7 @@
const variables = {slug: this.slug};
const data = store.readQuery({query, variables});
if (data.project && data.project.entries) {
data.project.entries.edges.push({
node: projectEntry,
__typename: 'ProjectEntryNode'
});
data.project.entries.push(projectEntry);
store.writeQuery({query, variables, data});
}
}

View File

@ -16,21 +16,11 @@
</li>
</more-options-widget>
<h3 class="project-entry__heading">Tätigkeit</h3>
<h3 class="project-entry__heading">{{ created }}</h3>
<p
class="project-entry__paragraph"
data-cy="project-entry-activity">
{{ activity }}
</p>
<h3 class="project-entry__heading">Reflexion</h3>
<p class="project-entry__paragraph">
{{ reflection }}
</p>
<h3 class="project-entry__heading">
Nächste Schritte
</h3>
<p class="project-entry__paragraph">
{{ nextSteps }}
{{ description }}
</p>
<p
class="project-entry__paragraph"
@ -51,7 +41,7 @@
import PROJECT_QUERY from '@/graphql/gql/queries/projectQuery.gql';
export default {
props: ['activity', 'reflection', 'nextSteps', 'documentUrl', 'created', 'id', 'readOnly'],
props: ['description', 'documentUrl', 'created', 'id', 'readOnly'],
components: {
DocumentBlock,
MoreOptionsWidget
@ -78,7 +68,7 @@
};
const data = store.readQuery({query, variables});
if (data) {
data.project.entries.edges.splice(data.project.entries.edges.findIndex(edge => edge.node.id === projectEntry.id), 1);
data.project.entries.splice(data.project.entries.findIndex(entry => entry.id === projectEntry.id), 1);
store.writeQuery({query, variables, data});
}
}
@ -105,6 +95,7 @@
&__paragraph {
margin-bottom: 30px;
white-space: pre-line;
}
&__date {

View File

@ -81,6 +81,8 @@
@import "~styles/helpers";
.project-entry-modal {
display: flex;
&__heading {
@include heading-3;
margin-bottom: 0;

View File

@ -1,7 +1,5 @@
fragment ProjectEntryParts on ProjectEntryNode {
id
activity
reflection
nextSteps
description
documentUrl
}

View File

@ -4,12 +4,8 @@ query ProjectQuery($id: ID, $slug: String){
project(slug: $slug, id: $id) {
...ProjectParts
entries {
edges {
node {
...ProjectEntryParts
created
}
}
...ProjectEntryParts
created
}
}

View File

@ -4,6 +4,7 @@ import factory
from core.factories import fake
from portfolio.models import Project, ProjectEntry
from users.models import User
class ProjectFactory(factory.django.DjangoModelFactory):
@ -14,4 +15,12 @@ class ProjectFactory(factory.django.DjangoModelFactory):
title = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(4, 8)))
appearance = factory.LazyAttribute(lambda x: random.choice(['red', 'green', 'yellow']))
final = False
student = factory.Iterator(User.objects.all())
class ProjectEntryFactory(factory.django.DjangoModelFactory):
class Meta:
model = ProjectEntry
project = factory.SubFactory(ProjectFactory)

View File

@ -0,0 +1,6 @@
def migrate_project_entries(ProjectEntry):
template = 'Tätigkeit:\n{}\n\n\nReflexion:\n{}\n\n\nNächste Schritte:\n{}'
for pe in ProjectEntry.objects.all():
pe.description = template.format(pe.activity, pe.reflection, pe.next_steps)
pe.save()

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.22 on 2021-09-28 12:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('portfolio', '0006_auto_20210810_1348'),
]
operations = [
migrations.AddField(
model_name='projectentry',
name='description',
field=models.TextField(blank=True),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 2.2.22 on 2021-09-28 12:27
from django.db import migrations
from portfolio.migration_helpers import migrate_project_entries
def migrate_project_entries_migration(apps, schema_editor):
ProjectEntry = apps.get_model('portfolio', 'ProjectEntry')
migrate_project_entries(ProjectEntry)
class Migration(migrations.Migration):
dependencies = [
('portfolio', '0007_projectentry_description'),
]
operations = [
migrations.RunPython(migrate_project_entries_migration)
]

View File

@ -19,8 +19,9 @@ class ProjectEntry(models.Model):
reflection = models.TextField(blank=True)
next_steps = models.TextField(blank=True)
document_url = models.TextField(blank=True)
description = models.TextField(blank=True)
created = models.DateTimeField(auto_now_add=True)
project = models.ForeignKey(Project, related_name='entries', on_delete=models.CASCADE)
def __str__(self):
return self.activity
return self.description

View File

@ -2,16 +2,23 @@ import graphene
from django.db.models import Q
from graphene import relay
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from api.utils import get_by_id_or_slug
from portfolio.models import Project, ProjectEntry
from users.models import Role, UserRole
class ProjectEntryNode(DjangoObjectType):
class Meta:
model = ProjectEntry
interfaces = (relay.Node,)
fields = ('description', 'document_url', 'project', 'created')
class ProjectNode(DjangoObjectType):
pk = graphene.Int()
entries_count = graphene.Int()
entries = graphene.List(ProjectEntryNode)
class Meta:
model = Project
@ -24,11 +31,9 @@ class ProjectNode(DjangoObjectType):
def resolve_entries_count(self, *args, **kwargs):
return self.entries.count()
class ProjectEntryNode(DjangoObjectType):
class Meta:
model = ProjectEntry
interfaces = (relay.Node,)
@staticmethod
def resolve_entries(root: Project, info, **kwargs):
return root.entries.all()
class PortfolioQuery(object):

View File

@ -0,0 +1,35 @@
from api.test_utils import DefaultUserTestCase
from core.tests.base_test import SkillboxTestCase
from portfolio.factories import ProjectEntryFactory
from portfolio.migration_helpers import migrate_project_entries
from portfolio.models import ProjectEntry
ACTIVITY='Kill Thanos'
REFLECTION='He sucks'
NEXT_STEPS='Go for the head'
class ProjectEntryMigrationTestCase(SkillboxTestCase):
def setUp(self):
self.createDefault()
self.project_entry = ProjectEntryFactory(
activity=ACTIVITY,
reflection=REFLECTION,
next_steps=NEXT_STEPS
)
def test_migration(self):
self.assertEqual(self.project_entry.description, '')
self.assertEqual(self.project_entry.activity, ACTIVITY)
self.assertEqual(self.project_entry.reflection, REFLECTION)
self.assertEqual(self.project_entry.next_steps, NEXT_STEPS)
migrate_project_entries(ProjectEntry)
project_entry = ProjectEntry.objects.get(id=self.project_entry.id)
self.assertEqual(project_entry.activity, ACTIVITY)
self.assertEqual(project_entry.reflection, REFLECTION)
self.assertEqual(project_entry.next_steps, NEXT_STEPS)
self.assertEqual(
project_entry.description,
f'Tätigkeit:\n{ACTIVITY}\n\n\nReflexion:\n{REFLECTION}\n\n\nNächste Schritte:\n{NEXT_STEPS}'
)

View File

@ -857,23 +857,11 @@ type PrivateUserNodeEdge {
}
type ProjectEntryNode implements Node {
id: ID!
activity: String!
reflection: String!
nextSteps: String!
documentUrl: String!
description: String!
created: DateTime!
project: ProjectNode!
}
type ProjectEntryNodeConnection {
pageInfo: PageInfo!
edges: [ProjectEntryNodeEdge]!
}
type ProjectEntryNodeEdge {
node: ProjectEntryNode
cursor: String!
id: ID!
}
type ProjectNode implements Node {
@ -886,7 +874,7 @@ type ProjectNode implements Node {
student: PrivateUserNode!
final: Boolean!
schoolClass: SchoolClassNode
entries(offset: Int, before: String, after: String, first: Int, last: Int): ProjectEntryNodeConnection!
entries: [ProjectEntryNode]
pk: Int
entriesCount: Int
}