Tomas 'Jethro' Pokorny
4 years ago
54 changed files with 91572 additions and 979 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,10 @@ |
|||||
|
from rest_framework import routers |
||||
|
from seminar import viewsets as vs |
||||
|
|
||||
|
router = routers.DefaultRouter() |
||||
|
|
||||
|
router.register(r'ulohavzoraknode', vs.UlohaVzorakNodeViewSet,basename='ulohavzoraknode') |
||||
|
router.register(r'text', vs.TextViewSet) |
||||
|
router.register(r'textnode', vs.TextNodeViewSet) |
||||
|
router.register(r'castnode', vs.CastNodeViewSet) |
||||
|
|
@ -0,0 +1,38 @@ |
|||||
|
/* |
||||
|
.pink { |
||||
|
background-color: #ffc0cb; |
||||
|
} |
||||
|
|
||||
|
div.borderized { |
||||
|
border-style: solid; |
||||
|
border-radius: 5px; |
||||
|
padding: 5px; |
||||
|
padding-right: 20px; |
||||
|
} |
||||
|
|
||||
|
div.tnmenu { |
||||
|
float: right; |
||||
|
margin-right: 0px; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
div.parent { |
||||
|
border-width: 2px; |
||||
|
} |
||||
|
|
||||
|
div.children { |
||||
|
border-width: 1px; |
||||
|
} |
||||
|
|
||||
|
div.node_type { |
||||
|
background-color: #d4d4d4; |
||||
|
} |
||||
|
|
||||
|
.hidden-tn { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
/*test*/ |
||||
|
h1 { |
||||
|
color: chartreuse; |
||||
|
} |
After Width: | Height: | Size: 1.8 MiB |
After Width: | Height: | Size: 1.8 MiB |
After Width: | Height: | Size: 1.8 MiB |
@ -0,0 +1,18 @@ |
|||||
|
function showSelectedItemForm(sel,id){ |
||||
|
var option; |
||||
|
var name; |
||||
|
var div; |
||||
|
Array.from(sel.options).forEach(function(option){ |
||||
|
console.log(option); |
||||
|
name = 'pridat-'+option.value+'-'+id; |
||||
|
div = document.getElementById(name); |
||||
|
console.log(div); |
||||
|
div.style.display = 'none'; |
||||
|
}); |
||||
|
name = sel.options[sel.selectedIndex].value; |
||||
|
name = 'pridat-'+name+'-'+id; |
||||
|
div = document.getElementById(name); |
||||
|
console.log(div); |
||||
|
div.style.display = 'block'; |
||||
|
|
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
{% extends 'base.html' %} |
||||
|
|
||||
|
{% load humanize %} |
||||
|
{% load staticfiles %} |
||||
|
|
||||
|
|
||||
|
{% block content %} |
||||
|
|
||||
|
<div class=jakresit> |
||||
|
|
||||
|
<img class="jakresit_obrazek" alt="" src="{% static 'images/jakresit_1.svg' %}" /> |
||||
|
<img class="jakresit_obrazek" alt="" src="{% static 'images/jakresit_2.svg' %}" /> |
||||
|
<img class="jakresit_obrazek" alt="" src="{% static 'images/jakresit_3.svg' %}" /> |
||||
|
|
||||
|
</div> |
||||
|
{% endblock %} |
@ -0,0 +1,23 @@ |
|||||
|
{% extends "seminar/archiv/base.html" %} |
||||
|
{% load staticfiles %} |
||||
|
{% load sekizai_tags %} |
||||
|
|
||||
|
{# toto z nejakeho duvodu nefunguje #} |
||||
|
{% addtoblock css %} |
||||
|
dfsdfs |
||||
|
<link rel="stylesheet" type="text/css" href="{% static 'css/mamweb-dev.css' %}" /> |
||||
|
{% endaddtoblock "css" %} |
||||
|
|
||||
|
{% block custom_css %} |
||||
|
<link rel="stylesheet" type="text/css" href="{% static 'css/mamweb-dev.css' %}" /> |
||||
|
{% endblock custom_css %} |
||||
|
|
||||
|
{% load comments %} |
||||
|
|
||||
|
{% block content %} |
||||
|
<ul> |
||||
|
{% for obj in object_list %} |
||||
|
<li>{{obj}} (id {{obj.id}})</li> |
||||
|
{% endfor %} |
||||
|
</ul> |
||||
|
{% endblock content %} |
@ -1,14 +1,25 @@ |
|||||
|
{% extends "base.html" %} |
||||
|
|
||||
|
|
||||
|
{% block content %} |
||||
|
<p style="text-align:justify">Témata jsou texty nejen z oblasti matematiky, fyziky a informatiky, které popisují nějaký problém a jsou doprovázeny návodnými úlohami. Vaším úkolem je zamyslet se nad daným problémem a sepsat vaše úvahy ve formě krátkého textu.</p> |
||||
|
|
||||
|
<p style="text-align:justify"><a href="/co-je-MaM/jak-resit/">Jak řešit téma?</a></p> |
||||
|
|
||||
|
<p style="text-align:justify"> </p> |
||||
|
|
||||
|
<h1>Aktuální témata</h1> |
||||
|
|
||||
{% for tematko in tematka %} |
{% for tematko in tematka %} |
||||
<h1>{{tematko.nazev}}</h1> |
<h2>{{tematko.nazev}}</h2> |
||||
|
<div class="tematko-obrazek"> |
||||
|
{% if tematko.obrazek %} |
||||
|
<a href="{{tematko.obrazek.url}}" class="ref-tema-obr"><img src="{{tematko.obrazek.url}}" height="{{tematko.obrazek.height}}" alt="{{tematko.nazev}}"></a> |
||||
|
{% else %} {# pokud témátko nemá fotku, zobrazuje se defaultní obrázek #} |
||||
|
{% load static %} <img src="{% static 'images/no-photo.png' %}" height=200px alt="{{tematko.nazev}}"> |
||||
|
{% endif %} |
||||
|
</div> |
||||
|
|
||||
<p>{{tematko.abstrakt}}</p> |
<p>{{tematko.abstrakt}}</p> |
||||
<ul> |
|
||||
{% for cislo in tematko.cisla %} |
|
||||
<li><a href="/{{rocnik}}/t{{tematko.kod}}/#{{cislo.0.1}}">{{cislo.0.0}}</a></li> |
|
||||
<ul> |
|
||||
{% for odkaz in cislo.1 %} |
|
||||
<li><a href="/{{rocnik}}/t{{tematko.kod}}/#{{odkaz.1}}">{{odkaz.0}}</a></li> |
|
||||
{% endfor %} |
|
||||
</ul> |
|
||||
{% endfor %} |
|
||||
</ul> |
|
||||
{% endfor %} |
{% endfor %} |
||||
|
{% endblock %} |
||||
|
@ -1,10 +1,12 @@ |
|||||
{% extends "base.html" %} |
{% extends "base.html" %} |
||||
|
{% load render_bundle from webpack_loader %} |
||||
|
|
||||
{% load comments %} |
|
||||
|
|
||||
{% block content %} |
{% block content %} |
||||
|
<div id="app"> |
||||
|
<app></app> |
||||
|
</div> |
||||
|
{% render_bundle 'chunk-vendors' %} |
||||
|
{% render_bundle 'vue_app_01' %} |
||||
|
|
||||
{%with obj=tnldata depth=1 template_name="seminar/treenode_recursive.html" %} |
|
||||
{%include template_name%} |
|
||||
{%endwith%} |
|
||||
{% endblock content %} |
{% endblock content %} |
||||
|
@ -0,0 +1,27 @@ |
|||||
|
{% load treenodes %} |
||||
|
{% if kam_slug == "syn" %} |
||||
|
{% appendableChildren obj as dostupne_typy %} |
||||
|
{% else %} |
||||
|
{% appendableChildren obj.parent as dostupne_typy %} |
||||
|
{% endif %} |
||||
|
|
||||
|
{# ulohaZadani ulohaVzorak Reseni Cast Text #} |
||||
|
{% if dostupne_typy %} |
||||
|
<div class="pink">Přidat {{kam}} |
||||
|
<select name="pridat-typ-{{obj.node.id}}-{{kam_slug}}" onchange="showSelectedItemForm(this,'{{obj.node.id}}-{{kam_slug}}')"> |
||||
|
{% for typ in dostupne_typy %} |
||||
|
<option value="{{typ.0}}">{{typ.1}}</option> |
||||
|
{% endfor %} |
||||
|
</select> |
||||
|
<div class="hidden-tn" id="pridat-castNode-{{obj.node.id}}-{{kam_slug}}"> |
||||
|
Nadpis: <input name="pridat-cast-{{obj.node.id}}-{{kam_slug}}" type="text"> |
||||
|
<button action="submit" formaction="{%url 'treenode_pridat' obj.node.id kam_slug%}">Přidat</button> |
||||
|
</div> |
||||
|
<div class="hidden-tn" id="pridat-textNode-{{obj.node.id}}-{{kam_slug}}"> Vytvořit</div> |
||||
|
<div class="hidden-tn" id="pridat-reseniNode-{{obj.node.id}}-{{kam_slug}}">Vytvořit, Tady bude autocomplete na reseniNode</div> |
||||
|
<div class="hidden-tn" id="pridat-ulohaZadaniNode-{{obj.node.id}}-{{kam_slug}}">Vytvořit zadání</div> |
||||
|
<div class="hidden-tn" id="pridat-ulohaVzorakNode-{{obj.node.id}}-{{kam_slug}}">Vytvořit vzorák k: Tady bude autocomplete na problémy k aktuálnímu kontextu</div> |
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
{% endif %}{# appendablebleChildren #} |
@ -0,0 +1,18 @@ |
|||||
|
{% load treenodes %} |
||||
|
{% if obj.node|isRocnik %} |
||||
|
<h{{depth}}> Ročník {{obj.node.rocnik}} </h{{depth}}> |
||||
|
{% elif obj.node|isCislo %} |
||||
|
<h{{depth}}> Číslo {{obj.node.cislo}} </h{{depth}}> |
||||
|
{% elif obj.node|isTemaVCisle %} |
||||
|
<h{{depth}}> Téma {{obj.node.tema.nazev}} </h{{depth}}> |
||||
|
{% elif obj.node|isUlohaZadani %} |
||||
|
<h{{depth}}>Úloha {{obj.node.uloha.kod_v_rocniku}} ({{obj.node.uloha.max_body}} b)</h{{depth}}> |
||||
|
{% elif obj.node|isUlohaVzorak %} |
||||
|
<h{{depth}}>Řešení: {{obj.node.uloha.kod_v_rocniku}}</h{{depth}}> |
||||
|
{% elif obj.node|isCast %} |
||||
|
<h{{depth}}> {{obj.node.nadpis}} </h{{depth}}> |
||||
|
{% elif obj.node|isText %} |
||||
|
{{obj.node.text.na_web}} |
||||
|
{% else %} |
||||
|
Objekt jiného typu {{obj.node}} |
||||
|
{% endif %} |
@ -1,28 +1,55 @@ |
|||||
{% load treenodes %} |
{% load treenodes %} |
||||
{# <b>{{depth}}</b> #} |
{# <b>{{depth}}</b> #} |
||||
<div> |
<div class="borderized parent"> |
||||
{% if obj.node|isRocnik %} |
<div class="node_type"> |
||||
<h{{depth}}> Ročník {{obj.node.rocnik}} </h{{depth}}> |
{{obj.node}} |
||||
{% elif obj.node|isCislo %} |
{{obj.node.id}} |
||||
<h{{depth}}> Číslo {{obj.node.cislo}} </h{{depth}}> |
{% if obj.node|deletable %} |
||||
{% elif obj.node|isTemaVCisle %} |
<button type="submit" formaction="{%url 'treenode_smazat' obj.node.id%}">Smazat</button> |
||||
<h{{depth}}> Téma {{obj.node.tema.nazev}} </h{{depth}}> |
{% endif %} |
||||
{% elif obj.node|isUlohaZadani %} |
{% if obj.parent and obj.parent|editableSiblings %} |
||||
<h{{depth}}>Úloha {{obj.node.uloha.kod_v_rocniku}} ({{obj.node.uloha.max_body}} b)</h{{depth}}> |
<button type="submit" formaction="{%url 'treenode_odvesitpryc' obj.node.id%}">Odvěsit pryč ze stromu {{obj.parent.node}}</button> |
||||
{% elif obj.node|isUlohaVzorak %} |
{% endif %} |
||||
<h{{depth}}>Řešení: {{obj.node.uloha.kod_v_rocniku}}</h{{depth}}> |
{% if obj|canPodvesitPred %} |
||||
{% elif obj.node|isText %} |
<button type="submit" formaction="{%url 'treenode_podvesit' obj.node.id 'pred'%}">Podvěsit pod předchozí</button> - nejsou testovací data |
||||
{{obj.node.text.na_web}} |
{% endif %} |
||||
{% else %} |
{% if obj|canPodvesitZa %} |
||||
Objekt jiného typu {{obj.node}} |
<button type="submit" formaction="{%url 'treenode_podvesit' obj.node.id 'za'%}">Podvěsit pod následující</button> - nejsou testovací data |
||||
|
{% endif %} |
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
{% if False %} |
||||
|
<div class="node_move"> |
||||
|
FIXME: není zatím implementováno |
||||
|
<button>Zvyš úroveň nadpisu</button> - nejsou testovací data |
||||
|
</div> |
||||
{% endif %} |
{% endif %} |
||||
|
{% include "seminar/treenode_name.html" %} |
||||
{%if obj.children %} |
{%if obj.children %} |
||||
<div> |
<div class="borderized children"> |
||||
|
|
||||
|
{% with kam="před" kam_slug="syn" %} {% include "seminar/treenode_add_stub.html" %} {% endwith %} |
||||
{%for ch in obj.children %} |
{%for ch in obj.children %} |
||||
{%with obj=ch depth=depth|add:"1" template_name="seminar/treenode_recursive.html" %} |
|
||||
{%include template_name%} |
{# ----------- Vypisujeme podstrom ----------#} |
||||
{%endwith%} |
{%with obj=ch depth=depth|add:"1" %} {%include "seminar/treenode_recursive.html" %} {%endwith%} |
||||
|
{# ----------- Přidáváme mezi syny / za posledního -------- #} |
||||
|
{% if forloop.last %} |
||||
|
{% with kam="za" kam_slug="za" obj=ch %} {% include "seminar/treenode_add_stub.html" %} {% endwith %} |
||||
|
{% else %} |
||||
|
{% with kam="mezi" obj=ch kam_slug="za" %} {% include "seminar/treenode_add_stub.html" %} {% endwith %} |
||||
|
{% endif %} |
||||
|
{# ----------- Prohazujeme sousedy ----------#} |
||||
|
<div class="pink"> |
||||
|
{% if not forloop.last and ch|editableSiblings %} |
||||
|
<button type="submit" formaction="{%url 'treenode_prohodit' ch.node.id%}">Prohodit ^ a v</button> |
||||
|
{% endif %} |
||||
|
</div> |
||||
{% endfor %} |
{% endfor %} |
||||
</div> |
</div> |
||||
|
{% else %} |
||||
|
{# ----------- Přidáváme prvního syna ----------#} |
||||
|
{% with kam="jako syna" kam_slug="syn" %} {% include "seminar/treenode_add_stub.html" %} {% endwith %} |
||||
{%endif%} |
{%endif%} |
||||
</div> |
</div> |
||||
|
@ -0,0 +1,7 @@ |
|||||
|
{% load render_bundle from webpack_loader %} |
||||
|
|
||||
|
<div id="app"> |
||||
|
<app></app> |
||||
|
</div> |
||||
|
{% render_bundle 'chunk-vendors' %} |
||||
|
{% render_bundle 'vue_app_01' %} |
@ -1,2 +1,3 @@ |
|||||
from .views_all import * |
from .views_all import * |
||||
from .autocomplete import * |
from .autocomplete import * |
||||
|
from .views_rest import * |
||||
|
@ -0,0 +1,162 @@ |
|||||
|
from rest_framework import serializers |
||||
|
from rest_polymorphic.serializers import PolymorphicSerializer |
||||
|
|
||||
|
import seminar.models as m |
||||
|
from seminar import treelib |
||||
|
|
||||
|
DEFAULT_NODE_DEPTH = 2 |
||||
|
|
||||
|
class TextSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.Text |
||||
|
fields = '__all__' |
||||
|
|
||||
|
|
||||
|
|
||||
|
class UlohaVzorakNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.UlohaVzorakNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class UlohaZadaniNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.UlohaZadaniNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class RocnikNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.RocnikNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class CisloNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.CisloNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class MezicisloNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.MezicisloNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class TemaVCisleNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.TemaVCisleNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class OrgTextNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.OrgTextNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class PohadkaNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.PohadkaNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class TextNodeSerializer(serializers.ModelSerializer): |
||||
|
text = TextSerializer() |
||||
|
|
||||
|
class Meta: |
||||
|
model = m.TextNode |
||||
|
fields = ('id','text','polymorphic_ctype') |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class TextNodeWriteSerializer(serializers.ModelSerializer): |
||||
|
text = TextSerializer() |
||||
|
|
||||
|
def update(self,node,validated_data): |
||||
|
node.text.na_web = validated_data.get('text').get('na_web') |
||||
|
node.text.save() |
||||
|
return node |
||||
|
|
||||
|
class Meta: |
||||
|
model = m.TextNode |
||||
|
fields = ('id','text') |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class TextNodeCreateSerializer(serializers.ModelSerializer): |
||||
|
text = TextSerializer() |
||||
|
refnode = serializers.CharField() |
||||
|
where = serializers.CharField() |
||||
|
|
||||
|
def create(self,validated_data): |
||||
|
temp_text = validated_data.pop('text') |
||||
|
where = validated_data.pop('where') |
||||
|
refnode_id = validated_data.pop('refnode') |
||||
|
refnode = m.TreeNode.objects.get(pk=refnode_id) |
||||
|
text = m.Text.objects.create(**temp_text) |
||||
|
if where == 'syn': |
||||
|
node = treelib.create_child(refnode,m.TextNode,text=text) |
||||
|
elif where == 'za': |
||||
|
node = treelib.create_node_after(refnode,m.TextNode,text=text) |
||||
|
elif where == 'pred': |
||||
|
node = treelib.create_node_before(refnode,m.TextNode,text=text) |
||||
|
node.where = None |
||||
|
node.refnode = None |
||||
|
return node |
||||
|
|
||||
|
class Meta: |
||||
|
model = m.TextNode |
||||
|
fields = ('text','where','refnode') |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class CastNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.CastNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class CastNodeCreateSerializer(serializers.ModelSerializer): |
||||
|
refnode = serializers.CharField() |
||||
|
where = serializers.CharField() |
||||
|
|
||||
|
def create(self,validated_data): |
||||
|
temp_nadpis = validated_data.pop('nadpis') |
||||
|
where = validated_data.pop('where') |
||||
|
refnode_id = validated_data.pop('refnode') |
||||
|
refnode = m.TreeNode.objects.get(pk=refnode_id) |
||||
|
if where == 'syn': |
||||
|
node = treelib.create_child(refnode,m.CastNode,nadpis=temp_nadpis) |
||||
|
elif where == 'za': |
||||
|
node = treelib.create_node_after(refnode,m.CastNode,nadpis=temp_nadpis) |
||||
|
elif where == 'pred': |
||||
|
node = treelib.create_node_before(refnode,m.CastNode,nadpis=temp_nadpis) |
||||
|
node.where = None |
||||
|
node.refnode = None |
||||
|
return node |
||||
|
|
||||
|
class Meta: |
||||
|
model = m.CastNode |
||||
|
fields = ('nadpis','where','refnode') |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
class ReseniNodeSerializer(serializers.ModelSerializer): |
||||
|
class Meta: |
||||
|
model = m.ReseniNode |
||||
|
fields = '__all__' |
||||
|
depth = DEFAULT_NODE_DEPTH |
||||
|
|
||||
|
|
||||
|
class TreeNodeSerializer(PolymorphicSerializer): |
||||
|
model_serializer_mapping = { |
||||
|
m.RocnikNode: RocnikNodeSerializer, |
||||
|
m.CisloNode: CisloNodeSerializer, |
||||
|
m.MezicisloNode: MezicisloNodeSerializer, |
||||
|
m.TemaVCisleNode: TemaVCisleNodeSerializer, |
||||
|
m.OrgTextNode: OrgTextNodeSerializer, |
||||
|
m.UlohaZadaniNode: UlohaZadaniNodeSerializer, |
||||
|
m.UlohaVzorakNode: UlohaVzorakNodeSerializer, |
||||
|
m.PohadkaNode: PohadkaNodeSerializer, |
||||
|
m.TextNode: TextNodeSerializer, |
||||
|
m.CastNode: CastNodeSerializer, |
||||
|
m.ReseniNode: ReseniNodeSerializer, |
||||
|
} |
||||
|
|
@ -0,0 +1,77 @@ |
|||||
|
from rest_framework import viewsets,filters |
||||
|
from . import models as m |
||||
|
from . import views |
||||
|
|
||||
|
class ReadWriteSerializerMixin(object): |
||||
|
""" |
||||
|
Overrides get_serializer_class to choose the read serializer |
||||
|
for GET requests and the write serializer for POST requests. |
||||
|
|
||||
|
Set read_serializer_class and write_serializer_class attributes on a |
||||
|
viewset. |
||||
|
""" |
||||
|
|
||||
|
read_serializer_class = None |
||||
|
create_serializer_class = None |
||||
|
write_serializer_class = None |
||||
|
|
||||
|
def get_serializer_class(self): |
||||
|
if self.action == "create": |
||||
|
return self.get_create_serializer_class() |
||||
|
if self.action in ["update", "partial_update", "destroy"]: |
||||
|
return self.get_write_serializer_class() |
||||
|
return self.get_read_serializer_class() |
||||
|
|
||||
|
def get_read_serializer_class(self): |
||||
|
assert self.read_serializer_class is not None, ( |
||||
|
"'%s' should either include a `read_serializer_class` attribute," |
||||
|
"or override the `get_read_serializer_class()` method." |
||||
|
% self.__class__.__name__ |
||||
|
) |
||||
|
return self.read_serializer_class |
||||
|
|
||||
|
def get_write_serializer_class(self): |
||||
|
assert self.write_serializer_class is not None, ( |
||||
|
"'%s' should either include a `write_serializer_class` attribute," |
||||
|
"or override the `get_write_serializer_class()` method." |
||||
|
% self.__class__.__name__ |
||||
|
) |
||||
|
return self.write_serializer_class |
||||
|
|
||||
|
def get_create_serializer_class(self): |
||||
|
assert self.create_serializer_class is not None, ( |
||||
|
"'%s' should either include a `create_serializer_class` attribute," |
||||
|
"or override the `get_create_serializer_class()` method." |
||||
|
% self.__class__.__name__ |
||||
|
) |
||||
|
return self.create_serializer_class |
||||
|
|
||||
|
class UlohaVzorakNodeViewSet(viewsets.ModelViewSet): |
||||
|
queryset = m.UlohaVzorakNode.objects.all() |
||||
|
serializer_class = views.UlohaVzorakNodeSerializer |
||||
|
|
||||
|
class TextViewSet(viewsets.ModelViewSet): |
||||
|
queryset = m.Text.objects.all() |
||||
|
serializer_class = views.TextSerializer |
||||
|
|
||||
|
class TextNodeViewSet(ReadWriteSerializerMixin,viewsets.ModelViewSet): |
||||
|
queryset = m.TextNode.objects.all() |
||||
|
read_serializer_class = views.TextNodeSerializer |
||||
|
write_serializer_class = views.TextNodeWriteSerializer |
||||
|
create_serializer_class = views.TextNodeCreateSerializer |
||||
|
|
||||
|
class CastNodeViewSet(ReadWriteSerializerMixin,viewsets.ModelViewSet): |
||||
|
queryset = m.CastNode.objects.all() |
||||
|
read_serializer_class = views.CastNodeSerializer |
||||
|
write_serializer_class = views.CastNodeSerializer |
||||
|
create_serializer_class = views.CastNodeCreateSerializer |
||||
|
|
||||
|
class UlohaVzorakNodeViewSet(viewsets.ModelViewSet): |
||||
|
serializer_class = views.UlohaVzorakNodeSerializer |
||||
|
|
||||
|
def get_queryset(self): |
||||
|
queryset = m.UlohaVzorakNode.objects.all() |
||||
|
nazev = self.request.query_params.get('nazev',None) |
||||
|
if nazev is not None: |
||||
|
queryset = queryset.filter(nazev__contains=nazev) |
||||
|
return queryset |
@ -0,0 +1,22 @@ |
|||||
|
.DS_Store |
||||
|
node_modules |
||||
|
/dist |
||||
|
|
||||
|
# local env files |
||||
|
.env.local |
||||
|
.env.*.local |
||||
|
|
||||
|
# Log files |
||||
|
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
|
yarn-error.log* |
||||
|
pnpm-debug.log* |
||||
|
|
||||
|
# Editor directories and files |
||||
|
.idea |
||||
|
.vscode |
||||
|
*.suo |
||||
|
*.ntvs* |
||||
|
*.njsproj |
||||
|
*.sln |
||||
|
*.sw? |
@ -0,0 +1,5 @@ |
|||||
|
module.exports = { |
||||
|
presets: [ |
||||
|
'@vue/cli-plugin-babel/preset' |
||||
|
] |
||||
|
} |
@ -0,0 +1,48 @@ |
|||||
|
{ |
||||
|
"name": "vue_frontend", |
||||
|
"version": "0.1.0", |
||||
|
"private": true, |
||||
|
"scripts": { |
||||
|
"serve": "vue-cli-service serve", |
||||
|
"build": "vue-cli-service build", |
||||
|
"lint": "vue-cli-service lint" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"@ckeditor/ckeditor5-upload": "^23.0.0", |
||||
|
"@ckeditor/ckeditor5-vue": "^1.0.1", |
||||
|
"axios": "^0.19.2", |
||||
|
"ckeditor5-build-classic-simple-upload-adapter-image-resize": "^1.0.4", |
||||
|
"core-js": "^3.6.5", |
||||
|
"vue": "^2.6.11", |
||||
|
"vue-router": "^3.4.3" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@vue/cli-plugin-babel": "~4.4.0", |
||||
|
"@vue/cli-plugin-eslint": "~4.4.0", |
||||
|
"@vue/cli-service": "^4.5.6", |
||||
|
"babel-eslint": "^10.1.0", |
||||
|
"eslint": "^6.7.2", |
||||
|
"eslint-plugin-vue": "^6.2.2", |
||||
|
"vue-template-compiler": "^2.6.11", |
||||
|
"webpack-bundle-tracker": "0.4.3" |
||||
|
}, |
||||
|
"eslintConfig": { |
||||
|
"root": true, |
||||
|
"env": { |
||||
|
"node": true |
||||
|
}, |
||||
|
"extends": [ |
||||
|
"plugin:vue/essential", |
||||
|
"eslint:recommended" |
||||
|
], |
||||
|
"parserOptions": { |
||||
|
"parser": "babel-eslint" |
||||
|
}, |
||||
|
"rules": {} |
||||
|
}, |
||||
|
"browserslist": [ |
||||
|
"> 1%", |
||||
|
"last 2 versions", |
||||
|
"not dead" |
||||
|
] |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
<template> |
||||
|
<router-view id="app"/> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { name: 'app' } |
||||
|
</script> |
@ -0,0 +1,50 @@ |
|||||
|
<template> |
||||
|
<div class="addnewnode"> |
||||
|
<button v-if="types.includes('castNode')" v-on:click="selected='castNode'" :disabled="selected && selected !== 'castNode'">Část</button> |
||||
|
<button v-if="types.includes('textNode')" v-on:click="selected='textNode'" :disabled="selected && selected !== 'textNode'">Text</button> |
||||
|
<button v-if="types.includes('reseniNode')" v-on:click="selected='reseniNode'" :disabled="selected && selected !== 'reseniNode'">Řešení</button> |
||||
|
<button v-if="types.includes('ulohaZadaniNode')" v-on:click="selected='ulohaZadaniNode'" :disabled="selected && selected !== 'ulohaZadaniNode'">Zadání úlohy</button> |
||||
|
<button v-if="types.includes('ulohaVzorakNode')" v-on:click="selected='ulohaVzorakNode'" :disabled="selected && selected !== 'ulohaVzorakNode'">Vzorák</button> |
||||
|
<div v-if="selected"> |
||||
|
<component :is='selected' :item='null' :where="where" :refnode="refnode" create></component> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import castNode from './CastNode.vue' |
||||
|
import textNode from './TextNode.vue' |
||||
|
import ulohaZadaniNode from './UlohaZadaniNode.vue' |
||||
|
import ulohaVzorakNode from './UlohaVzorakNode.vue' |
||||
|
//import reseniNode from './UlohaVzorakNode.vue' |
||||
|
|
||||
|
export default { |
||||
|
name: 'AddNewNode', |
||||
|
props: { |
||||
|
types: Array, |
||||
|
where: String, |
||||
|
refnode: Object, |
||||
|
}, |
||||
|
data: () => ({ |
||||
|
selected: null, |
||||
|
}), |
||||
|
components: { |
||||
|
castNode, |
||||
|
textNode, |
||||
|
ulohaZadaniNode, |
||||
|
ulohaVzorakNode, |
||||
|
}, |
||||
|
mounted: function() { |
||||
|
this.$root.$on('dataUpdated',(arg) => { |
||||
|
this.selected = null; |
||||
|
console.log('dataUpdated'+arg); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.addnewnode { |
||||
|
display: inline; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,86 @@ |
|||||
|
<template> |
||||
|
<div class="castnode"> |
||||
|
<!--pre>CastNode {{item}} {{typeof(item)}}</pre--> |
||||
|
<div v-if="editorShow"> |
||||
|
<input type="text" v-model="currentText" /> |
||||
|
<button v-on:click="saveText">Uložit</button> |
||||
|
<button v-on:click="currentText = originalText;editorShow=!editorShow;">Zahodit úpravy</button> |
||||
|
</div> |
||||
|
<div v-else> |
||||
|
<h4>{{ currentText }} </h4> <button v-if="editorMode" v-on:click="editorShow=!editorShow">Upravit</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import axios from 'axios' |
||||
|
|
||||
|
export default { |
||||
|
name: 'CastNode', |
||||
|
data: () => ({ |
||||
|
editorShow: false, |
||||
|
currentText: "", |
||||
|
originalText: "", |
||||
|
}), |
||||
|
props: { |
||||
|
item: Object, |
||||
|
editorShow: Boolean, |
||||
|
create: Boolean, |
||||
|
where: String, |
||||
|
refnode: Object |
||||
|
}, |
||||
|
mounted: function() { |
||||
|
if (this.create){ |
||||
|
this.currentText = ""; |
||||
|
this.originalText = ""; |
||||
|
this.editorShow = true; |
||||
|
} |
||||
|
else { |
||||
|
this.currentText = this.item.node.nadpis; |
||||
|
this.originalText = this.item.node.nadpis; |
||||
|
} |
||||
|
|
||||
|
//this.getText(); |
||||
|
}, |
||||
|
methods: { |
||||
|
saveText: function() { |
||||
|
console.log("Saving cast"); |
||||
|
console.log(this.currentText); |
||||
|
if (this.create){ |
||||
|
console.log(this.refnode); |
||||
|
console.log(this.where); |
||||
|
axios.post('/api/castnode/',{ |
||||
|
'nadpis': this.currentText, |
||||
|
'refnode': this.refnode.id, |
||||
|
'where': this.where |
||||
|
}).then(response => { |
||||
|
this.originalText = response.data.nadpis; |
||||
|
this.$root.$emit('updateData',"castNode create update"); |
||||
|
}) |
||||
|
.catch(e => { |
||||
|
console.log(e); |
||||
|
this.errors.push(e); |
||||
|
}); |
||||
|
} else { |
||||
|
axios.put('/api/castnode/'+this.item.node.id+'/',{ |
||||
|
'nadpis': this.currentText, |
||||
|
'id': this.item.node.id |
||||
|
}).then(response => { |
||||
|
this.originalText = response.data.nadpis; |
||||
|
}) |
||||
|
.catch(e => { |
||||
|
console.log(e); |
||||
|
this.errors.push(e) |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
this.editorShow = false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<!-- Add "scoped" attribute to limit CSS to this component only --> |
||||
|
<style scoped> |
||||
|
</style> |
@ -0,0 +1,19 @@ |
|||||
|
<template> |
||||
|
<div class="cislonode"> |
||||
|
<!--pre>CisloNode {{item}} {{typeof(item)}}</pre--> |
||||
|
<h1>{{ item.node.cislo.poradi }}. číslo</h1> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'CisloNode', |
||||
|
props: { |
||||
|
item: Object |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<!-- Add "scoped" attribute to limit CSS to this component only --> |
||||
|
<style scoped> |
||||
|
</style> |
@ -0,0 +1,21 @@ |
|||||
|
<template> |
||||
|
|
||||
|
<div class="rocniknode"> |
||||
|
<!--pre>RocnikNode {{item}} {{typeof(item)}}</pre--> |
||||
|
<h1>Ročník {{ item.node.rocnik.rocnik }} ({{ item.node.rocnik.prvni_rok }}/{{item.node.rocnik.prvni_rok+1 }})</h1> |
||||
|
</div> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'RocnikNode', |
||||
|
props: { |
||||
|
item: Object |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<!-- Add "scoped" attribute to limit CSS to this component only --> |
||||
|
<style scoped> |
||||
|
</style> |
@ -0,0 +1,19 @@ |
|||||
|
<template> |
||||
|
<div class="temavcislenode"> |
||||
|
<!--pre>TemaVCisleNode {{item}} {{typeof(item)}}</pre--> |
||||
|
<h2>Téma {{ item.node.tema.kod }}: {{ item.node.tema.nazev }}</h2> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'TemaVCisleNode', |
||||
|
props: { |
||||
|
item: Object |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<!-- Add "scoped" attribute to limit CSS to this component only --> |
||||
|
<style scoped> |
||||
|
</style> |
@ -0,0 +1,174 @@ |
|||||
|
<template> |
||||
|
<div v-if="loading" class="loading"> |
||||
|
<p>Loading...</p> |
||||
|
</div> |
||||
|
<div v-else class="textnode"> |
||||
|
<!--pre>TextNode {{item}} {{typeof(item)}}</pre--> |
||||
|
<template v-if="editorShow"> |
||||
|
|
||||
|
<div v-if="plainEditShow"> |
||||
|
<textarea id="textarea" v-model="currentText" rows="8" cols="50"></textarea> |
||||
|
<br> |
||||
|
<button v-on:click="plainEditShow=!plainEditShow">Editovat v editoru</button> |
||||
|
</div> |
||||
|
|
||||
|
<div v-else> |
||||
|
<component v-bind:is="editorComponent" :editor="editor" v-model="currentText" :config="editorConfig"></component> |
||||
|
<button v-on:click="plainEditShow=!plainEditShow">Editovat HTML</button> |
||||
|
</div> |
||||
|
<button v-on:click="saveText">Uložit</button> |
||||
|
<button v-on:click="currentText = originalText;editorShow=!editorShow;">Zahodit úpravy</button> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
<template v-else v-bind:class="changedObject"> |
||||
|
<p v-html="currentText"></p> |
||||
|
<button v-if="editorMode" v-on:click="editorShow=!editorShow">Upravit</button> |
||||
|
</template> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import axios from 'axios' |
||||
|
|
||||
|
//import ClassicEditor from '@ckeditor/ckeditor5-build-classic' |
||||
|
import ClassicEditor from 'ckeditor5-build-classic-simple-upload-adapter-image-resize'; |
||||
|
import CKEditor from '@ckeditor/ckeditor5-vue'; |
||||
|
|
||||
|
export default { |
||||
|
name: 'TextNode', |
||||
|
data: () => ({ |
||||
|
loading: false, |
||||
|
editor: ClassicEditor, |
||||
|
editorData: '<p>Content of the editor.</p>', |
||||
|
editorConfig: { |
||||
|
extraPlugins: ['SimpleUploadAdapter'], |
||||
|
simpleUpload: { |
||||
|
uploadUrl: "/temp/image_upload/", |
||||
|
headers: {}, |
||||
|
withCredentials: true |
||||
|
} |
||||
|
// The configuration of the editor. |
||||
|
}, |
||||
|
editorShow: false, |
||||
|
plainEditShow: false, |
||||
|
editorComponent: CKEditor.component, |
||||
|
currentText: "",// this.item.node.text.na_web, |
||||
|
originalText: "",// this.item.node.text.na_web, |
||||
|
}), |
||||
|
computed: { |
||||
|
changedObject: function () { |
||||
|
//console.log(this.currentText); |
||||
|
//console.log(this.originalText); |
||||
|
return { |
||||
|
changed: this.currentText !== this.originalText, |
||||
|
} |
||||
|
}, |
||||
|
textId: function () { |
||||
|
console.log(this.create); |
||||
|
console.log(this.node.text.id); |
||||
|
if (this.create){ |
||||
|
return null; |
||||
|
} |
||||
|
return this.node.text.id; |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
item: Object, |
||||
|
editorShow: Boolean, |
||||
|
editorMode: Boolean, |
||||
|
create: Boolean, |
||||
|
where: String, |
||||
|
refnode: Object |
||||
|
}, |
||||
|
mounted: function() { |
||||
|
//console.log("mounted"); |
||||
|
this.editorConfig.simpleUpload.headers['X-CSRFToken'] = this.getCookie('csrftoken'); |
||||
|
axios.defaults.headers.common['X-CSRFToken'] = this.getCookie('csrftoken'); |
||||
|
if (this.create){ |
||||
|
this.currentText = ""; |
||||
|
this.originalText = ""; |
||||
|
this.editorShow = true; |
||||
|
} else { |
||||
|
this.currentText = this.item.node.text.na_web; |
||||
|
this.originalText = this.item.node.text.na_web; |
||||
|
this.editorConfig.simpleUpload.headers.textId = this.item.node.text.id; |
||||
|
|
||||
|
} |
||||
|
//this.getText(); |
||||
|
}, |
||||
|
methods: { |
||||
|
getCookie: function (name){ |
||||
|
var cookieValue = null; |
||||
|
if (document.cookie && document.cookie != '') { |
||||
|
var cookies = document.cookie.split(';'); |
||||
|
for (var i = 0; i < cookies.length; i++) { |
||||
|
var cookie = cookies[i].trim(); |
||||
|
// Does this cookie string begin with the name we want? |
||||
|
|
||||
|
if (cookie.substring(0, name.length + 1) == (name + '=')) { |
||||
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return cookieValue; |
||||
|
}, |
||||
|
getText: function() { |
||||
|
this.loading = true; |
||||
|
console.log(this.item); |
||||
|
console.log(this.item.node.text); |
||||
|
axios.get('/treenode/text/'+this.item.node.text) |
||||
|
.then((response) => { |
||||
|
this.text = response.data.na_web; |
||||
|
this.loading = false; |
||||
|
}) |
||||
|
.catch((err) => { |
||||
|
this.loading = false; |
||||
|
console.log(err); |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
saveText: function() { |
||||
|
console.log("Saving text"); |
||||
|
console.log(this.currentText); |
||||
|
if (this.create){ |
||||
|
console.log(this.refnode); |
||||
|
console.log(this.where); |
||||
|
axios.post('/api/textnode/',{ |
||||
|
'text': { 'na_web': this.currentText}, |
||||
|
'refnode': this.refnode.id, |
||||
|
'where': this.where |
||||
|
}).then(response => { |
||||
|
this.originalText = response.data.text.na_web; |
||||
|
this.loading = false; |
||||
|
this.$root.$emit('updateData',"textNode create update"); |
||||
|
}) |
||||
|
.catch(e => { |
||||
|
this.errors.push(e) |
||||
|
}); |
||||
|
} else { |
||||
|
axios.put('/api/textnode/'+this.item.node.id+'/',{ |
||||
|
'text': { 'na_web': this.currentText}, |
||||
|
'id': this.item.node.id |
||||
|
}).then(response => { |
||||
|
this.originalText = response.data.text.na_web; |
||||
|
}) |
||||
|
.catch(e => { |
||||
|
this.errors.push(e) |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
this.editorShow = false; |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<!-- Add "scoped" attribute to limit CSS to this component only --> |
||||
|
<style scoped> |
||||
|
.changed { |
||||
|
background-color: 'yellow'; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,161 @@ |
|||||
|
<template> |
||||
|
|
||||
|
<div :class="editorMode ? 'treenode-org' : 'treenode'"> |
||||
|
<!--b v-if="v_tematu">v tematu</b> |
||||
|
<b v-if="visible">visible</b> |
||||
|
Force visible: {{String(force_visible)}}--> |
||||
|
<component :is='item.node.polymorphic_ctype.model' :item='item' :key='item.node.id' |
||||
|
:editorMode="editorMode" |
||||
|
:debugMode="debugMode"></component> |
||||
|
|
||||
|
|
||||
|
<button v-if="debugMode" v-on:click="debugShow = !debugShow" class="nodebug">Ladící data</button> <!-- bude tu nějaký if na class="nodebug", v debug módu bude tlačítko vidět, jinak ne --> |
||||
|
<div v-if="debugShow"> |
||||
|
<pre>{{ item.node.polymorphic_ctype.model }}</pre> |
||||
|
<pre>{{ item }}</pre> |
||||
|
</div> |
||||
|
|
||||
|
<div v-if="item.children.length === 0"> |
||||
|
<div v-if="item.appendable_children.length > 0 && editorMode"> |
||||
|
<b>Vložit jako syna: </b> |
||||
|
<addnewnode :types="item.appendable_children" :refnode="item.node" where="syn" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div v-else :class="editorMode ? 'children-org' : 'children'"> <!-- bude tu nějaký if na class="children" --> |
||||
|
<div v-if="item.children.length > 0 && item.children[0].appendable_siblings.length > 0 && editorMode"> |
||||
|
<b>Vložit před: </b> |
||||
|
<addnewnode :types="item.children[0].appendable_siblings" :refnode="item.children[0].node" where="pred" /> |
||||
|
</div> |
||||
|
<div v-if="item.node.polymorphic_ctype.model==='temavcislenode'"> |
||||
|
<!--Children: {{String(showChildren)}}--> |
||||
|
<div v-for="(chld, index) in item.children" v-bind:key="chld.nazev" > |
||||
|
<!--Hide: {{hideNode(chld)}}, v tematu: {{v_tematu}}, force_visible: {{force_visible}}--> |
||||
|
<div v-if="!hideNode(chld)"> |
||||
|
<div v-if="chld.node.polymorphic_ctype.model==='ulohazadaninode'"> |
||||
|
<button v-if="showChildren" v-on:click="showChildren=!showChildren"> Schovat </button> |
||||
|
<button v-else v-on:click="showChildren=!showChildren"> Rozbalit </button> |
||||
|
<TreeNode :item="chld" :v_tematu="true" |
||||
|
:force_visible="showChildren" |
||||
|
:editorMode="editorMode" |
||||
|
:debugMode="debugMode"> |
||||
|
</TreeNode> |
||||
|
</div> |
||||
|
<div v-else> |
||||
|
<TreeNode :item="chld" :v_tematu="true" |
||||
|
:force_visible="showChildren" |
||||
|
:editorMode="editorMode" |
||||
|
:debugMode="debugMode"> |
||||
|
</TreeNode> |
||||
|
</div> |
||||
|
<div v-if="chld.appendable_siblings.length > 0 && editorMode" > |
||||
|
<b v-if="index < (item.children.length - 1)">Vložit mezi: </b> |
||||
|
<b v-else>Vložit za: </b> |
||||
|
<addnewnode :types="chld.appendable_siblings" :refnode="chld.node" where="za" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<button v-if="showChildren" v-on:click="showChildren=!showChildren"> Schovat </button> |
||||
|
<button v-else v-on:click="showChildren=!showChildren"> Rozbalit </button> |
||||
|
</div> |
||||
|
<div v-else> |
||||
|
<div v-for="(chld, index) in item.children" v-bind:key="chld.nazev" > |
||||
|
<div v-if="v_tematu && chld.node.polymorphic_ctype.model==='ulohazadaninode'"> |
||||
|
<div> Tady možná něco je </div> |
||||
|
<TreeNode :item="chld" :v_tematu="v_tematu" |
||||
|
:force_visible="force_visible" |
||||
|
:editorMode="editorMode" |
||||
|
:debugMode="debugMode"> |
||||
|
</TreeNode> |
||||
|
</div> |
||||
|
<div v-else> |
||||
|
<TreeNode :item="chld" :v_tematu="v_tematu" |
||||
|
:force_visible="force_visible" |
||||
|
:editorMode="editorMode" |
||||
|
:debugMode="debugMode"> |
||||
|
</TreeNode> |
||||
|
</div> |
||||
|
<div v-if="chld.appendable_siblings.length > 0 && editorMode" > |
||||
|
<b v-if="index < (item.children.length - 1)">Vložit mezi: </b> |
||||
|
<b v-else>Vložit za: </b> |
||||
|
<addnewnode :types="chld.appendable_siblings" :refnode="chld.node" where="za" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
import rocniknode from './RocnikNode.vue' |
||||
|
import cislonode from './CisloNode.vue' |
||||
|
import temavcislenode from './TemaVCisleNode.vue' |
||||
|
import castnode from './CastNode.vue' |
||||
|
import textnode from './TextNode.vue' |
||||
|
import ulohazadaninode from './UlohaZadaniNode.vue' |
||||
|
import ulohavzoraknode from './UlohaVzorakNode.vue' |
||||
|
import addnewnode from './AddNewNode.vue' |
||||
|
|
||||
|
export default { |
||||
|
name: 'TreeNode', |
||||
|
components: { |
||||
|
rocniknode, |
||||
|
cislonode, |
||||
|
temavcislenode, |
||||
|
castnode, |
||||
|
textnode, |
||||
|
ulohazadaninode, |
||||
|
ulohavzoraknode, |
||||
|
addnewnode |
||||
|
}, |
||||
|
data: () => ({ |
||||
|
debugShow: false, |
||||
|
showChildren: false |
||||
|
}), |
||||
|
computed: { |
||||
|
}, |
||||
|
props: { |
||||
|
item: Object, |
||||
|
force_visible: Boolean, |
||||
|
v_tematu: Boolean, |
||||
|
editorMode: Boolean, |
||||
|
debugMode: Boolean, |
||||
|
}, |
||||
|
methods: { |
||||
|
hideNode: function(chld){ |
||||
|
if (this.showChildren || this.force_visible){ |
||||
|
return false; |
||||
|
} |
||||
|
if (chld.node.polymorphic_ctype.model === 'ulohazadaninode'){ |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<!-- Add "scoped" attribute to limit CSS to this component only --> |
||||
|
<style scoped> |
||||
|
|
||||
|
|
||||
|
.treenode-org { |
||||
|
padding: 5px; |
||||
|
margin: 5px; |
||||
|
border: #6a0043 2px solid; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.children-org { |
||||
|
padding: 10px; |
||||
|
margin: 5px; |
||||
|
border: #6a0043 2px dashed; |
||||
|
} |
||||
|
|
||||
|
.nodebug { |
||||
|
/* display: none; */ |
||||
|
} |
||||
|
|
||||
|
</style> |
@ -0,0 +1,70 @@ |
|||||
|
<template> |
||||
|
<div id="app"> |
||||
|
<div id="loading" v-if="loading"> |
||||
|
Loading... |
||||
|
</div> |
||||
|
<!--pre> |
||||
|
{{item}} |
||||
|
</pre--> |
||||
|
<button v-show="editorMode" v-on:click="editorMode = false">Vypnout editační mód</button> |
||||
|
<button v-show="!editorMode" v-on:click="editorMode = true">Zapnout editační mód</button> |
||||
|
<button v-show="debugMode" v-on:click="debugMode = false">Vypnout ladicí mód</button> |
||||
|
<button v-show="!debugMode" v-on:click="debugMode = true">Zapnout ladicí mód</button> |
||||
|
<TreeNode :item="item" :editorMode="editorMode" :debugMode="debugMode"/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import TreeNode from './TreeNode.vue' |
||||
|
import axios from 'axios' |
||||
|
export default { |
||||
|
name: 'App', |
||||
|
components: { |
||||
|
TreeNode, |
||||
|
}, |
||||
|
data: () => ({ |
||||
|
loading: true, |
||||
|
item: null, |
||||
|
tnid: 1, |
||||
|
editorMode: false, |
||||
|
debugMode: false, |
||||
|
}), |
||||
|
props:{ |
||||
|
tnid: Number, |
||||
|
editorMode: Boolean, |
||||
|
debugMode: Boolean, |
||||
|
}, |
||||
|
mounted: function() { |
||||
|
this.getArticles(); |
||||
|
this.$root.$on('updateData',(arg) => { |
||||
|
console.log(arg); |
||||
|
this.getArticles(); |
||||
|
}); |
||||
|
}, |
||||
|
methods: { |
||||
|
getArticles: function() { |
||||
|
this.loading = true; |
||||
|
axios.get('/treenode/'+this.tnid+'/json/') |
||||
|
.then((response) => { |
||||
|
this.item = response.data; |
||||
|
this.loading = false; |
||||
|
console.log('Data updated'); |
||||
|
this.$root.$emit('dataUpdated',"dataUpdated"); |
||||
|
}) |
||||
|
.catch((err) => { |
||||
|
this.loading = false; |
||||
|
console.log(err); |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
events: { |
||||
|
updateData: function(){ |
||||
|
this.getArticles() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
@import '../../../mamweb/static/css/mamweb.css'; |
||||
|
</style> |
@ -0,0 +1,74 @@ |
|||||
|
<template> |
||||
|
<div class="ulohavzoraknode"> |
||||
|
<!--pre>UlohaVzorakNode {{item}} {{typeof(item)}}</pre--> |
||||
|
<h5>Řešení {{item.node.uloha.cislo_zadani.poradi}}.{{ item.node.uloha.kod }}: {{ item.node.uloha.nazev }}</h5> |
||||
|
<button v-if="editorMode" v-on:click="showSelect=!showSelect" class="upravit">Upravit</button> |
||||
|
<div v-if="showSelect"> |
||||
|
<form class="searchForm" v-on:submit.prevent="submitSearch"> |
||||
|
<input type="text" v-model="searchQuery" placeholder="Napište název" @keyup="submitSearch"> |
||||
|
</form> |
||||
|
<div class="searchResult" v-show="isResult"> |
||||
|
<ul> |
||||
|
<li v-for="res in searchResults" :key="res.id" v-on:click="setSelected(res)">{{res.nazev}}</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import axios from 'axios' |
||||
|
|
||||
|
export default { |
||||
|
name: 'UlohaVzorakNode', |
||||
|
data: () => { |
||||
|
return { |
||||
|
isResult: false, |
||||
|
searchQuery: '', |
||||
|
searchResults: [], |
||||
|
showSelect: false, |
||||
|
selected: null, |
||||
|
selected_id: null |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
item: Object, |
||||
|
create: Boolean, |
||||
|
showSelect: Boolean, |
||||
|
}, |
||||
|
mounted: function(){ |
||||
|
if (this.item.node.uloha === null){ |
||||
|
console.log("Uloha je null!"); |
||||
|
console.log(this.item); |
||||
|
} |
||||
|
if (this.create){ |
||||
|
this.showSelect = true; |
||||
|
console.log('Creating'); |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
submitSearch: function(){ |
||||
|
if (this.searchQuery.length < 3) { return;} |
||||
|
var reqURL = "/api/ulohavzoraknode/?nazev="+this.searchQuery; |
||||
|
axios.get(reqURL).then( (response) => { |
||||
|
this.searchResults = response.data.results; |
||||
|
this.isResult = true; |
||||
|
console.log("Got:"); |
||||
|
console.log(this.searchResults); |
||||
|
}).catch( (err) => { /* fail response msg */ |
||||
|
console.log(err); |
||||
|
}); |
||||
|
}, |
||||
|
setSelected: function(res){ |
||||
|
this.searchQuery = res.nazev |
||||
|
this.selected_id = res.id |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.upravit { |
||||
|
margin-top:-40px; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,23 @@ |
|||||
|
<template> |
||||
|
<div class="ulohazadaninode"> |
||||
|
<!--pre>UlohaZadaniNode {{item.node.uloha}} {{typeof(item)}}</pre--> |
||||
|
<h5>Zadání {{item.node.uloha.cislo_zadani.poradi}}.{{ item.node.uloha.kod }}: {{ item.node.uloha.nazev }}</h5> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'UlohaZadaniNode', |
||||
|
props: { |
||||
|
item: Object, |
||||
|
created: Boolean |
||||
|
, |
||||
|
mounted: function(){ |
||||
|
if (this.item.node.uloha === null){ |
||||
|
console.log("Uloha je null!"); |
||||
|
console.log(this.item); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,12 @@ |
|||||
|
import Vue from 'vue' |
||||
|
import App from './App.vue' |
||||
|
import router from './router' |
||||
|
import CKEditor from '@ckeditor/ckeditor5-vue' |
||||
|
|
||||
|
Vue.config.productionTip = false |
||||
|
Vue.use(CKEditor); |
||||
|
|
||||
|
new Vue({ |
||||
|
router, |
||||
|
render: h => h(App), |
||||
|
}).$mount('#app') |
@ -0,0 +1,28 @@ |
|||||
|
import Vue from 'vue' |
||||
|
import Router from 'vue-router' |
||||
|
import TreeNodeRoot from '../components/TreeNodeRoot.vue' |
||||
|
|
||||
|
Vue.use(Router) |
||||
|
|
||||
|
export default new Router({ |
||||
|
mode: 'history', |
||||
|
linkActiveClass: 'active', |
||||
|
routes: [{ |
||||
|
path: '/temp/vue', |
||||
|
name: 'treenodedefault', |
||||
|
props: {'tnid': 23}, |
||||
|
component: TreeNodeRoot |
||||
|
}, { |
||||
|
path: '/temp/vue/:tnid', |
||||
|
name: 'treenode', |
||||
|
props: true, |
||||
|
component: TreeNodeRoot |
||||
|
}, { |
||||
|
path: '/zadani/aktualni', |
||||
|
name: 'treenode_zadani', |
||||
|
props: {'tnid': 23}, |
||||
|
component: TreeNodeRoot |
||||
|
}, |
||||
|
] |
||||
|
}) |
||||
|
|
@ -0,0 +1,61 @@ |
|||||
|
const BundleTracker = require("webpack-bundle-tracker"); |
||||
|
|
||||
|
const pages = { |
||||
|
'vue_app_01': { |
||||
|
entry: './src/main.js', |
||||
|
chunks: ['chunk-vendors'] |
||||
|
}, |
||||
|
/* 'vue_app_02': { |
||||
|
entry: './src/newhampshir.js', |
||||
|
chunks: ['chunk-vendors'] |
||||
|
}, |
||||
|
*/ |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
pages: pages, |
||||
|
filenameHashing: false, |
||||
|
productionSourceMap: false, |
||||
|
publicPath: process.env.NODE_ENV === 'production' |
||||
|
? '/static/seminar/vue/' |
||||
|
: 'http://localhost:8080/', |
||||
|
outputDir: '../seminar/static/seminar/vue/', |
||||
|
|
||||
|
chainWebpack: config => { |
||||
|
|
||||
|
config.optimization |
||||
|
.splitChunks({ |
||||
|
cacheGroups: { |
||||
|
vendor: { |
||||
|
test: /[\\/]node_modules[\\/]/, |
||||
|
name: "chunk-vendors", |
||||
|
chunks: "all", |
||||
|
priority: 1 |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
Object.keys(pages).forEach(page => { |
||||
|
config.plugins.delete(`html-${page}`); |
||||
|
config.plugins.delete(`preload-${page}`); |
||||
|
config.plugins.delete(`prefetch-${page}`); |
||||
|
}) |
||||
|
|
||||
|
config |
||||
|
.plugin('BundleTracker') |
||||
|
.use(BundleTracker, [{filename: '../vue_frontend/webpack-stats.json'}]); |
||||
|
|
||||
|
config.resolve.alias |
||||
|
.set('__STATIC__', 'static') |
||||
|
|
||||
|
config.devServer |
||||
|
.public('http://localhost:8080') |
||||
|
.host('localhost') |
||||
|
.port(8080) |
||||
|
.hotOnly(true) |
||||
|
.watchOptions({poll: 1000}) |
||||
|
.https(false) |
||||
|
.headers({"Access-Control-Allow-Origin": ["*"]}) |
||||
|
|
||||
|
} |
||||
|
}; |
File diff suppressed because it is too large
Loading…
Reference in new issue