Update project entry properties
This commit is contained in:
parent
1f18f0feeb
commit
937c6cff2e
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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 => ({
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@
|
|||
@import "~styles/helpers";
|
||||
|
||||
.project-entry-modal {
|
||||
display: flex;
|
||||
|
||||
&__heading {
|
||||
@include heading-3;
|
||||
margin-bottom: 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
fragment ProjectEntryParts on ProjectEntryNode {
|
||||
id
|
||||
activity
|
||||
reflection
|
||||
nextSteps
|
||||
description
|
||||
documentUrl
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,8 @@ query ProjectQuery($id: ID, $slug: String){
|
|||
project(slug: $slug, id: $id) {
|
||||
...ProjectParts
|
||||
entries {
|
||||
edges {
|
||||
node {
|
||||
...ProjectEntryParts
|
||||
created
|
||||
}
|
||||
}
|
||||
...ProjectEntryParts
|
||||
created
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
@ -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),
|
||||
),
|
||||
]
|
||||
|
|
@ -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)
|
||||
]
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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}'
|
||||
)
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue