Browse Source

Impl. of features for editing notes and quotes.

pull/10/head
LeandroRoberto 9 years ago
parent
commit
ae19c6a170
  1. 142
      compilacao/forms.py
  2. 21
      compilacao/models.py
  3. 11
      compilacao/templatetags/compilacao_filters.py
  4. 16
      compilacao/urls.py
  5. 282
      compilacao/views.py
  6. 4
      norma/urls.py
  7. 3
      sapl/settings.py
  8. 4
      static/js/compilacao.js
  9. 135
      static/js/compilacao_notas.js
  10. 236
      static/styles/compilacao.scss
  11. 3
      templates/compilacao/ajax_form.html
  12. 43
      templates/compilacao/dispositivo_search_fragment_form.html
  13. 2
      templates/compilacao/edit_bloco.html
  14. 101
      templates/compilacao/index_bloco.html
  15. 4
      templates/compilacao/index_bloco_alteracao.html
  16. 3
      templates/compilacao/nota_ajaxform.html

142
compilacao/forms.py

@ -1,13 +1,12 @@
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Fieldset, ButtonHolder, Submit, Field,\ from crispy_forms.layout import HTML, Button, Column, Div, Field, Layout, Row
Div, Column, Row, Hidden, Button
from django import forms from django import forms
from django.core.urlresolvers import reverse
from django.forms.models import ModelForm from django.forms.models import ModelForm
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from compilacao.models import Nota, TipoNota, Dispositivo from compilacao.models import Dispositivo, Nota, TipoNota, TipoVide, Vide
import sapl from norma.models import TipoNormaJuridica
from sapl.layout import to_column, to_row
class UpLoadImportFileForm(forms.Form): class UpLoadImportFileForm(forms.Form):
@ -15,31 +14,25 @@ class UpLoadImportFileForm(forms.Form):
required=True, required=True,
label=_('Arquivo formato ODF para Importanção')) label=_('Arquivo formato ODF para Importanção'))
error_messages = {
def get_tipos_nota(): 'required': _('Este campo é obrigatório'),
return [(t.id, t.sigla + ' - ' + t.nome) for t in TipoNota.objects.all()] 'invalid': _('URL inválida.')
}
class NotaForm(ModelForm): class NotaForm(ModelForm):
NPRIV = 1 NPRIV = 1
NSTRL = 2 NINST = 2
NINST = 3 NPUBL = 3
NPUBL = 4
PUBLICIDADE_CHOICES = ( PUBLICIDADE_CHOICES = (
# Only the owner of the note has visibility. # Only the owner of the note has visibility.
(NPRIV, _('Nota Privada')), (NPRIV, _('Nota Privada')),
# All of the same group have visibility.
(NSTRL, _('Nota Setorial')),
# All authenticated users have visibility. # All authenticated users have visibility.
(NINST, _('Nota Institucional')), (NINST, _('Nota Institucional')),
# All users have visibility. # All users have visibility.
(NPUBL, _('Nota Pública')), (NPUBL, _('Nota Pública')),
) )
error_messages = {
'required': _('Este campo é obrigatório'),
'invalid': _('URL inválida.')
}
titulo = forms.CharField(label=' ', required=False) titulo = forms.CharField(label=' ', required=False)
texto = forms.CharField( texto = forms.CharField(
label='', label='',
@ -51,18 +44,18 @@ class NotaForm(ModelForm):
error_messages=error_messages) error_messages=error_messages)
publicidade = forms.ChoiceField( publicidade = forms.ChoiceField(
required=True, required=True,
label='Publicidade', label=_('Publicidade'),
choices=PUBLICIDADE_CHOICES, choices=PUBLICIDADE_CHOICES,
widget=forms.Select(attrs={'class': 'selector'})) widget=forms.Select(attrs={'class': 'selector'}))
tipo = forms.ModelChoiceField( tipo = forms.ModelChoiceField(
required=False, required=False,
label='Tipo da Nota', label=_('Tipo da Nota'),
queryset=TipoNota.objects.all(), queryset=TipoNota.objects.all(),
empty_label=None) empty_label=None)
publicacao = forms.DateField( publicacao = forms.DateField(
label=u'Publicação', label=_('Publicação'),
input_formats=['%d/%m/%Y'], input_formats=['%d/%m/%Y'],
required=True, required=True,
widget=forms.DateInput( widget=forms.DateInput(
@ -70,7 +63,7 @@ class NotaForm(ModelForm):
error_messages=error_messages error_messages=error_messages
) )
efetividade = forms.DateField( efetividade = forms.DateField(
label=u'Efetividade', label=_('Efetividade'),
input_formats=['%d/%m/%Y'], input_formats=['%d/%m/%Y'],
required=True, required=True,
widget=forms.DateInput( widget=forms.DateInput(
@ -96,7 +89,7 @@ class NotaForm(ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
row1 = sapl.layout.to_row([ row1 = to_row([
('tipo', 4), ('tipo', 4),
]) ])
row1.append( row1.append(
@ -107,31 +100,112 @@ class NotaForm(ModelForm):
), ),
css_class='columns large-8')) css_class='columns large-8'))
row3 = sapl.layout.to_row([ row3 = to_row([
('publicidade', 3), ('publicidade', 3),
('publicacao', 3), ('publicacao', 3),
('efetividade', 3), ('efetividade', 3),
(Button('submit', 'Salvar', (Button('submit', 'Salvar',
css_class='button primary'), 3) css_class='button primary radius'), 3)
]) ])
self.helper = FormHelper() self.helper = FormHelper()
self.helper.layout = Layout( self.helper.layout = Layout(
Div(HTML(_('Notas')), css_class='title_form'),
row1, row1,
Field('texto', placeholder=_('Adicionar Nota')), Field('texto', placeholder=_('Adicionar Nota')),
Field('url_externa', placeholder=_('URL Externa (opcional)')), Field('url_externa', placeholder=_('URL Externa (opcional)')),
row3 row3
) )
kwargs.pop('norma_id')
dispositivo_id = kwargs.pop('dispositivo_id')
if 'pk' in kwargs:
pk = kwargs.pop('pk')
else:
pk = ''
super(NotaForm, self).__init__(*args, **kwargs) super(NotaForm, self).__init__(*args, **kwargs)
self.fields['dispositivo'].initial = dispositivo_id
if pk: class VideForm(ModelForm):
self.fields['pk'].initial = pk dispositivo_base = forms.ModelChoiceField(
queryset=Dispositivo.objects.all(),
widget=forms.HiddenInput())
dispositivo_ref = forms.ModelChoiceField(
queryset=Dispositivo.objects.all(),
widget=forms.HiddenInput())
tipo_norma = forms.ModelChoiceField(
queryset=TipoNormaJuridica.objects.all(),
required=False)
num_norma = forms.IntegerField(label=_('Núm. da Norma'), required=False)
ano_norma = forms.IntegerField(label=_('Ano da Norma'), required=False)
texto = forms.CharField(
label='',
widget=forms.Textarea,
error_messages=error_messages,
required=False)
tipo = forms.ModelChoiceField(
label=_('Tipo do Vide'),
queryset=TipoVide.objects.all(),
required=True)
busca_dispositivo = forms.CharField(
label=_('Buscar Dispositivo a Referenciar'),
required=False)
pk = forms.IntegerField(widget=forms.HiddenInput(),
required=False)
class Meta:
model = Vide
fields = ['dispositivo_base',
'dispositivo_ref',
'texto',
'tipo',
'pk']
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.layout = Layout(
Div(HTML(_('Vides')), css_class='title_form'),
Row(
to_column((
Div(
Div(to_column((Field(
'tipo',
placeholder=_('Selecione um Tipo de Vide')), 12))),
Div(to_column((
Field(
'texto',
placeholder=_(
'Texto Adicional ao Vide')), 12))),
Div(to_column((
Button(
'submit',
'Salvar',
css_class='button primary radius'), 12)))
), 4)),
to_column((
Div(
Div(to_column(('tipo_norma', 6))),
Div(to_column(('num_norma', 3)),
to_column(('ano_norma', 3))),
Div(to_column(
(Field(
'busca_dispositivo',
placeholder=_('Digite palavras, letras, '
'números ou algo'
' que estejam '
'no rótulo ou no texto.')), 10)),
to_column((
Button(
'buscar',
'Buscar',
css_class='button btn-busca radius'), 2))
),
to_column(
(Div(css_class='container-busca'), 12))
), 8)
)
)
)
super(VideForm, self).__init__(*args, **kwargs)

21
compilacao/models.py

@ -950,9 +950,16 @@ class Dispositivo(BaseModel, TimestampedMixin):
return proxima_articulacao[0] return proxima_articulacao[0]
def is_relative_auto_insert(self, perfil_pk): def is_relative_auto_insert(self, perfil_pk=None):
if self.dispositivo_pai is not None: if self.dispositivo_pai is not None:
# pp possiveis_pais # pp possiveis_pais
if not perfil_pk:
perfis = PerfilEstruturalTextosNormativos.objects.filter(
padrao=True)[:1]
if perfis.exists():
perfil_pk = perfis[0].pk
pp = self.tipo_dispositivo.possiveis_pais.filter( pp = self.tipo_dispositivo.possiveis_pais.filter(
pai=self.dispositivo_pai.tipo_dispositivo, pai=self.dispositivo_pai.tipo_dispositivo,
perfil_id=perfil_pk) perfil_id=perfil_pk)
@ -1032,15 +1039,16 @@ class Vide(TimestampedMixin):
dispositivo_base = models.ForeignKey( dispositivo_base = models.ForeignKey(
Dispositivo, Dispositivo,
verbose_name=_('Dispositivo Base'), verbose_name=_('Dispositivo Base'),
related_name='%(class)s_dispositivo_base') related_name='cita')
dispositivo_ref = models.ForeignKey( dispositivo_ref = models.ForeignKey(
Dispositivo, Dispositivo,
related_name='%(class)s_dispositivo_ref', related_name='citado',
verbose_name=_('Dispositivo Referido')) verbose_name=_('Dispositivo Referido'))
class Meta: class Meta:
verbose_name = _('Vide') verbose_name = _('Vide')
verbose_name_plural = _('Vides') verbose_name_plural = _('Vides')
unique_together = ['dispositivo_base', 'dispositivo_ref']
def __str__(self): def __str__(self):
return _('Vide %s') % self.texto return _('Vide %s') % self.texto
@ -1048,15 +1056,12 @@ class Vide(TimestampedMixin):
class Nota(TimestampedMixin): class Nota(TimestampedMixin):
NPRIV = 1 NPRIV = 1
NSTRL = 2 NINST = 2
NINST = 3 NPUBL = 3
NPUBL = 4
PUBLICIDADE_CHOICES = ( PUBLICIDADE_CHOICES = (
# Only the owner of the note has visibility. # Only the owner of the note has visibility.
(NPRIV, _('Nota Privada')), (NPRIV, _('Nota Privada')),
# All of the same group have visibility.
(NSTRL, _('Nota Setorial')),
# All authenticated users have visibility. # All authenticated users have visibility.
(NINST, _('Nota Institucional')), (NINST, _('Nota Institucional')),
# All users have visibility. # All users have visibility.

11
compilacao/templatetags/compilacao_filters.py

@ -128,9 +128,17 @@ def nomenclatura(d):
@register.simple_tag @register.simple_tag
def nomenclatura_heranca(d): def nomenclatura_heranca(d, ignore_ultimo=0, ignore_primeiro=0):
result = '' result = ''
while d is not None: while d is not None:
if ignore_ultimo and d.dispositivo_pai is None:
break
if ignore_primeiro:
ignore_primeiro = 0
d = d.dispositivo_pai
continue
if d.rotulo != '': if d.rotulo != '':
if d.tipo_dispositivo.rotulo_prefixo_texto != '': if d.tipo_dispositivo.rotulo_prefixo_texto != '':
result = d.rotulo + ' ' + result result = d.rotulo + ' ' + result
@ -141,4 +149,5 @@ def nomenclatura_heranca(d):
result = '(' + d.tipo_dispositivo.nome + \ result = '(' + d.tipo_dispositivo.nome + \
d.rotulo_padrao() + ')' + ' ' + result d.rotulo_padrao() + ')' + ' ' + result
d = d.dispositivo_pai d = d.dispositivo_pai
return result return result

16
compilacao/urls.py

@ -34,6 +34,22 @@ urlpatterns_compilacao = [
'(?P<dispositivo_id>[0-9]+)/nota/(?P<pk>[0-9]+)/delete$', '(?P<dispositivo_id>[0-9]+)/nota/(?P<pk>[0-9]+)/delete$',
views.NotasDeleteView.as_view(), name='nota_delete'), views.NotasDeleteView.as_view(), name='nota_delete'),
url(r'^(?P<norma_id>[0-9]+)/compilacao/'
'(?P<dispositivo_id>[0-9]+)/vide/create$',
views.VideCreateView.as_view(), name='vide_create'),
url(r'^(?P<norma_id>[0-9]+)/compilacao/'
'(?P<dispositivo_id>[0-9]+)/vide/(?P<pk>[0-9]+)/edit$',
views.VideEditView.as_view(), name='vide_edit'),
url(r'^(?P<norma_id>[0-9]+)/compilacao/'
'(?P<dispositivo_id>[0-9]+)/vide/(?P<pk>[0-9]+)/delete$',
views.VideDeleteView.as_view(), name='vide_delete'),
url(r'^(?P<norma_id>[0-9]+)/compilacao/search$',
views.DispositivoSearchFragmentFormView.as_view(),
name='search_dispositivo'),
] ]
urlpatterns = [ urlpatterns = [

282
compilacao/views.py

@ -2,31 +2,30 @@ from collections import OrderedDict
from datetime import datetime, timedelta from datetime import datetime, timedelta
from os.path import sys from os.path import sys
from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required
from django.core.signing import Signer from django.core.signing import Signer
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db.models import Q from django.db.models import Q
from django.http.response import JsonResponse, HttpResponse,\ from django.http.response import (HttpResponse, HttpResponseRedirect,
HttpResponseRedirect JsonResponse)
from django.shortcuts import render from django.shortcuts import get_object_or_404, render
from django.utils.dateparse import parse_date from django.utils.dateparse import parse_date
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import FormMixin, UpdateView
from django.views.generic.edit import FormMixin, UpdateView, DeleteView
from django.views.generic.list import ListView from django.views.generic.list import ListView
from vanilla.model_views import CreateView from vanilla.model_views import CreateView
from compilacao import forms from compilacao import forms
from compilacao.file2dispositivo import Parser from compilacao.file2dispositivo import Parser
from compilacao.forms import NotaForm from compilacao.models import (Dispositivo, Nota,
from compilacao.models import (Dispositivo, PerfilEstruturalTextosNormativos, PerfilEstruturalTextosNormativos,
TipoDispositivo, TipoNota, TipoPublicacao, TipoDispositivo, TipoNota, TipoPublicacao,
TipoVide, VeiculoPublicacao, Nota) TipoVide, VeiculoPublicacao, Vide)
from norma.models import NormaJuridica from norma.models import NormaJuridica
from sapl.crud import build_crud from sapl.crud import build_crud
DISPOSITIVO_SELECT_RELATED = ( DISPOSITIVO_SELECT_RELATED = (
'tipo_dispositivo', 'tipo_dispositivo',
'norma_publicada', 'norma_publicada',
@ -131,6 +130,22 @@ class CompilacaoView(ListView):
inicio_vigencia = None inicio_vigencia = None
fim_vigencia = None fim_vigencia = None
def get_context_data(self, **kwargs):
context = super(CompilacaoView, self).get_context_data(**kwargs)
vides = Vide.objects.filter(
Q(dispositivo_base__norma_id=self.kwargs['norma_id']) |
Q(dispositivo_ref__norma_id=self.kwargs['norma_id']))
context['cita'] = [v.dispositivo_base_id for v in vides]
context['citado'] = [v.dispositivo_ref_id for v in vides]
notas = Nota.objects.filter(
dispositivo__norma_id=self.kwargs['norma_id'])
context['notas'] = [n.dispositivo_id for n in notas]
return context
def get_queryset(self): def get_queryset(self):
self.flag_alteradora = -1 self.flag_alteradora = -1
self.flag_nivel_ini = 0 self.flag_nivel_ini = 0
@ -153,11 +168,22 @@ class CompilacaoView(ListView):
norma_id=self.kwargs['norma_id'], norma_id=self.kwargs['norma_id'],
).select_related(*DISPOSITIVO_SELECT_RELATED) ).select_related(*DISPOSITIVO_SELECT_RELATED)
else: else:
return Dispositivo.objects.filter(
r = Dispositivo.objects.filter(
ordem__gt=0, ordem__gt=0,
norma_id=self.kwargs['norma_id'] norma_id=self.kwargs['norma_id'],
).select_related(*DISPOSITIVO_SELECT_RELATED).prefetch_related( ).select_related(
'notas',) 'tipo_dispositivo',
'norma_publicada',
'norma',
'dispositivo_atualizador',
'dispositivo_atualizador__dispositivo_pai',
'dispositivo_atualizador__dispositivo_pai__norma',
'dispositivo_atualizador__dispositivo_pai__norma__tipo',
'dispositivo_pai',
'dispositivo_pai__tipo_dispositivo')
return r
def get_vigencias(self): def get_vigencias(self):
itens = Dispositivo.objects.filter( itens = Dispositivo.objects.filter(
@ -1087,31 +1113,65 @@ class ActionsEditView(ActionsEditMixin, TemplateView):
return self.render_to_json_response(context, **response_kwargs) return self.render_to_json_response(context, **response_kwargs)
class NotasCreateView(FormMixin, CreateView): class DispositivoSuccessUrlMixin(object):
template_name = 'compilacao/nota_ajaxform.html'
form_class = forms.NotaForm def get_success_url(self):
return reverse(
'dispositivo', kwargs={
'norma_id': self.kwargs[
'norma_id'],
'dispositivo_id': self.kwargs[
'dispositivo_id']})
def get(self, request, *args, **kwargs):
class NotaMixin(DispositivoSuccessUrlMixin):
def get_modelo_nota(self, request):
# TODO: permitir edição apenas das notas do usuário conectado
# TODO: tratar revalidação no método post
# TODO: não mostrar botão de edição na interface
if 'action' in request.GET and request.GET['action'] == 'modelo_nota': if 'action' in request.GET and request.GET['action'] == 'modelo_nota':
tn = TipoNota.objects.get(pk=request.GET['id_tipo']) tn = TipoNota.objects.get(pk=request.GET['id_tipo'])
return HttpResponse(tn.modelo) return True, tn.modelo
return False, ''
return super(NotasCreateView, self).get(request, *args, **kwargs) def get_initial(self):
dispositivo = get_object_or_404(
Dispositivo, pk=self.kwargs.get('dispositivo_id'))
initial = {'dispositivo': dispositivo}
if 'pk' in self.kwargs:
initial['pk'] = self.kwargs.get('pk')
return initial
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(NotaMixin, self).dispatch(*args, **kwargs)
class NotasCreateView(NotaMixin, FormMixin, CreateView):
template_name = 'compilacao/ajax_form.html'
form_class = forms.NotaForm
def get(self, request, *args, **kwargs):
flag_action, modelo_nota = self.get_modelo_nota(request)
if flag_action:
return HttpResponse(modelo_nota)
def get_form_kwargs(self): return super(NotasCreateView, self).get(request, *args, **kwargs)
kwargs = super(NotasCreateView, self).get_form_kwargs()
kwargs.update(self.kwargs)
return kwargs
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
try: try:
form = NotaForm(request.POST, request.FILES, **kwargs) norma_id = kwargs.pop('norma_id')
dispositivo_id = kwargs.pop('dispositivo_id')
form = forms.NotaForm(request.POST, request.FILES, **kwargs)
kwargs['norma_id'] = norma_id
kwargs['dispositivo_id'] = dispositivo_id
if form.is_valid(): if form.is_valid():
nt = form.save(commit=False) nt = form.save(commit=False)
# TODO: Implementar tratamento do usuário. nt.owner_id = request.user.pk
nt.owner_id = User.objects.order_by('id')[:1][0].pk
nt.save() nt.save()
self.kwargs['pk'] = nt.pk self.kwargs['pk'] = nt.pk
return self.form_valid(form) return self.form_valid(form)
@ -1121,59 +1181,147 @@ class NotasCreateView(FormMixin, CreateView):
print(e) print(e)
return HttpResponse("post") return HttpResponse("post")
def get_success_url(self):
return reverse(
'dispositivo', kwargs={
'norma_id': self.kwargs[
'norma_id'],
'dispositivo_id': self.kwargs[
'dispositivo_id']})
class NotasEditView(UpdateView): class NotasEditView(NotaMixin, UpdateView):
model = Nota model = Nota
template_name = 'compilacao/nota_ajaxform.html' template_name = 'compilacao/ajax_form.html'
form_class = forms.NotaForm form_class = forms.NotaForm
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try: flag_action, modelo_nota = self.get_modelo_nota(request)
# TODO: permitir edição apenas das notas do usuário conectado if flag_action:
# TODO: tratar revalidação no método post return HttpResponse(modelo_nota)
# TODO: não mostrar botão de edição na interface
if 'action' in request.GET and request.GET['action'] == 'modelo_nota':
tn = TipoNota.objects.get(pk=request.GET['id_tipo'])
return HttpResponse(tn.modelo)
return super(NotasEditView, self).get(request, *args, **kwargs) return super(NotasEditView, self).get(request, *args, **kwargs)
class NotasDeleteView(NotaMixin, TemplateView):
def get(self, request, *args, **kwargs):
nt = Nota.objects.get(pk=self.kwargs['pk'])
nt.delete()
return HttpResponseRedirect(self.get_success_url())
class VideMixin(DispositivoSuccessUrlMixin):
def get_initial(self):
dispositivo_base = get_object_or_404(
Dispositivo, pk=self.kwargs.get('dispositivo_id'))
initial = {'dispositivo_base': dispositivo_base}
if 'pk' in self.kwargs:
initial['pk'] = self.kwargs.get('pk')
return initial
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(VideMixin, self).dispatch(*args, **kwargs)
class VideCreateView(VideMixin, FormMixin, CreateView):
template_name = 'compilacao/ajax_form.html'
form_class = forms.VideForm
def post(self, request, *args, **kwargs):
try:
norma_id = kwargs.pop('norma_id')
dispositivo_id = kwargs.pop('dispositivo_id')
form = forms.VideForm(request.POST, request.FILES, **kwargs)
kwargs['norma_id'] = norma_id
kwargs['dispositivo_id'] = dispositivo_id
if form.is_valid():
vd = form.save(commit=False)
vd.save()
self.kwargs['pk'] = vd.pk
return self.form_valid(form)
else:
return self.form_invalid(form)
except Exception as e: except Exception as e:
print(e) print(e)
return HttpResponse("post")
def get_form_kwargs(self):
kwargs = super(NotasEditView, self).get_form_kwargs()
kwargs.update(self.kwargs)
return kwargs
def get_success_url(self): class VideEditView(VideMixin, UpdateView):
return reverse( model = Vide
'dispositivo', kwargs={ template_name = 'compilacao/ajax_form.html'
'norma_id': self.kwargs[ form_class = forms.VideForm
'norma_id'],
'dispositivo_id': self.kwargs[
'dispositivo_id']})
class NotasDeleteView(TemplateView): class VideDeleteView(VideMixin, TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
nt = Nota.objects.get(pk=self.kwargs['pk']) vd = Vide.objects.get(pk=self.kwargs['pk'])
success_url = self.get_success_url() vd.delete()
nt.delete() return HttpResponseRedirect(self.get_success_url())
return HttpResponseRedirect(success_url)
def get_success_url(self):
return reverse( class DispositivoSearchFragmentFormView(ListView):
'dispositivo', kwargs={ template_name = 'compilacao/dispositivo_search_fragment_form.html'
'norma_id': self.kwargs[
'norma_id'], @method_decorator(login_required)
'dispositivo_id': self.kwargs[ def dispatch(self, *args, **kwargs):
'dispositivo_id']}) return super(
DispositivoSearchFragmentFormView,
self).dispatch(*args, **kwargs)
def get_queryset(self):
try:
busca = ''
if 'busca' in self.request.GET:
busca = self.request.GET['busca']
q = Q(nivel__gt=0)
busca = busca.split(' ')
n = 10
for item in busca:
if not item:
continue
if q:
q = q & (Q(dispositivo_pai__rotulo__icontains=item) |
Q(rotulo__icontains=item) |
Q(texto__icontains=item) |
Q(texto_atualizador__icontains=item))
n = 50
else:
q = (Q(dispositivo_pai__rotulo__icontains=item) |
Q(rotulo__icontains=item) |
Q(texto__icontains=item) |
Q(texto_atualizador__icontains=item))
n = 50
if 'tipo_norma' in self.request.GET:
tipo_norma = self.request.GET['tipo_norma']
if tipo_norma:
q = q & Q(norma__tipo_id=tipo_norma)
n = 50
if 'num_norma' in self.request.GET:
num_norma = self.request.GET['num_norma']
if num_norma:
q = q & Q(norma__numero=num_norma)
n = 50
if 'ano_norma' in self.request.GET:
ano_norma = self.request.GET['ano_norma']
if ano_norma:
q = q & Q(norma__ano=ano_norma)
n = 50
if 'initial_ref' in self.request.GET:
initial_ref = self.request.GET['initial_ref']
if initial_ref:
q = q & Q(pk=initial_ref)
n = 50
return Dispositivo.objects.filter(q)[:n]
except Exception as e:
print(e)

4
norma/urls.py

@ -1,7 +1,7 @@
from django.conf.urls import include, url from django.conf.urls import include, url
from norma.views import NormaIncluirView, assunto_norma_crud, tipo_norma_crud,\ from norma.views import (NormaIncluirView, assunto_norma_crud,
norma_temporario_crud norma_temporario_crud, tipo_norma_crud)
norma_url_patterns = norma_temporario_crud.urlpatterns + [] norma_url_patterns = norma_temporario_crud.urlpatterns + []
# norma_url_patterns = norma_crud.urlpatterns + [] # norma_url_patterns = norma_crud.urlpatterns + []

3
sapl/settings.py

@ -60,8 +60,7 @@ INSTALLED_APPS = (
'sass_processor', 'sass_processor',
) )
if DEBUG: if DEBUG:
# INSTALLED_APPS += ('debug_toolbar',) INSTALLED_APPS += ('debug_toolbar',)
pass
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',

4
static/js/compilacao.js

@ -33,3 +33,7 @@ function ReadCookie(cookieName) {
if (ind1==-1) ind1=theCookie.length; if (ind1==-1) ind1=theCookie.length;
return unescape(theCookie.substring(ind+cookieName.length+2,ind1)); return unescape(theCookie.substring(ind+cookieName.length+2,ind1));
} }
function insertWaitAjax(element) {
jQuery(element).append('<div style="text-align:center;"><img src="/static/img/ajax-loader.gif"></div>');
}

135
static/js/compilacao_notas.js

@ -13,6 +13,12 @@ function onEventsDneExec(pk) {
todayBtn: true todayBtn: true
}); });
$('#dne'+pk+" .primary").click(onSubmitEditForm);
$('#dne'+pk+" .btn-close-container").click(function(){
$(this).closest('.dne-nota').removeClass('dne-nota');
$(this).closest('.dne-form').html('');
});
$('#dne'+pk+" select[name='tipo']").change(function(event) { $('#dne'+pk+" select[name='tipo']").change(function(event) {
var url = ''; var url = '';
url = 'compilacao/'+pk+'/nota/create?action=modelo_nota&id_tipo='+this.value; url = 'compilacao/'+pk+'/nota/create?action=modelo_nota&id_tipo='+this.value;
@ -21,19 +27,71 @@ function onEventsDneExec(pk) {
}); });
}); });
$('#dne'+pk+" .button").click(onSubmitEditForm); $('#dne'+pk+" select[name='tipo_norma']"
).change(onChangeParamNorma);
$('#dne'+pk+" input[name='num_norma'], "
+ '#dne'+pk+" input[name='ano_norma'], "
+ '#dne'+pk+" input[name='busca_dispositivo']"
).change(onChangeParamNorma);
$('#dne'+pk+" .btn-busca").click(onChangeParamNorma);
onChangeParamNorma();
}
var onChangeParamNorma = function(event) {
var tipo_norma = $("select[name='tipo_norma']").val();
var num_norma = $("input[name='num_norma']").val();
var ano_norma = $("input[name='ano_norma']").val();
var busca_dispositivo = $("input[name='busca_dispositivo']").val();
var dispositivo_ref = $("#id_dispositivo_ref").val();
$('#id_dispositivo_ref').remove();
if (dispositivo_ref == null)
dispositivo_ref = ''
var url = '';
var pk = $("select[name='tipo_norma']").closest('.dne').attr('pk')
var formData = {
'tipo_norma' : tipo_norma,
'num_norma' : num_norma,
'ano_norma' : ano_norma,
'busca' : busca_dispositivo,
'tipo_form' : 'radio',
'initial_ref' : dispositivo_ref
};
url = 'compilacao/search';
$('.container-busca').html('');
insertWaitAjax('.container-busca')
$.get(url, formData).done(function( data ) {
$('.container-busca').html(data);
$("input[name='dispositivo_ref']").first().prop('checked', true);
});
} }
var onSubmitEditForm = function(event) { var onSubmitEditForm = function(event) {
var url = '';
var model = 'nota';
var id_edit = null;
var id_dispositivo = $('#id_dispositivo').val(); var id_dispositivo = $('#id_dispositivo').val();
var id_nota = $('#id_pk').val();
var url = 'compilacao/'+id_dispositivo+'/nota/'
if (id_nota == '') if (id_dispositivo == null) { // trata-se de um vide
$('#id_dispositivo_ref').remove();
id_dispositivo = $('#id_dispositivo_base').val();
model='vide';
}
id_edit = $('#id_pk').val();
url = 'compilacao/'+id_dispositivo+'/'+model+'/'
if (id_edit == null || id_edit == '')
url += 'create'; url += 'create';
else else
url += id_nota+'/edit'; url += id_edit+'/edit';
console.log($('#dne'+id_dispositivo+" form").serialize());
$.post( url, $('#dne'+id_dispositivo+" form").serialize(), function(data) { $.post( url, $('#dne'+id_dispositivo+" form").serialize(), function(data) {
@ -44,7 +102,12 @@ var onSubmitEditForm = function(event) {
} }
else { else {
$('#dne'+id_dispositivo+' .dne-form').closest('.dpt').html(data) $('#dne'+id_dispositivo+' .dne-form').closest('.dpt').html(data)
onReadyNotas(); onReadyNotasVides();
$('html, body').animate({
scrollTop: $('#dne' + id_dispositivo ).offset().top - window.innerHeight / 3
}, 300);
} }
} }
} }
@ -52,55 +115,65 @@ var onSubmitEditForm = function(event) {
} }
var onDelete = function(event) { var onDelete = function(event) {
var model = $(event).attr('model');
var id_dispositivo = $(event).closest('.dn').attr('pk'); var id_dispositivo = $(event).closest('.dn').attr('pk');
var id_nota = $(event).attr('pk'); var id_delete = $(event).attr('pk');
var url = 'compilacao/'+id_dispositivo+'/nota/'+id_nota+'/delete' var url = 'compilacao/'+id_dispositivo+'/'+model+'/'+id_delete+'/delete';
$.get( url, function(data) { $.get( url, function(data) {
$('#dne'+id_dispositivo+' .dne-form').closest('.dpt').html(data) $('#dne'+id_dispositivo+' .dne-form').closest('.dpt').html(data)
onReadyNotas(); onReadyNotasVides();
} }
); );
} }
function getFormNota(_this, _btn) {
var id_dispositivo = $('.dne-exec .dne-form').closest('.dne').attr('pk'); function getForm(_this) {
var url = '';
var model = $(_this).attr('model');
var id_dispositivo = $('.dne-nota .dne-form').closest('.dne').attr('pk');
if (id_dispositivo != null) { if (id_dispositivo != null) {
$('#dne'+id_dispositivo).removeClass('dne-exec'); $('#dne'+id_dispositivo).removeClass('dne-nota');
$('#dne'+id_dispositivo+' .dne-form').html(''); $('#dne'+id_dispositivo+' .dne-form').html('');
} }
var url = ''; if (_this.className.indexOf('create') >= 0 ) {
if (_btn == 'btn-create') {
id_dispositivo = $(_this).attr('pk'); id_dispositivo = $(_this).attr('pk');
url = 'compilacao/'+id_dispositivo+'/nota/create'; url = 'compilacao/'+id_dispositivo+'/'+model+'/create';
} }
else if (_btn == 'btn-edit') { else if (_this.className.indexOf('edit') >= 0 ) {
var id_nota = $(_this).attr('pk'); var id_edit = $(_this).attr('pk');
id_dispositivo = $(_this).closest('.dn').attr('pk'); id_dispositivo = $(_this).closest('.dn').attr('pk');
url = 'compilacao/'+id_dispositivo+'/nota/'+id_nota+'/edit' url = 'compilacao/'+id_dispositivo+'/'+model+'/'+id_edit+'/edit'
} }
$('#dne'+id_dispositivo).addClass('dne-exec');
$('#dne'+id_dispositivo).addClass('dne-nota');
$.get(url).done(function( data ) { $.get(url).done(function( data ) {
$('#dne'+id_dispositivo+' .dne-form').html(data); $('#dne'+id_dispositivo+' .dne-form').html(data);
onEventsDneExec(id_dispositivo); onEventsDneExec(id_dispositivo);
}).fail(function() {
onReadyNotasVides();
}); });
} }
function onReadyNotas() {
$('.dne .btn-create').off(); function onReadyNotasVides() {
$('.dne .btn-edit').off();
$('.dne .btn-delete').off(); $('.dne-nota').removeClass('dne-nota');
$('.dne .btn-create').click(function(){ $('.dne-form').html('');
getFormNota(this, 'btn-create')
}); $('.dne .btn-action').off();
$('.dn .btn-edit').click(function(){ $('.dn .btn-action').off();
getFormNota(this, 'btn-edit')
$('.dne .btn-action, .dn .btn-action').not('.btn-nota-delete').not('.btn-vide-delete').click(function(){
getForm(this);
}); });
$('.dn .btn-delete').click(function(){
onDelete(this, 'btn-delete') $('.dn .btn-nota-delete, .dn .btn-vide-delete').click(function(){
onDelete(this);
}); });
} }
$(document).ready(function() { $(document).ready(function() {
onReadyNotas() onReadyNotasVides()
}); });

236
static/styles/compilacao.scss

@ -19,32 +19,34 @@ $color_actions_border: #CCC;
@mixin placeholder($color, $opacity, $fontsize, $fontweight) { @mixin placeholder($color, $opacity, $fontsize, $fontweight) {
&::-webkit-input-placeholder { &::-webkit-input-placeholder {
color: $color; color: $color !important;
opacity: $opacity; opacity: $opacity;
font-size:$fontsize; font-size:$fontsize;
font-weight: $fontweight; font-weight: $fontweight;
} }
&::-moz-placeholder { &::-moz-placeholder {
color: $color; color: $color !important;
opacity: $opacity; opacity: $opacity;
font-size:$fontsize; font-size:$fontsize;
font-weight: $fontweight; font-weight: $fontweight;
} }
&::-moz-placeholder { &::-moz-placeholder {
color: $color; color: $color !important;
opacity: $opacity; opacity: $opacity;
font-size:$fontsize; font-size:$fontsize;
font-weight: $fontweight; font-weight: $fontweight;
} }
&:-ms-input-placeholder { &:-ms-input-placeholder {
color: $color; color: $color !important;
opacity: $opacity; opacity: $opacity;
font-size:$fontsize; font-size:$fontsize;
font-weight: $fontweight; font-weight: $fontweight;
} }
} }
a:link:after, a:visited:after {
content: "";
}
@mixin li_flutuante() { @mixin li_flutuante() {
@ -142,7 +144,7 @@ $color_actions_border: #CCC;
.cp { .cp {
.desativado, .desativado * { .desativado, .desativado * {
text-decoration: line-through; text-decoration: line-through;
color: #777 !important; color: #999 !important;
table, table td { table, table td {
border: 1px dotted #ccc; border: 1px dotted #ccc;
@ -273,7 +275,6 @@ $color_actions_border: #CCC;
font-weight: normal; font-weight: normal;
line-height: 1rem; line-height: 1rem;
position: relative; position: relative;
text-decoration: none;
p, ul { p, ul {
font-size: 0.8rem; font-size: 0.8rem;
font-weight: normal; font-weight: normal;
@ -281,14 +282,30 @@ $color_actions_border: #CCC;
margin: 0 0 0 0; margin: 0 0 0 0;
list-style: none; list-style: none;
} }
.dnl { /* Lista Notas de Dispositivo*/ .dnl { /* Lista Notas de Dispositivo*/
display: block; display: block;
margin-left: 15%; text-align: left !important;
* {
display: inline;
}
.bullet {
padding: 0 0.333em;
padding-bottom: 0.2em;
display: inline-block;
}
.dnli { .dnli {
margin-top: 0.5em; min-height: 2.5em;
border-top: 1px solid #c7e3d3; &:hover {
display: block; ul {
transition: opacity 0.5s linear, clip 0s 0.3s;
clip: auto;
opacity: 1;
background: rgba(230,230,230, 0.9);
}
}
ul { ul {
transition: opacity 0.5s linear, clip 0s 0.3s; transition: opacity 0.5s linear, clip 0s 0.3s;
@ -300,25 +317,9 @@ $color_actions_border: #CCC;
padding: 0.5em 0.5em 0em 0.5em; padding: 0.5em 0.5em 0em 0.5em;
border: 1px solid #c7e3d3; border: 1px solid #c7e3d3;
border-top: 0px; border-top: 0px;
}
&:hover {
min-height: 2.5em;
ul {
transition: opacity 0.5s linear, clip 0s 0.3s;
clip: auto;
opacity: 1;
background: rgba(230,230,230, 0.9);
}
}
li { li {
display: table-cell; display: table-cell;
color: #aaa; color: #aaa;
&.bullet {
padding: 0 0.333em;
padding-bottom: 0.2em;
}
&:hover { &:hover {
color: #787; color: #787;
@ -326,12 +327,17 @@ $color_actions_border: #CCC;
color: #27AE60 !important; color: #27AE60 !important;
} }
} }
.nowner {
color: #27AE60 !important;
}
}
} }
.ntitulo { .ntitulo {
font-weight: bold; font-weight: bold;
color: #676; color: #676;
font-size: 90%; font-size: 90%;
text-decoration: none;
a{ a{
color: #294 !important; color: #294 !important;
} }
@ -342,13 +348,26 @@ $color_actions_border: #CCC;
color: #294 !important; color: #294 !important;
} }
} }
.nowner {
color: #27AE60;
} }
&:hover {
display: block;
* {
display: block;
}
& > .bullet {
display: none;
}
.dnli {
margin-top: 0.5em;
border-top: 1px solid #c7e3d3;
} }
} }
} }
}
.dptt { .dptt {
.dne { .dne {
text-decoration: none; text-decoration: none;
@ -366,7 +385,7 @@ $color_actions_border: #CCC;
font-size: 0.8rem; font-size: 0.8rem;
font-weight: normal; font-weight: normal;
line-height: 1rem; line-height: 1rem;
text-decoration: none; text-decoration: none !important;
} }
ul.btns-action { ul.btns-action {
@ -378,23 +397,32 @@ $color_actions_border: #CCC;
opacity: 0; opacity: 0;
transition: opacity 1.5s linear, clip 1s linear; transition: opacity 1.5s linear, clip 1s linear;
transition-delay: 0s; transition-delay: 0s;
border-collapse:separate;
border-spacing:0.5em;
li { li {
display: table-cell; display: table-cell;
background-color: #ddd;
border-radius: 50%;
a { a {
background-color: #DDD;
border-radius: 50%; border-radius: 50%;
width: 3rem;
height: 3rem;
display: inline-block; display: inline-block;
background: url(/static/img/hand-note.png) no-repeat 50% 50%; font-size: 203%;
padding: 1.2em 1.7em; line-height: 3rem;
text-align: center;
&.btn-nota-create {
background: #ddd url(/static/img/hand-note.png) no-repeat 50% 50%;
}
&.btn-vide-create {
}
&:hover { &:hover {
background-color: rgba(0, 150, 0, 0.1); background-color: #Cdc ;
} }
} }
} }
} }
} }
.dne-exec { .dne-nota {
box-shadow: -4px 15px 15px rgba(0, 0, 0, 0.1), 0px 6px 6px rgba(0, 0, 0, 0.23); box-shadow: -4px 15px 15px rgba(0, 0, 0, 0.1), 0px 6px 6px rgba(0, 0, 0, 0.23);
@include background-top-down(#f5f5f5, #eee); @include background-top-down(#f5f5f5, #eee);
@ -413,10 +441,18 @@ $color_actions_border: #CCC;
&::before { &::before {
color: red; color: red;
content: "\2b25"; content: "\2b25";
padding: 0.333em; padding: 0 0.333em;
vertical-align: super; vertical-align: super;
} }
} }
.title_form {
font-size: 2.5em;
padding: 0.5em 0.3em 0.2em;
background: #e5e5e5;
color: #777;
margin-bottom: 0.4em;
border-bottom: 1px solid #aaa;
}
fieldset { fieldset {
border: 0px; border: 0px;
} }
@ -429,6 +465,9 @@ $color_actions_border: #CCC;
margin-top: 1em; margin-top: 1em;
display: inline-block; display: inline-block;
} }
.columns {
padding: 0 0.5rem;
}
.input { .input {
border: 0px; border: 0px;
border-bottom: 1px solid #ccc; border-bottom: 1px solid #ccc;
@ -440,6 +479,14 @@ $color_actions_border: #CCC;
@include placeholder(#777, 1, 100%, normal); @include placeholder(#777, 1, 100%, normal);
&:focus { &:focus {
background: #fafafa; background: #fafafa;
@include placeholder(#456, 1, 100%, normal);
}
}
.textinput{
@include placeholder(#777, 1, 90%, normal);
&:focus {
background: #fafafa;
@include placeholder(#456, 1, 90%, normal);
} }
} }
.textinput[name='titulo']{ .textinput[name='titulo']{
@ -448,6 +495,10 @@ $color_actions_border: #CCC;
font-weight: bold; font-weight: bold;
border-bottom: 0; border-bottom: 0;
@include placeholder(#777, 1, 100%, bold); @include placeholder(#777, 1, 100%, bold);
&:focus {
background: #fafafa;
@include placeholder(#777, 1, 100%, bold);
}
} }
.textarea { .textarea {
@ -464,14 +515,67 @@ $color_actions_border: #CCC;
.button { .button {
width: 100%; width: 100%;
margin-top: 1.6em; margin-top: 1.6em;
height: 2.3125rem;
padding: 0; padding: 0;
height: 2.835em;
}
.btn-busca {
margin-top: 1.25em;
}
.container-busca {
ul{
list-style: none;
display: table;
margin-left: 0;
border-collapse:separate;
border-spacing:1px;
li {
display: table-row;
&:nth-child(even) {
background-color: rgba(0, 0, 0, 0.05);
}
&:nth-child(odd) {
background-color: rgba(0, 0, 0, 0.08);
}
.iteminput {
display: table-cell;
padding: 0.5em;
vertical-align: middle;
text-align: center;
input {
margin: 0;
}
}
.itemlabel {
display: table-cell;
padding: 0.5em;
vertical-align: middle;
width: 100%;
}
}
}
.norma_title {
padding: 0.15em 0.7em;
background-color: rgba(0, 0, 0, 0.15);
margin: 0.1em 0.08em 0 0.1em;
}
.nomenclatura_heranca {
font-size: 90%;
color: #057dba;
}
} }
} }
} }
&:hover { &:hover {
.dne { .dne {
height: 3.2em; height: 4.3em;
transform: scaleY(1); transform: scaleY(1);
transition-delay: 1s; transition-delay: 1s;
@ -486,7 +590,7 @@ $color_actions_border: #CCC;
} }
} }
} }
.dne-exec { .dne-nota {
transition-delay: 0s; transition-delay: 0s;
height: auto; height: auto;
@ -639,6 +743,9 @@ $color_actions_border: #CCC;
*:hover { *:hover {
color: #27AE60; color: #27AE60;
} }
.de {
cursor: pointer;
}
} }
.articulacao{ .articulacao{
margin-left: -0.8em; margin-left: -0.8em;
@ -1043,8 +1150,54 @@ $color_actions_border: #CCC;
} }
} }
} }
}
.btn-busca {
background-color: #0093dd;
&:hover {
background-color: #007ebe;
}
&:focus {
background-color: #036190;
}
}
.btn-close-container{
position: absolute;
background-color: #AAA;
width: 2em;
height: 2em;
border: 0.3em solid #FFF;
top: -0.9em;
right: -0.9em;
border-radius: 50%;
cursor: pointer;
opacity: 0.7;
transform: rotate(45deg);
.icon-close{
background: #FFF;
height: 1.2em;
position: absolute;
width: 0.2em;
top: 0.15em;
left: 0.66em;
&::after {
background: #FFF;
content: "";
height: 0.2em;
left: -0.5em;
position: absolute;
top: 0.48em;
width: 1.2em;
}
}
&:hover{
opacity: 1;
}
} }
.class_color_container { .class_color_container {
background: #ddd !important; background: #ddd !important;
} }
@ -1149,7 +1302,6 @@ $color_actions_border: #CCC;
} }
} }
@media print { @media print {
.cp .vigencias { .cp .vigencias {
display:none; display:none;

3
templates/compilacao/ajax_form.html

@ -0,0 +1,3 @@
{% load crispy_forms_tags %}
<div class="btn-close-container"><div class="icon-close"></div></div>
{% crispy form form.helper%}

43
templates/compilacao/dispositivo_search_fragment_form.html

@ -0,0 +1,43 @@
{% load i18n %}
{% load compilacao_filters %}
{% if object_list.count >= 100 %}
<div class="alert-box success radius">
{% trans 'Use argumentos para simplificar listagem...' %}
</div>
{% endif %}
{% for dpt in object_list %}
{% ifchanged dpt.norma%}
{% if not forloop.first %}</ul>{% endif %}
<div class="norma_title">{{dpt.norma}}</div>
<ul>
{% endifchanged %}
{% if dpt.is_relative_auto_insert and dpt.dispositivo_pai and dpt.dispositivo_pai.nivel != 0 %}
<li>
<div class="iteminput">
<input type="{{request.GET.tipo_form}}" name="dispositivo_ref" id="r{{dpt.pk}}" value="{{dpt.pk}}"/>
</div>
<div class="itemlabel">
<label for="r{{dpt.dispositivo_pai.pk}}">{{dpt.dispositivo_pai.rotulo|safe}} - {{dpt.texto|safe}}</label>
<a target="_blank" href="{% url 'compilacao' dpt.norma.pk%}#{{dpt.pk}}" class="nomenclatura_heranca">{% nomenclatura_heranca dpt 1 1 %}</a>
</div>
</li>
{% endif%}
{% if not dpt.tipo_dispositivo.dispositivo_de_articulacao and not dpt.is_relative_auto_insert %}
<li>
<div class="iteminput">
<input type="{{request.GET.tipo_form}}" name="dispositivo_ref" id="r{{dpt.pk}}" value="{{dpt.pk}}"/>
</div>
<div class="itemlabel">
<label for="r{{dpt.pk}}">{{dpt.rotulo|safe}} - {{dpt.texto|safe}}</label>
<a target="_blank" href="{% url 'compilacao' dpt.norma.pk%}#{{dpt.pk}}" class="nomenclatura_heranca">{% nomenclatura_heranca dpt 1 1 %}</a>
</div>
</li>
{% endif%}
{% if forloop.last %}</ul>{% endif %}
{% endfor %}

2
templates/compilacao/edit_bloco.html

@ -106,7 +106,7 @@
{% endif %} {% endif %}
<div class="bloco {% dispositivo_desativado dpt view.inicio_vigencia view.fim_vigencia %} {{ dpt.tipo_dispositivo.class_css }}"> <div class="bloco {% dispositivo_desativado dpt view.inicio_vigencia view.fim_vigencia %} {{ dpt.tipo_dispositivo.class_css }}">
{% spaceless %} {% spaceless %}
<a class="de" id="id{{dpt.id}}" pk="{{dpt.pk}}" ordem="{{dpt.ordem}}" name="{{dpt.pk}}" title="{{dpt.pk}}">{{ dpt.tipo_dispositivo.rotulo_prefixo_html|safe }}{{ dpt.rotulo }}{{ dpt.tipo_dispositivo.rotulo_sufixo_html|safe }}{{ dpt.tipo_dispositivo.texto_prefixo_html|safe }}{% if dpt.texto == '' and not dpt.tipo_dispositivo.dispositivo_de_articulacao %}<span class="semtexto">({{dpt.tipo_dispositivo}} sem texto)</span>{%else%}{{ dpt.texto|safe }}{%endif%}</a> <div class="de" id="id{{dpt.id}}" pk="{{dpt.pk}}" ordem="{{dpt.ordem}}" name="{{dpt.pk}}" title="{{dpt.pk}}">{{ dpt.tipo_dispositivo.rotulo_prefixo_html|safe }}{{ dpt.rotulo }}{{ dpt.tipo_dispositivo.rotulo_sufixo_html|safe }}{{ dpt.tipo_dispositivo.texto_prefixo_html|safe }}{% if dpt.texto == '' and not dpt.tipo_dispositivo.dispositivo_de_articulacao %}<span class="semtexto">({{dpt.tipo_dispositivo}} sem texto)</span>{%else%}{{ dpt.texto|safe }}{%endif%}</div>
{% if dpt.norma_publicada_id != None and not dpt.tipo_dispositivo.dispositivo_de_articulacao %} {% if dpt.norma_publicada_id != None and not dpt.tipo_dispositivo.dispositivo_de_articulacao %}
<a class="link_alterador" href="{%url 'comp_edit' dpt.norma_publicada.pk %}#{{dpt.dispositivo_atualizador_id}}"> <a class="link_alterador" href="{%url 'comp_edit' dpt.norma_publicada.pk %}#{{dpt.dispositivo_atualizador_id}}">
{{ dpt.tipo_dispositivo.nota_automatica_prefixo_html|safe }} {{ dpt.tipo_dispositivo.nota_automatica_prefixo_html|safe }}

101
templates/compilacao/index_bloco.html

@ -11,12 +11,12 @@
{% if forloop.first and view|isinst:'DispositivoView' %} {% if forloop.first and view|isinst:'DispositivoView' %}
{% else %} {% else %}
<div class="dpt {% dispositivo_desativado dpt view.inicio_vigencia view.fim_vigencia %}"> <div class="dpt {%if dpt.tipo_dispositivo.class_css == 'bloco_alteracao'%}bloco_alteracao{%endif%}">
{% endif%} {% endif%}
{% spaceless %} {% spaceless %}
<div class="{{ dpt.tipo_dispositivo.class_css }}"> <div class="{{ dpt.tipo_dispositivo.class_css }}">
<div class="dptt"> <div class="dptt {% dispositivo_desativado dpt view.inicio_vigencia view.fim_vigencia %}">
{{ dpt.tipo_dispositivo.rotulo_prefixo_html|safe }}<a name="{{dpt.pk}}" title="{{dpt.pk}}">{{ dpt.rotulo }}</a>{{ dpt.tipo_dispositivo.rotulo_sufixo_html|safe }}{{ dpt.tipo_dispositivo.texto_prefixo_html|safe }}{%if dpt.texto%}{{ dpt.texto|safe }}{%else%}&nbsp;{%endif%} {{ dpt.tipo_dispositivo.rotulo_prefixo_html|safe }}<a name="{{dpt.pk}}" title="{{dpt.pk}}">{{ dpt.rotulo }}</a>{{ dpt.tipo_dispositivo.rotulo_sufixo_html|safe }}{{ dpt.tipo_dispositivo.texto_prefixo_html|safe }}{%if dpt.texto%}{{ dpt.texto|safe }}{%else%}&nbsp;{%endif%}
{% if dpt.norma_publicada_id != None and not dpt.tipo_dispositivo.dispositivo_de_articulacao %} {% if dpt.norma_publicada_id != None and not dpt.tipo_dispositivo.dispositivo_de_articulacao %}
<a class="link_alterador" href="{%url 'compilacao' dpt.norma_publicada.pk %}#{{dpt.dispositivo_atualizador_id}}"> <a class="link_alterador" href="{%url 'compilacao' dpt.norma_publicada.pk %}#{{dpt.dispositivo_atualizador_id}}">
@ -25,27 +25,99 @@
{{ dpt.tipo_dispositivo.nota_automatica_sufixo_html|safe }} {{ dpt.tipo_dispositivo.nota_automatica_sufixo_html|safe }}
</a> </a>
{% endif %} {% endif %}
{% if not dpt.tipo_dispositivo.dispositivo_de_articulacao%} {% if user.is_authenticated and not dpt.tipo_dispositivo.dispositivo_de_articulacao%}
{% if perms.compilacao.add_nota or perms.compilacao.add_vide %}
<div class="dne" id="dne{{dpt.pk}}" pk="{{dpt.pk}}">{# TODO: User - dne - Dispostivo Nota Editor - tratar permissão de usuário#} <div class="dne" id="dne{{dpt.pk}}" pk="{{dpt.pk}}">{# TODO: User - dne - Dispostivo Nota Editor - tratar permissão de usuário#}
<ul class="btns-action"> <ul class="btns-action">
<li><a class="btn-create" pk="{{dpt.pk}}" title="{% trans 'Adcionar uma Nota ao Dispositivo'%}">&nbsp;</a></li> {% if perms.compilacao.add_nota %}<li><a class="btn-action btn-nota-create" model="nota" pk="{{dpt.pk}}" title="{% trans 'Adcionar Nota'%}">&nbsp;</a></li>{% endif %}
{% if perms.compilacao.add_vide %}<li><a class="btn-action btn-vide-create" model="vide" pk="{{dpt.pk}}" title="{% trans 'Adcionar Vide'%}">V</a></li>{% endif %}
</ul> </ul>
<div class="dne-form"></div> <div class="dne-form"></div>
</div> </div>
{% endif %} {% endif %}
{% endif%}
</div> </div>
{% if not dpt.tipo_dispositivo.dispositivo_de_articulacao%}
<div class="dn" id="dn{{dpt.pk}}" pk="{{dpt.pk}}">{# Dispostivo Nota#}
{% if not dpt.tipo_dispositivo.dispositivo_de_articulacao%}
<div class="dn" id="dn{{dpt.pk}}" pk="{{dpt.pk}}">{# Dispostivo Nota e Vides #}
<ul class="dnl">{# Dispostivo Nota Lista#} <ul class="dnl">{# Dispostivo Nota Lista#}
{% for nota in dpt.notas.all %}{# TODO: User - dnl - Dispostivo Nota Editor - tratar permissão de usuário quanto a publicidade#} {% if cita and dpt.pk in cita %}
<li class="dnli" id="nt{{nota.pk}}"> {% for vide in dpt.cita.all %}
{%if not forloop.first %}<li class="bullet">&#8226;</li>{%endif%}
<li class="dnli" id="nt{{vide.pk}}">
<ul> <ul>
<li><a class="btn-edit" pk="{{nota.pk}}">Editar</a></li> {# TODO: User - tratar permissão usuário #} {% if user.is_authenticated %}
{% if perms.compilacao.change_vide %}
<li><a class="btn-action btn-vide-edit" model="vide" pk="{{vide.pk}}">Editar</a></li>
<li class="bullet">&#8226;</li>
{%endif%}
{% if perms.compilacao.delete_vide %}
<li><a class="btn-action btn-vide-delete" model="vide" pk="{{vide.pk}}">Excluir</a></li>
<li class="bullet">&#8226;</li>
{%endif%}
{% endif %}
<li class="ntipo">{{vide.tipo.nome}}</li>
<li class="bullet">&#8226;</li> <li class="bullet">&#8226;</li>
<li><a class="btn-delete" pk="{{nota.pk}}">Excluir</a></li> {# TODO: User - tratar permissão usuário #} <li class="npublicacao" title="{% trans 'Data de Criação'%}">{{vide.created|date:"d M Y"}}</li>
</ul>
<div class="ntitulo">Vide: </div>
<div class="ntexto">
{% if dpt.is_relative_auto_insert %}
<a href="{%url 'compilacao' vide.dispositivo_ref.dispositivo_pai.norma.pk%}#{{vide.dispositivo_ref.dispositivo_pai.pk }}">{{ vide.dispositivo_ref.dispositivo_pai}}</a>
{% else %}
<a href="{%url 'compilacao' vide.dispositivo_ref.norma.pk%}#{{vide.dispositivo_ref.pk }}">{{ vide.dispositivo_ref}}</a>
{% endif %}
{% if vide.texto %} - {{vide.texto}}{% endif %}
</div>
</li>
{% endfor %}
{% endif %}
{% if citado and dpt.pk in citado %}
{% for vide in dpt.citado.all %}
{%if not forloop.first %}<li class="bullet">&#8226;</li>{%endif%}
<li class="dnli" id="nt{{vide.pk}}">
<ul>
<li class="ntipo">{{vide.tipo.nome}}</li>
<li class="bullet">&#8226;</li> <li class="bullet">&#8226;</li>
<li class="npublicacao" title="{% trans 'Data de Criação'%}">{{vide.created|date:"d M Y"}}</li>
</ul>
<div class="ntitulo">Citado em: </div>
<div class="ntexto">
{% if dpt.is_relative_auto_insert %}
<a href="{%url 'compilacao' vide.dispositivo_base.dispositivo_pai.norma.pk%}#{{vide.dispositivo_base.dispositivo_pai.pk }}">{{ vide.dispositivo_base.dispositivo_pai}}</a>
{% else %}
<a href="{%url 'compilacao' vide.dispositivo_base.norma.pk%}#{{vide.dispositivo_base.pk }}">{{ vide.dispositivo_base}}</a>
{% endif %}
{% if vide.texto %} - {{vide.texto}}{% endif %}
</div>
</li>
{% endfor %}
{% endif %}
{%if notas and dpt.pk in notas and dpt.pk in cita or dpt.pk in citado and notas%}<li class="bullet">&#8226;</li>{%endif%}
{% if notas and dpt.pk in notas %}
{% for nota in dpt.notas.all %}
{% if user.is_superuser or nota.publicidade == nota.NPUBL or nota.publicidade == nota.NINST and user.is_authenticated or nota.publicidade = nota.NPRIV and nota.owner == user %}
{%if not forloop.first %}<li class="bullet">&#8226;</li>{%endif%}
<li class="dnli" id="nt{{nota.pk}}">
<ul>
{% if user.is_authenticated %}
{% if user == nota.owner and perms.compilacao.change_nota or user.is_superuser%}
<li><a class="btn-action btn-nota-edit" model="nota" pk="{{nota.pk}}">Editar</a></li>
<li class="bullet">&#8226;</li>
{% endif %}
{% if user == nota.owner and perms.compilacao.delete_nota or user.is_superuser %}
<li><a class="btn-action btn-nota-delete" model="nota" pk="{{nota.pk}}">Excluir</a></li>
<li class="bullet">&#8226;</li>
{% endif %}
{% endif %}
<li class="ntipo">{{nota.tipo.nome}}</li> <li class="ntipo">{{nota.tipo.nome}}</li>
<li class="bullet">&#8226;</li> <li class="bullet">&#8226;</li>
<li class="nowner" title="{% trans 'Criado Por' %}">{%if nota.owner.first_name%}{{nota.owner.first_name}}{%else%}{{nota.owner}}{%endif%}</li> <li class="nowner" title="{% trans 'Criado Por' %}">{%if nota.owner.first_name%}{{nota.owner.first_name}}{%else%}{{nota.owner}}{%endif%}</li>
@ -56,7 +128,7 @@
{%if nota.titulo %} {%if nota.titulo %}
<div class="ntitulo"> <div class="ntitulo">
{%if nota.url_externa %}<a target="_blank" href="{{nota.url_externa}}">{%endif%} {%if nota.url_externa %}<a target="_blank" href="{{nota.url_externa}}">{%endif%}
{{nota.titulo}} {{nota.titulo}} -
{%if nota.url_externa %}</a>{%endif%} {%if nota.url_externa %}</a>{%endif%}
</div> </div>
{%endif%} {%endif%}
@ -74,8 +146,13 @@
<li class="npublicidade">{{nota.get_publicidade_display}}</li> <li class="npublicidade">{{nota.get_publicidade_display}}</li>
</ul> </ul>
{%endcomment%} {%endcomment%}
</li>{# Dispostivo Nota Lista Item#} </li>
{% endif %}
{% endfor %} {% endfor %}
{% endif %}
</ul> </ul>
</div> </div>
{% endif%} {% endif%}

4
templates/compilacao/index_bloco_alteracao.html

@ -3,9 +3,9 @@
{% spaceless %} {% spaceless %}
<div class="dpt" id="d{{ch.id}}"> <div class="dpt" id="d{{ch.id}}">
<div class="{{ ch.tipo_dispositivo.class_css }}" id="id{{ch.id}}" nivel="{{ch.nivel}}"> <div class="{{ ch.tipo_dispositivo.class_css }}" id="id{{ch.id}}" nivel="{{ch.nivel}}">
<div class="dptt">
{{ ch.tipo_dispositivo.rotulo_prefixo_html|safe }}<a name="{{ch.pk}}" href="{%url 'compilacao' ch.norma.pk %}#{{ch.pk}}">{{ ch.rotulo }}</a>{{ ch.tipo_dispositivo.rotulo_sufixo_html|safe }}{{ ch.tipo_dispositivo.texto_prefixo_html|safe }}{{ ch.texto|safe }} {{ ch.tipo_dispositivo.rotulo_prefixo_html|safe }}<a name="{{ch.pk}}" href="{%url 'compilacao' ch.norma.pk %}#{{ch.pk}}">{{ ch.rotulo }}</a>{{ ch.tipo_dispositivo.rotulo_sufixo_html|safe }}{{ ch.tipo_dispositivo.texto_prefixo_html|safe }}{{ ch.texto|safe }}
</div>
</div> </div>
</div> </div>
{% endspaceless %} {% endspaceless %}

3
templates/compilacao/nota_ajaxform.html

@ -1,3 +0,0 @@
{% load crispy_forms_tags %}
{% crispy form form.helper%}
Loading…
Cancel
Save