Browse Source

Merge pull request #299 from interlegis/compilacao

Fix #14 - Edição Avançada de Dispositivos
pull/301/head 3.1.1-alpha
Leandro Roberto da Silva 9 years ago
parent
commit
e9c7701235
  1. 756
      compilacao/forms.py
  2. 36
      compilacao/migrations/0045_auto_20160311_1117.py
  3. 25
      compilacao/migrations/0046_auto_20160319_1542.py
  4. 21
      compilacao/migrations/0047_auto_20160330_0027.py
  5. 21
      compilacao/migrations/0048_auto_20160404_2309.py
  6. 16
      compilacao/migrations/0049_merge.py
  7. 113
      compilacao/models.py
  8. 132
      compilacao/templatetags/compilacao_filters.py
  9. 29
      compilacao/urls.py
  10. 15
      compilacao/utils.py
  11. 1700
      compilacao/views.py
  12. 4
      crispy_layout_mixin.py
  13. 2
      norma/urls.py
  14. 32
      static/js/app.js
  15. 225
      static/js/compilacao.js
  16. 65
      static/js/compilacao_edit.js
  17. 70
      static/js/compilacao_notas.js
  18. 8
      static/js/compilacao_view.js
  19. 17
      static/styles/app.scss
  20. 411
      static/styles/compilacao.scss
  21. 2
      static/styles/style_tinymce.css
  22. 42
      templates/compilacao/dispositivo_form.html
  23. 12
      templates/compilacao/dispositivo_form_alteracao.html
  24. 11
      templates/compilacao/dispositivo_form_definidor_vigencia.html
  25. 36
      templates/compilacao/dispositivo_form_edicao_basica.html
  26. 31
      templates/compilacao/dispositivo_form_parents.html
  27. 19
      templates/compilacao/dispositivo_form_search.html
  28. 125
      templates/compilacao/dispositivo_form_search_fragment.html
  29. 28
      templates/compilacao/dispositivo_form_vigencia.html
  30. 39
      templates/compilacao/dispositivo_search_fragment_form.html
  31. 6
      templates/compilacao/form.html
  32. 54
      templates/compilacao/layout/dispositivo_checkbox.html
  33. 54
      templates/compilacao/layout/dispositivo_checkbox_old.html
  34. 43
      templates/compilacao/layout/dispositivo_radio.html
  35. 3
      templates/compilacao/publicacao_list.html
  36. 92
      templates/compilacao/text_edit.html
  37. 54
      templates/compilacao/text_edit_bloco.html
  38. 3
      templates/compilacao/text_edit_blocoalteracao.html
  39. 27
      templates/compilacao/text_list.html
  40. 6
      templates/compilacao/text_list_bloco.html
  41. 2
      templates/compilacao/textoarticulado_detail.html
  42. 8
      templates/compilacao/textoarticulado_menu_config.html

756
compilacao/forms.py

@ -1,18 +1,25 @@
from crispy_forms.bootstrap import FieldWithButtons, FormActions, StrictButton
from datetime import timedelta
from crispy_forms.bootstrap import (Alert, FieldWithButtons, FormActions,
InlineRadios, StrictButton)
from crispy_forms.helper import FormHelper
from crispy_forms.layout import (HTML, Button, Column, Div, Field, Fieldset,
Layout, Row)
from django import forms
from django.core.exceptions import NON_FIELD_ERRORS
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
from django.forms.forms import Form
from django.forms.models import ModelForm
from django.template import defaultfilters
from django.utils.translation import ugettext_lazy as _
from compilacao.models import (NOTAS_PUBLICIDADE_CHOICES,
PARTICIPACAO_SOCIAL_CHOICES, Dispositivo, Nota,
Publicacao, TextoArticulado, TipoNota,
TipoPublicacao, TipoTextoArticulado, TipoVide,
VeiculoPublicacao, Vide)
Publicacao, TextoArticulado, TipoDispositivo,
TipoNota, TipoPublicacao, TipoTextoArticulado,
TipoVide, VeiculoPublicacao, Vide)
from compilacao.utils import DISPOSITIVO_SELECT_RELATED
from crispy_layout_mixin import SaplFormLayout, to_column, to_row
from sapl import utils
from sapl.utils import YES_NO_CHOICES
error_messages = {
@ -136,6 +143,17 @@ class TaForm(ModelForm):
)
super(TaForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['tipo_ta'].widget.attrs['disabled'] = True
self.fields['tipo_ta'].required = False
def clean_tipo_ta(self):
instance = getattr(self, 'instance', None)
if instance and instance.pk:
return instance.tipo_ta
else:
return self.cleaned_data['tipo_ta']
class NotaForm(ModelForm):
@ -246,13 +264,7 @@ class NotaForm(ModelForm):
super(NotaForm, self).__init__(*args, **kwargs)
class VideForm(ModelForm):
dispositivo_base = forms.ModelChoiceField(
queryset=Dispositivo.objects.all(),
widget=forms.HiddenInput())
dispositivo_ref = forms.ModelChoiceField(
queryset=Dispositivo.objects.all(),
widget=forms.HiddenInput())
class DispositivoSearchFragmentForm(ModelForm):
tipo_ta = forms.ModelChoiceField(
label=_('Tipo do Texto Articulado'),
@ -264,23 +276,73 @@ class VideForm(ModelForm):
label=_('Tipos de...'), required=False)
num_ta = forms.IntegerField(
label=_('Núm Texto Articulado'), required=False)
label=_('Número'), required=False)
ano_ta = forms.IntegerField(
label=_('Ano Texto Articulado'), required=False)
label=_('Ano'), required=False)
texto = forms.CharField(
label='',
widget=forms.Textarea,
rotulo_dispositivo = forms.CharField(
label=_('Rótulo'),
required=False)
texto_dispositivo = forms.CharField(
label=_('Pesquisa Textual'),
required=False)
def __init__(self, *args, **kwargs):
if 'fields_search' in kwargs:
fields_search = kwargs['fields_search'].fields
fields_search.append(Fieldset(
_('Busca por um Dispositivo'),
Row(
to_column(('num_ta', 6)),
to_column(('ano_ta', 6))),
Row(
to_column(('tipo_ta', 6)),
to_column(('tipo_model', 6))),
Row(to_column(('rotulo_dispositivo', 3)),
to_column((FieldWithButtons(
Field(
'texto_dispositivo',
placeholder=_('Digite palavras, letras, '
'números ou algo'
' que estejam no texto.')),
StrictButton(_('Buscar'), css_class='btn-busca')), 9)))
))
fields_search.append(
Row(to_column(
(Div(css_class='result-busca-dispositivo'), 12))))
kwargs.pop('fields_search')
if 'choice_model_type_foreignkey_in_extenal_views' in kwargs:
ch = kwargs.pop('choice_model_type_foreignkey_in_extenal_views')
if 'data' in kwargs:
choice = ch(kwargs['data']['tipo_ta'])
self.base_fields['tipo_model'].choices = choice
elif 'instance' in kwargs and\
isinstance(kwargs['instance'], Dispositivo):
choice = ch(kwargs['instance'].ta.tipo_ta_id)
self.base_fields['tipo_model'].choices = choice
super(DispositivoSearchFragmentForm, self).__init__(*args, **kwargs)
class VideForm(DispositivoSearchFragmentForm):
dispositivo_base = forms.ModelChoiceField(
queryset=Dispositivo.objects.all(),
widget=forms.HiddenInput())
dispositivo_ref = forms.ModelChoiceField(
queryset=Dispositivo.objects.all(),
widget=forms.HiddenInput())
tipo = forms.ModelChoiceField(
label=TipoVide._meta.verbose_name,
queryset=TipoVide.objects.all(),
required=True,
error_messages=error_messages)
busca_dispositivo = forms.CharField(
label=_('Buscar Dispositivo a Referenciar'),
required=False)
pk = forms.IntegerField(widget=forms.HiddenInput(),
required=False)
@ -318,24 +380,7 @@ class VideForm(ModelForm):
placeholder=_('Texto Adicional ao Vide')), 12))),
Row(to_column((buttons, 12))))
fields_search = Div(
Row(
to_column(('tipo_ta', 6)),
to_column(('tipo_model', 6))),
Row(
to_column(('num_ta', 6)),
to_column(('ano_ta', 6))),
Row(to_column((FieldWithButtons(
Field(
'busca_dispositivo',
placeholder=_('Digite palavras, letras, '
'números ou algo'
' que estejam '
'no rótulo ou no texto.')),
StrictButton("Buscar", css_class='btn-busca')), 12))),
Row(to_column(
(Div(css_class='container-busca'), 12)))
)
kwargs['fields_search'] = fields_search = Div()
self.helper = FormHelper()
self.helper.layout = Layout(
@ -351,12 +396,6 @@ class VideForm(ModelForm):
)
)
if 'choice_model_type_foreignkey_in_extenal_views' in kwargs:
ch = kwargs.pop('choice_model_type_foreignkey_in_extenal_views')
if 'data' in kwargs:
choice = ch(kwargs['data']['tipo_ta'])
self.base_fields['tipo_model'].choices = choice
super(VideForm, self).__init__(*args, **kwargs)
@ -451,3 +490,632 @@ class PublicacaoForm(ModelForm):
super(PublicacaoForm, self).__init__(*args, **kwargs)
pass
class DispositivoIntegerField(forms.IntegerField):
def __init__(self, field_name=None, *args, **kwargs):
if 'required' not in kwargs:
kwargs.setdefault('required', False)
self.widget = forms.NumberInput(
attrs={'title': Dispositivo._meta.get_field(
field_name).verbose_name,
'onchange': 'atualizaRotulo()'})
super(DispositivoIntegerField, self).__init__(
min_value=0, *args, **kwargs)
class DispositivoEdicaoBasicaForm(ModelForm):
class Meta:
model = Dispositivo
fields = []
error_messages = {
NON_FIELD_ERRORS: {
'unique_together':
_("Já existe um Dispositivo com características idênticas."),
}
}
def __init__(self, *args, **kwargs):
layout = []
inst = kwargs['instance'] if 'instance' in kwargs else None
if inst and inst.tipo_dispositivo.formato_variacao0 in [
TipoDispositivo.FNC8, TipoDispositivo.FNCN]:
if 'rotulo' in DispositivoEdicaoBasicaForm.Meta.fields:
DispositivoEdicaoBasicaForm.Meta.fields.remove('rotulo')
for i in range(6):
DispositivoEdicaoBasicaForm.Meta.fields.remove(
'dispositivo%s' % i)
else:
if 'rotulo' not in DispositivoEdicaoBasicaForm.Meta.fields:
DispositivoEdicaoBasicaForm.Meta.fields.append('rotulo')
for i in range(6):
DispositivoEdicaoBasicaForm.Meta.fields.append(
'dispositivo%s' % i)
# adiciona campos de rótulo no formulário
self.dispositivo0 = forms.IntegerField(
min_value=0,
label=Dispositivo._meta.get_field('dispositivo0').verbose_name,
widget=forms.NumberInput(
attrs={'title': _('Valor 0(zero) é permitido apenas para '
'Dispositivos com tipos variáveis.'),
'onchange': 'atualizaRotulo()'}))
self.dispositivo1 = DispositivoIntegerField(
label=('1ª %s' % _('Variação')),
field_name='dispositivo1')
self.dispositivo2 = DispositivoIntegerField(
label=('2ª'),
field_name='dispositivo2')
self.dispositivo3 = DispositivoIntegerField(
label=('3ª'),
field_name='dispositivo3')
self.dispositivo4 = DispositivoIntegerField(
label=('4ª'),
field_name='dispositivo4')
self.dispositivo5 = DispositivoIntegerField(
label=('5ª'),
field_name='dispositivo5')
self.rotulo = forms.CharField(
required=False, label=_('Rótulo Resultante'))
rotulo_fieldset = to_row([
('dispositivo0', 3),
('dispositivo1', 2),
('dispositivo2', 1),
('dispositivo3', 1),
('dispositivo4', 1),
('dispositivo5', 1),
('rotulo', 3)])
layout.append(Fieldset(_('Construção do Rótulo'), rotulo_fieldset,
css_class="col-md-12"))
if inst and inst.tipo_dispositivo.dispositivo_de_articulacao:
if 'texto' in DispositivoEdicaoBasicaForm.Meta.fields:
DispositivoEdicaoBasicaForm.Meta.fields.remove('texto')
else:
if 'texto' not in DispositivoEdicaoBasicaForm.Meta.fields:
DispositivoEdicaoBasicaForm.Meta.fields.append('texto')
self.texto = forms.CharField(required=False,
label='',
widget=forms.Textarea())
row_texto = to_row([('texto', 12)])
layout.append(
Fieldset(Dispositivo._meta.get_field('texto').verbose_name,
row_texto,
css_class="col-md-12"))
fields = DispositivoEdicaoBasicaForm.Meta.fields
if fields:
self.base_fields.clear()
for f in fields:
self.base_fields.update({f: getattr(self, f)})
self.helper = FormHelper()
self.helper.layout = SaplFormLayout(
*layout,
label_cancel=_('Retornar para o Editor Sequencial'))
super(DispositivoEdicaoBasicaForm, self).__init__(*args, **kwargs)
class DispositivoSearchModalForm(Form):
tipo_ta = forms.ModelChoiceField(
label=_('Tipo do Texto Articulado'),
queryset=TipoTextoArticulado.objects.all(),
required=False)
tipo_model = forms.ChoiceField(
choices=[],
label=_('Tipos de...'), required=False)
num_ta = forms.IntegerField(
label=_('Número do Documento'), required=False)
ano_ta = forms.IntegerField(
label=_('Ano do Documento'), required=False)
dispositivos_internos = forms.ChoiceField(
label=_('Dispositivos Internos?'),
choices=utils.YES_NO_CHOICES,
widget=forms.RadioSelect(),
required=False)
max_results = forms.ChoiceField(
label=_('Limite de Listagem'),
choices=[(10, _('Dez Dispositivos')),
(30, _('Trinta Dispositivos')),
(50, _('Cinquenta Dispositivos')),
(0, _('Tudo que atender aos Critérios da Busca'))],
widget=forms.Select(),
required=False)
rotulo_dispositivo = forms.CharField(
label=_('Rótulo'),
required=False)
texto_dispositivo = forms.CharField(
label=_('Pesquisa Textual'),
required=False)
def __init__(self, *args, **kwargs):
fields_search = Fieldset(
_('Busca por um Dispositivo'),
Row(
to_column(('num_ta', 4)),
to_column(('ano_ta', 4)),
to_column(('max_results', 4))),
Row(
to_column(('tipo_ta', 6)),
to_column(('tipo_model', 6))),
Row(to_column((InlineRadios('dispositivos_internos'), 3)),
to_column(('rotulo_dispositivo', 2)),
to_column((FieldWithButtons(
Field(
'texto_dispositivo',
placeholder=_('Digite palavras, letras, '
'números ou algo'
' que estejam no texto.')),
StrictButton(_('Buscar'), css_class='btn-busca')), 7))
)
)
self.helper = FormHelper()
self.helper.layout = Layout(
fields_search,
Row(to_column((Div(css_class='result-busca-dispositivo'), 12))))
if 'choice_model_type_foreignkey_in_extenal_views' in kwargs:
ch = kwargs.pop('choice_model_type_foreignkey_in_extenal_views')
if 'data' in kwargs:
choice = ch(kwargs['data']['tipo_ta'])
self.base_fields['tipo_model'].choices = choice
elif 'instance' in kwargs and\
isinstance(kwargs['instance'], Dispositivo):
choice = ch(kwargs['instance'].ta.tipo_ta_id)
self.base_fields['tipo_model'].choices = choice
kwargs['initial'].update({'dispositivos_internos': False})
super(DispositivoSearchModalForm, self).__init__(*args, **kwargs)
class DispositivoEdicaoVigenciaForm(ModelForm):
inconstitucionalidade = forms.ChoiceField(
label=Dispositivo._meta.get_field(
'inconstitucionalidade').verbose_name,
choices=utils.YES_NO_CHOICES,
widget=forms.RadioSelect())
dispositivo_vigencia = forms.ModelChoiceField(
label=Dispositivo._meta.get_field(
'dispositivo_vigencia').verbose_name,
required=False,
queryset=Dispositivo.objects.all())
extensao = forms.ChoiceField(
label=_('Extender a seleção abaixo como Dispositivo de Vigência '
'para todos dependentes originais '
'deste Dispositivo em edição?'),
choices=utils.YES_NO_CHOICES,
widget=forms.RadioSelect(),
required=False)
class Meta:
model = Dispositivo
fields = ['inicio_vigencia',
'fim_vigencia',
'inicio_eficacia',
'fim_eficacia',
'publicacao',
'inconstitucionalidade',
'dispositivo_vigencia'
]
error_messages = {
NON_FIELD_ERRORS: {
'unique_together':
_("Já existe um Dispositivo com características idênticas."),
}
}
def __init__(self, *args, **kwargs):
layout = []
row_publicacao = to_row([
('publicacao', 6),
(InlineRadios('inconstitucionalidade'), 3), ])
row_publicacao.fields.append(
Alert(
css_class='alert-info col-md-3',
content='<strong>%s</strong> %s' % (
_('Dica!'), _('Inclua uma Nota de Dispositivo informando '
'sobre a Inconstitucionalidade.'))))
layout.append(
Fieldset(_('Registro de Publicação e Validade'),
row_publicacao,
css_class="col-md-12"))
row_datas = to_row([
('inicio_vigencia', 3),
('fim_vigencia', 3),
('inicio_eficacia', 3),
('fim_eficacia', 3), ])
layout.append(
Fieldset(_('Datas de Controle de Vigência'),
row_datas,
css_class="col-md-12"))
row_vigencia = Field(
'dispositivo_vigencia',
data_sapl_ta='DispositivoSearch',
data_field='dispositivo_vigencia',
data_type_selection='radio',
template="compilacao/layout/dispositivo_radio.html")
layout.append(
Fieldset(_('Dispositivo de Vigência'),
to_row([(InlineRadios('extensao'), 12)]),
row_vigencia,
css_class="col-md-12"))
self.helper = FormHelper()
self.helper.layout = SaplFormLayout(
*layout,
label_cancel=_('Retornar para o Editor Sequencial'))
super(DispositivoEdicaoVigenciaForm, self).__init__(*args, **kwargs)
pubs = Publicacao.objects.order_by(
'-data', '-hora').filter(ta=self.instance.ta)
self.fields['publicacao'].choices = [("", "---------")] + [(
p.pk, _('%s realizada em %s') % (
p.tipo_publicacao,
defaultfilters.date(
p.data, "d \d\e F \d\e Y"))) for p in pubs]
dvs = Dispositivo.objects.order_by('ordem').filter(
pk=self.instance.dispositivo_vigencia_id)
self.fields['dispositivo_vigencia'].choices = [(d.pk, d) for d in dvs]
def clean_dispositivo_vigencia(self):
dv = self.cleaned_data['dispositivo_vigencia']
if dv and dv.is_relative_auto_insert():
dv = dv.dispositivo_pai
return dv
def save(self):
super(DispositivoEdicaoVigenciaForm, self).save()
data = self.cleaned_data
extensao = 'extensao' in data and data['extensao'] == 'True'
if extensao:
dv = data['dispositivo_vigencia']
if dv and dv.is_relative_auto_insert():
dv = dv.dispositivo_pai
dv_pk = dv.pk if dv else None
instance = self.instance
def extenderPara(dpt_pk):
Dispositivo.objects.filter(
dispositivo_pai_id=dpt_pk,
ta_publicado__isnull=True).update(
dispositivo_vigencia_id=dv_pk)
filhos = Dispositivo.objects.filter(
dispositivo_pai_id=dpt_pk).values_list('pk', flat=True)
for d in filhos:
extenderPara(d)
extenderPara(instance.pk)
class MultipleChoiceWithoutValidationField(forms.MultipleChoiceField):
def validate(self, value):
if self.required and not value:
raise ValidationError(
self.error_messages['required'], code='required')
class DispositivoDefinidorVigenciaForm(Form):
dispositivo_vigencia = MultipleChoiceWithoutValidationField(
label=Dispositivo._meta.get_field(
'dispositivo_vigencia').verbose_name,
required=False)
def __init__(self, *args, **kwargs):
layout = []
row_vigencia = Field(
'dispositivo_vigencia',
data_sapl_ta='DispositivoSearch',
data_field='dispositivo_vigencia',
data_type_selection='checkbox',
template="compilacao/layout/dispositivo_checkbox.html")
layout.append(
Fieldset(_('Definidor de Vigência dos Dispositívos abaixo'),
row_vigencia,
css_class="col-md-12"))
self.helper = FormHelper()
self.helper.layout = SaplFormLayout(
*layout,
label_cancel=_('Retornar para o Editor Sequencial'))
pk = kwargs.pop('pk')
super(DispositivoDefinidorVigenciaForm, self).__init__(*args, **kwargs)
dvs = Dispositivo.objects.order_by('ta', 'ordem').filter(
dispositivo_vigencia_id=pk).select_related(
*DISPOSITIVO_SELECT_RELATED)
self.initial['dispositivo_vigencia'] = [d.pk for d in dvs]
TA_TA_PUB = 'ta_id', 'ta_publicado_id'
tas = Dispositivo.objects.order_by(
*TA_TA_PUB).filter(dispositivo_vigencia_id=pk).distinct(
*TA_TA_PUB).values_list(
*TA_TA_PUB)
tas = list(set().union(*list(map(list, zip(*tas)))))
if not tas:
tas = Dispositivo.objects.filter(pk=pk).values_list('ta_id')
dvs = Dispositivo.objects.order_by(
'-ta__data', '-ta__ano', '-ta__numero', 'ta', 'ordem').filter(
ta__in=tas).select_related(*DISPOSITIVO_SELECT_RELATED)
self.fields['dispositivo_vigencia'].choices = [
(d.pk, d)
for d in dvs
if d.pk in self.initial['dispositivo_vigencia']]
class DispositivoEdicaoAlteracaoForm(ModelForm):
class Meta:
model = Dispositivo
fields = [
'dispositivo_atualizador',
'dispositivo_substituido',
'dispositivo_subsequente',
]
error_messages = {
NON_FIELD_ERRORS: {
'unique_together':
_("Já existe um Dispositivo com características idênticas."),
}
}
def __init__(self, *args, **kwargs):
layout = []
self.dispositivo_substituido = forms.ModelChoiceField(
label=Dispositivo._meta.get_field(
'dispositivo_substituido').verbose_name,
required=False,
queryset=Dispositivo.objects.all())
self.dispositivo_subsequente = forms.ModelChoiceField(
label=Dispositivo._meta.get_field(
'dispositivo_subsequente').verbose_name,
required=False,
queryset=Dispositivo.objects.all())
self.dispositivo_atualizador = forms.ModelChoiceField(
label=Dispositivo._meta.get_field(
'dispositivo_atualizador').verbose_name,
required=False,
queryset=Dispositivo.objects.all())
substituido = Field(
'dispositivo_substituido',
data_sapl_ta='DispositivoSearch',
data_field='dispositivo_substituido',
data_type_selection='radio',
template="compilacao/layout/dispositivo_radio.html")
subsequente = Field(
'dispositivo_subsequente',
data_sapl_ta='DispositivoSearch',
data_field='dispositivo_subsequente',
data_type_selection='radio',
template="compilacao/layout/dispositivo_radio.html")
alterador = Field(
'dispositivo_atualizador',
data_sapl_ta='DispositivoSearch',
data_field='dispositivo_atualizador',
data_type_selection='radio',
data_function='alterador',
template="compilacao/layout/dispositivo_radio.html")
layout.append(
to_row([
(Fieldset(_('Dispositivo Subsitituido'), substituido), 6),
(Fieldset(_('Dispositivo Subsequente'), subsequente), 6)]))
layout.append(
Fieldset(
_('Dispositivo Alterador'),
Div(alterador),
css_class="col-md-12"))
inst = kwargs['instance'] if 'instance' in kwargs else None
if inst and inst.tipo_dispositivo.dispositivo_de_articulacao:
if 'texto_atualizador' in\
DispositivoEdicaoAlteracaoForm.Meta.fields:
DispositivoEdicaoAlteracaoForm.Meta.fields.remove(
'texto_atualizador')
DispositivoEdicaoAlteracaoForm.Meta.fields.remove(
'visibilidade')
else:
if 'texto_atualizador' not in\
DispositivoEdicaoAlteracaoForm.Meta.fields:
DispositivoEdicaoAlteracaoForm.Meta.fields.append(
'texto_atualizador')
DispositivoEdicaoAlteracaoForm.Meta.fields.append(
'visibilidade')
self.texto_atualizador = forms.CharField(required=False,
label='',
widget=forms.Textarea())
self.visibilidade = forms.ChoiceField(
label=Dispositivo._meta.get_field(
'visibilidade').verbose_name,
choices=utils.YES_NO_CHOICES,
widget=forms.RadioSelect())
layout.append(
Fieldset(Dispositivo._meta.get_field(
'texto_atualizador').verbose_name,
to_row([(InlineRadios('visibilidade'), 12)]),
to_row([('texto_atualizador', 12)]),
css_class="col-md-12"))
fields = DispositivoEdicaoAlteracaoForm.Meta.fields
if fields:
self.base_fields.clear()
for f in fields:
if hasattr(self, f):
self.base_fields.update({f: getattr(self, f)})
self.helper = FormHelper()
self.helper.layout = SaplFormLayout(
*layout,
label_cancel=_('Retornar para o Editor Sequencial'))
super(DispositivoEdicaoAlteracaoForm, self).__init__(*args, **kwargs)
self.fields['dispositivo_substituido'].choices = []
self.fields['dispositivo_subsequente'].choices = []
self.fields['dispositivo_atualizador'].choices = []
if inst.dispositivo_substituido:
self.fields['dispositivo_substituido'].choices = [
(inst.dispositivo_substituido.pk,
inst.dispositivo_substituido)]
if inst.dispositivo_subsequente:
self.fields['dispositivo_subsequente'].choices = [
(inst.dispositivo_subsequente.pk,
inst.dispositivo_subsequente)]
if inst.dispositivo_atualizador:
self.fields['dispositivo_atualizador'].choices = [
(inst.dispositivo_atualizador.pk,
inst.dispositivo_atualizador)]
def clean_dispositivo_substituido(self):
dst = self.cleaned_data['dispositivo_substituido']
if dst and dst.ta != self.instance.ta:
raise ValidationError(_('Não é permitido selecionar um '
'Dispositivo de outro Texto Articulado.'))
if dst and dst.tipo_dispositivo != self.instance.tipo_dispositivo:
raise ValidationError(_('Não é permitido selecionar um '
'Dispositivo de outro Tipo.'))
return dst
def clean_dispositivo_subsequente(self):
dsq = self.cleaned_data['dispositivo_subsequente']
if dsq and dsq.ta != self.instance.ta:
raise ValidationError(_('Não é permitido selecionar um '
'Dispositivo de outro Texto Articulado.'))
if dsq and dsq.tipo_dispositivo != self.instance.tipo_dispositivo:
raise ValidationError(_('Não é permitido selecionar um '
'Dispositivo de outro Tipo.'))
return dsq
def clean_dispositivo_atualizador(self):
da = self.cleaned_data['dispositivo_atualizador']
if da and not da.tipo_dispositivo.dispositivo_de_alteracao and\
not da.tipo_dispositivo.dispositivo_de_articulacao:
raise ValidationError(_('O Dispositivo de Atualização selecionado '
'não é um Bloco de Alteração.'))
return da
def clean(self):
data = self.cleaned_data
ndst = data['dispositivo_substituido']
nda = data['dispositivo_atualizador']
if not nda and ndst:
raise ValidationError(_('Não é permitido substituir um '
'Dispositivo sem haver um '
'Dispositivo Alterador.'))
def save(self):
data = self.cleaned_data
od = Dispositivo.objects.get(pk=self.instance.pk)
nd = self.instance
ndst = data['dispositivo_substituido']
ndsq = data['dispositivo_subsequente']
nda = data['dispositivo_atualizador']
if ndst != od.dispositivo_substituido:
if od.dispositivo_substituido:
odst = od.dispositivo_substituido
odst.dispositivo_subsequente = None
odst.fim_vigencia = None
odst.fim_eficacia = None
odst.save()
if ndst:
if ndst.dispositivo_subsequente:
ndst.dispositivo_subsequente.dispositivo_substituido = None
ndst.dispositivo_subsequente.save()
ndst.dispositivo_subsequente = nd
ndst.fim_vigencia = nd.inicio_vigencia - timedelta(days=1)
ndst.fim_eficacia = nd.inicio_eficacia - timedelta(days=1)
ndst.save()
if ndsq != od.dispositivo_subsequente:
if od.dispositivo_subsequente:
odsq = od.dispositivo_subsequente
odsq.dispositivo_substituido = None
odsq.save()
if ndsq:
if ndsq.dispositivo_substituido:
ndsq.dispositivo_substituido.dispositivo_subsequente = None
ndsq.dispositivo_substituido.fim_vigencia = None
ndsq.dispositivo_substituido.fim_eficacia = None
ndsq.dispositivo_substituido.save()
ndsq.dispositivo_substituido = nd
ndsq.save()
nd.ta_publicado = nda.ta if nda else None
super(DispositivoEdicaoAlteracaoForm, self).save()
if nd.dispositivo_subsequente:
nd.fim_vigencia = nd.dispositivo_subsequente.inicio_vigencia - \
timedelta(days=1)
nd.fim_eficacia = nd.dispositivo_subsequente.inicio_eficacia - \
timedelta(days=1)
nd.save()

36
compilacao/migrations/0045_auto_20160311_1117.py

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-03-11 14:17
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0044_auto_20160307_0918'),
]
operations = [
migrations.AlterField(
model_name='dispositivo',
name='dispositivo_subsequente',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='compilacao.Dispositivo', verbose_name='Dispositivo Subsequente'),
),
migrations.AlterField(
model_name='dispositivo',
name='dispositivo_substituido',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='compilacao.Dispositivo', verbose_name='Dispositivo Substituido'),
),
migrations.AlterField(
model_name='dispositivo',
name='inconstitucionalidade',
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Declaração de Inconstitucionalidade'),
),
migrations.AlterField(
model_name='dispositivo',
name='texto',
field=models.TextField(blank=True, default='', verbose_name='Texto na Norma Original'),
),
]

25
compilacao/migrations/0046_auto_20160319_1542.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-03-19 18:42
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0045_auto_20160311_1117'),
]
operations = [
migrations.AlterField(
model_name='dispositivo',
name='inconstitucionalidade',
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Declarado Inconstitucional'),
),
migrations.AlterField(
model_name='dispositivo',
name='texto',
field=models.TextField(blank=True, default='', verbose_name='Texto Original'),
),
]

21
compilacao/migrations/0047_auto_20160330_0027.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-03-30 03:27
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0046_auto_20160319_1542'),
]
operations = [
migrations.AlterField(
model_name='dispositivo',
name='dispositivo_vigencia',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dispositivos_vigencias_set', to='compilacao.Dispositivo', verbose_name='Dispositivo de Vigência'),
),
]

21
compilacao/migrations/0048_auto_20160404_2309.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-04-05 02:09
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0047_auto_20160330_0027'),
]
operations = [
migrations.AlterField(
model_name='dispositivo',
name='dispositivo_vigencia',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dispositivos_vigencias_set', to='compilacao.Dispositivo', verbose_name='Dispositivo de Vigência'),
),
]

16
compilacao/migrations/0049_merge.py

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-04-06 17:43
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('compilacao', '0045_auto_20160404_1411'),
('compilacao', '0048_auto_20160404_2309'),
]
operations = [
]

113
compilacao/models.py

@ -1,4 +1,3 @@
from datetime import datetime
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericForeignKey
@ -59,6 +58,17 @@ class BaseModel(models.Model):
self.__class__, tuple(unique_fields))
raise ValidationError(msg)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None, clean=True):
if clean:
self.clean()
return models.Model.save(
self,
force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields)
class TipoTextoArticulado(models.Model):
sigla = models.CharField(max_length=3, verbose_name=_('Sigla'))
@ -124,6 +134,24 @@ class TextoArticulado(TimestampedMixin):
'numero': self.numero,
'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")}
def organizar_ordem_de_dispositivos(self):
dpts = Dispositivo.objects.filter(ta=self)
if not dpts.exists():
return
ordem_max = dpts.last().ordem
dpts.update(ordem=F('ordem') + ordem_max)
dpts = Dispositivo.objects.filter(
ta=self).values_list('pk', flat=True).order_by('ordem')
count = 0
for d in dpts:
count += Dispositivo.INTERVALO_ORDEM
Dispositivo.objects.filter(pk=d).update(ordem=count)
class TipoNota(models.Model):
sigla = models.CharField(
@ -532,7 +560,7 @@ class Dispositivo(BaseModel, TimestampedMixin):
texto = models.TextField(
blank=True,
default='',
verbose_name=_('Texto'))
verbose_name=_('Texto Original'))
texto_atualizador = models.TextField(
blank=True,
default='',
@ -551,7 +579,7 @@ class Dispositivo(BaseModel, TimestampedMixin):
inconstitucionalidade = models.BooleanField(
default=False,
choices=utils.YES_NO_CHOICES,
verbose_name=_('Inconstitucionalidade'))
verbose_name=_('Declarado Inconstitucional'))
# Relevant attribute only in altering norms
visibilidade = models.BooleanField(
default=False,
@ -581,11 +609,13 @@ class Dispositivo(BaseModel, TimestampedMixin):
'self',
blank=True, null=True, default=None,
related_name='+',
on_delete=models.SET_NULL,
verbose_name=_('Dispositivo Subsequente'))
dispositivo_substituido = models.ForeignKey(
'self',
blank=True, null=True, default=None,
related_name='+',
on_delete=models.SET_NULL,
verbose_name=_('Dispositivo Substituido'))
dispositivo_pai = models.ForeignKey(
'self',
@ -595,7 +625,8 @@ class Dispositivo(BaseModel, TimestampedMixin):
dispositivo_vigencia = models.ForeignKey(
'self',
blank=True, null=True, default=None,
related_name='+',
on_delete=models.SET_NULL,
related_name='dispositivos_vigencias_set',
verbose_name=_('Dispositivo de Vigência'))
dispositivo_atualizador = models.ForeignKey(
'self',
@ -702,10 +733,26 @@ class Dispositivo(BaseModel, TimestampedMixin):
'º' if
self.tipo_dispositivo.
rotulo_ordinal >= 0 else '',)
elif irmaos_mesmo_tipo.count() == 1 and\
irmaos_mesmo_tipo[0].dispositivo0 == 0 and\
self.dispositivo0 == 1:
irmao = irmaos_mesmo_tipo[0]
irmao.dispositivo0 = 1
rr = prefixo[0]
rr += irmao.get_nomenclatura_completa()
irmao.rotulo = rr + t.rotulo_sufixo_texto
irmao.save()
r += prefixo[0]
self.dispositivo0 = 2
r += self.get_nomenclatura_completa()
else:
r += prefixo[0]
r += self.get_nomenclatura_completa()
else:
if self.dispositivo0 == 0:
self.dispositivo0 = 1
r += prefixo[0]
r += self.get_nomenclatura_completa()
@ -777,6 +824,27 @@ class Dispositivo(BaseModel, TimestampedMixin):
return (flag_direcao, flag_variacao)
def transform_in_prior(self, profundidade=-1):
numero = self.get_numero_completo()
numero.reverse()
if profundidade != -1:
profundidade = len(numero) - profundidade - 1
for i in range(len(numero)):
if not numero[i]:
continue
if i > profundidade:
continue
numero[i] -= 1
break
numero.reverse()
self.set_numero_completo(numero)
def set_numero_completo(self, *numero):
numero = numero[0]
self.dispositivo0 = numero[0]
@ -913,7 +981,7 @@ class Dispositivo(BaseModel, TimestampedMixin):
def get_parents(self, ordem='desc'):
dp = self
p = []
while dp.dispositivo_pai is not None:
while dp.dispositivo_pai:
dp = dp.dispositivo_pai
if ordem == 'desc':
p.append(dp)
@ -925,7 +993,7 @@ class Dispositivo(BaseModel, TimestampedMixin):
def get_parents_asc(self):
return self.get_parents(ordem='asc')
def incrementar_irmaos(self, variacao=0, tipoadd=[]):
def incrementar_irmaos(self, variacao=0, tipoadd=[], force=True):
if not self.tipo_dispositivo.contagem_continua:
irmaos = list(Dispositivo.objects.filter(
@ -956,6 +1024,10 @@ class Dispositivo(BaseModel, TimestampedMixin):
dp_profundidade = self.get_profundidade()
if (not force and not variacao and len(irmaos) > 0 and
irmaos[0].get_numero_completo() > self.get_numero_completo()):
return
irmaos_a_salvar = []
ultimo_irmao = None
for irmao in irmaos:
@ -1029,15 +1101,18 @@ class Dispositivo(BaseModel, TimestampedMixin):
irmao.save()
def get_proximo_nivel_zero(self):
proxima_articulacao = Dispositivo.objects.filter(
proxima_articulacao = Dispositivo.objects.order_by('ordem').filter(
ordem__gt=self.ordem,
nivel=0,
ta_id=self.ta_id)[:1]
ta_id=self.ta_id).first()
return proxima_articulacao
if not proxima_articulacao.exists():
return None
return proxima_articulacao[0]
def get_nivel_zero_anterior(self):
anterior_articulacao = Dispositivo.objects.order_by('ordem').filter(
ordem__lt=self.ordem,
nivel=0,
ta_id=self.ta_id).last()
return anterior_articulacao
def is_relative_auto_insert(self, perfil_pk=None):
if self.dispositivo_pai is not None:
@ -1076,10 +1151,20 @@ class Dispositivo(BaseModel, TimestampedMixin):
dp.texto = ''
dp.ta = dispositivo_base.ta
dp.dispositivo_pai = dispositivo_base.dispositivo_pai
dp.publicacao = dispositivo_base.publicacao
dp.dispositivo_vigencia = dispositivo_base.dispositivo_vigencia
if dp.dispositivo_vigencia:
dp.inicio_eficacia = dp.dispositivo_vigencia.inicio_eficacia
dp.inicio_vigencia = dp.dispositivo_vigencia.inicio_vigencia
dp.fim_eficacia = dp.dispositivo_vigencia.fim_eficacia
dp.fim_vigencia = dp.dispositivo_vigencia.fim_vigencia
else:
dp.inicio_eficacia = dispositivo_base.inicio_eficacia
dp.inicio_vigencia = dispositivo_base.inicio_vigencia
dp.publicacao = dispositivo_base.publicacao
dp.timestamp = datetime.now()
dp.fim_eficacia = dispositivo_base.inicio_eficacia
dp.fim_vigencia = dispositivo_base.fim_vigencia
dp.ordem = dispositivo_base.ordem
return dp

132
compilacao/templatetags/compilacao_filters.py

@ -1,9 +1,11 @@
from django import template
from django.core.signing import Signer
from django.db.models import Q
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from compilacao.models import Dispositivo, TipoDispositivo
from compilacao.models import Dispositivo
register = template.Library()
@ -15,13 +17,6 @@ def get_bloco_atualizador(pk_atualizador):
Q(dispositivo_atualizador_id=pk_atualizador)).select_related()
@register.filter
def get_tipos_dispositivo(pk_atual):
return TipoDispositivo.objects.filter(
id__gte=pk_atual)
@register.simple_tag
def dispositivo_desativado(dispositivo, inicio_vigencia, fim_vigencia):
if inicio_vigencia and fim_vigencia:
@ -38,17 +33,23 @@ def dispositivo_desativado(dispositivo, inicio_vigencia, fim_vigencia):
@register.simple_tag
def nota_automatica(dispositivo, ta_pub_list):
if dispositivo.ta_publicado is not None:
d = dispositivo.dispositivo_atualizador.dispositivo_pai
ta_publicado = ta_pub_list[dispositivo.ta_publicado_id] if\
ta_pub_list else dispositivo.ta_publicado
if dispositivo.texto == Dispositivo.TEXTO_PADRAO_DISPOSITIVO_REVOGADO:
return _('Revogado pelo %s - %s.') % (
d, ta_pub_list[dispositivo.ta_publicado_id])
d, ta_publicado)
elif not dispositivo.dispositivo_substituido_id:
return _('Inclusão feita pelo %s - %s.') % (
d, ta_pub_list[dispositivo.ta_publicado_id])
d, ta_publicado)
else:
return _('Alteração feita pelo %s - %s.') % (
d, ta_pub_list[dispositivo.ta_publicado_id])
d, ta_publicado)
return ''
@ -60,12 +61,15 @@ def set_nivel_old(view, value):
@register.simple_tag
def close_div(value_max, value_min, varr):
return '</div>' * (int(value_max) - int(value_min) + 1 + varr)
return mark_safe('</div>' * (int(value_max) - int(value_min) + 1 + varr))
@register.filter
def get_sign_vigencia(value):
string = "%s,%s" % (value.inicio_vigencia, value.fim_vigencia)
string = "%s,%s,%s" % (
value.ta_publicado_id if value.ta_publicado_id else 0,
value.inicio_vigencia,
value.fim_vigencia)
signer = Signer()
return signer.sign(str(string))
@ -89,7 +93,7 @@ def isinst(value, class_str):
@register.filter
def render_actions_head(view, d_atual):
if view.__class__.__name__ != 'DispositivoEditView':
if view.__class__.__name__ != 'DispositivoSimpleEditView':
return False
# Menu
@ -121,8 +125,96 @@ def nomenclatura(d):
result = '(' + d.tipo_dispositivo.nome + ' ' + \
d.rotulo + ')'
else:
result = '(' + d.tipo_dispositivo.nome + \
d.rotulo_padrao() + ')'
r = d.rotulo_padrao()
if r:
r += ' '
result = '(' + d.tipo_dispositivo.nome + r + ')'
return result
def update_dispositivos_parents(dpts_parents, ta_id):
dpts = Dispositivo.objects.order_by('ordem').filter(
ta_id=ta_id).values_list(
'pk', 'dispositivo_pai_id', 'rotulo', 'tipo_dispositivo__nome',
'tipo_dispositivo__rotulo_prefixo_texto')
for d in dpts:
dpts_parents[str(d[0])] = {
'd': d, 'p': [], 'h': None}
def parents(k):
pai = dpts_parents[str(k)]['d'][1]
p = dpts_parents[str(k)]['p']
if not p:
if pai:
parent_k = [pai, ] + parents(pai)
else:
parent_k = []
else:
parent_k = p
return parent_k
for k in dpts_parents:
dpts_parents[str(k)]['p'] = parents(k)
@register.simple_tag
def heranca(request, d, ignore_ultimo=0, ignore_primeiro=0):
ta_dpts_parents = request.session.get('herancas')
if not ta_dpts_parents:
ta_dpts_parents = {}
ta_id = str(d.ta_id)
if ta_id not in ta_dpts_parents:
dpts_parents = {}
ta_dpts_parents[ta_id] = dpts_parents
update_dispositivos_parents(dpts_parents, ta_id)
herancas_fila = request.session.get('herancas_fila')
if not herancas_fila:
herancas_fila = []
herancas_fila.append(ta_id)
if len(herancas_fila) > 100:
ta_remove = herancas_fila.pop(0)
del ta_dpts_parents[str(ta_remove)]
request.session['herancas_fila'] = herancas_fila
request.session['herancas'] = ta_dpts_parents
d_pk = str(d.pk)
h = ta_dpts_parents[ta_id][d_pk]['h']
if h:
return h
dpts_parents = ta_dpts_parents[ta_id]
parents = dpts_parents[d_pk]['p']
result = ''
if parents:
pk_last = parents[-1]
for pk in parents:
if ignore_ultimo and pk == pk_last:
break
if ignore_primeiro:
ignore_primeiro = 0
continue
p = dpts_parents[str(pk)]['d']
if p[4] != '':
result = p[2] + ' ' + result
else:
result = '(' + p[3] + ' ' + \
p[2] + ')' + ' ' + result
dpts_parents[d_pk]['h'] = result
return result
@ -154,4 +246,10 @@ def nomenclatura_heranca(d, ignore_ultimo=0, ignore_primeiro=0):
@register.filter
def urldetail_content_type(obj):
return '%s:detail' % obj.content_type.model
return '%s:%s_detail' % (
obj.content_type.app_label, obj.content_type.model)
@register.filter
def list(obj):
return [obj, ]

29
compilacao/urls.py

@ -31,12 +31,25 @@ urlpatterns_compilacao = [
views.DispositivoView.as_view(), name='dispositivo'),
url(r'^(?P<ta_id>[0-9]+)/text/(?P<dispositivo_id>[0-9]+)/refresh',
views.DispositivoEditView.as_view(), name='dispositivo_edit'),
views.DispositivoSimpleEditView.as_view(), name='dispositivo_refresh'),
url(r'^(?P<ta_id>[0-9]+)/text/(?P<dispositivo_id>[0-9]+)/actions',
views.ActionsEditView.as_view(), name='dispositivo_actions'),
url(r'^(?P<ta_id>[0-9]+)/text/(?P<pk>[0-9]+)/edit$',
views.DispositivoEdicaoBasicaView.as_view(), name='dispositivo_edit'),
url(r'^(?P<ta_id>[0-9]+)/text/(?P<pk>[0-9]+)/edit/vigencia',
views.DispositivoEdicaoVigenciaView.as_view(),
name='dispositivo_edit_vigencia'),
url(r'^(?P<ta_id>[0-9]+)/text/(?P<pk>[0-9]+)/edit/alteracao',
views.DispositivoEdicaoAlteracaoView.as_view(),
name='dispositivo_edit_alteracao'),
url(r'^(?P<ta_id>[0-9]+)/text/(?P<pk>[0-9]+)/edit/definidor_vigencia',
views.DispositivoDefinidorVigenciaView.as_view(),
name='dispositivo_edit_definidor_vigencia'),
url(r'^(?P<ta_id>[0-9]+)/text/(?P<dispositivo_id>[0-9]+)/actions',
views.ActionsEditView.as_view(), name='dispositivo_actions'),
url(r'^(?P<ta_id>[0-9]+)/text/'
'(?P<dispositivo_id>[0-9]+)/nota/create$',
@ -62,9 +75,13 @@ urlpatterns_compilacao = [
'(?P<dispositivo_id>[0-9]+)/vide/(?P<pk>[0-9]+)/delete$',
views.VideDeleteView.as_view(), name='vide_delete'),
url(r'^(?P<ta_id>[0-9]+)/text/search$',
url(r'^search_fragment_form$',
views.DispositivoSearchFragmentFormView.as_view(),
name='search_dispositivo'),
name='dispositivo_fragment_form'),
url(r'^search_form$',
views.DispositivoSearchModalView.as_view(),
name='dispositivo_search_form'),
url(r'^(?P<ta_id>[0-9]+)/publicacao$',
@ -94,7 +111,7 @@ urlpatterns_compilacao = [
]
urlpatterns = [
url(r'^ta/', include(urlpatterns_compilacao, 'compilacao', 'compilacao')),
url(r'^ta/', include(urlpatterns_compilacao)),
url(r'^ta/config/tipo-nota/',
include(TipoNotaCrud.get_urls())),

15
compilacao/utils.py

@ -1,4 +1,17 @@
DISPOSITIVO_SELECT_RELATED = (
'tipo_dispositivo',
'ta_publicado',
'ta',
'dispositivo_atualizador',
'dispositivo_atualizador__dispositivo_pai',
'dispositivo_atualizador__dispositivo_pai__ta',
'dispositivo_atualizador__dispositivo_pai__ta__tipo_ta',
'dispositivo_pai',
'dispositivo_pai__tipo_dispositivo',
'ta_publicado',
'ta',)
def int_to_roman(int_value):
# if isinstance(int_value, type(1)):
@ -18,6 +31,8 @@ def int_to_roman(int_value):
def int_to_letter(int_value):
result = ''
if not int_value:
return '0'
int_value -= 1
while int_value >= 26:
rest = int_value % 26

1700
compilacao/views.py

File diff suppressed because it is too large

4
crispy_layout_mixin.py

@ -39,10 +39,10 @@ def form_actions(more=[], save_label=_('Salvar')):
class SaplFormLayout(Layout):
def __init__(self, *fields):
def __init__(self, *fields, label_cancel=_('Cancelar')):
buttons = form_actions(more=[
HTML('<a href="{{ view.cancel_url }}"'
' class="btn btn-inverse">%s</a>' % _('Cancelar'))])
' class="btn btn-inverse">%s</a>' % label_cancel)])
_fields = list(to_fieldsets(fields)) + [to_row([(buttons, 12)])]
super(SaplFormLayout, self).__init__(*_fields)

2
norma/urls.py

@ -19,7 +19,7 @@ app_name = AppConfig.name
# url(r'^norma/(?P<pk>[0-9]+)/ta$', NormaTaView.as_view(), name='ta')
# bem como a classe NormaTaView que está em norma.views
norma_url_patterns = NormaTemporarioCrud.get_urls() + [
url(r'^norma/(?P<pk>[0-9]+)/ta$',
url(r'^(?P<pk>[0-9]+)/ta$',
NormaTaView.as_view(), name='ta')
]

32
static/js/app.js

@ -1,8 +1,31 @@
function initTinymce(elements) {
removeTinymce();
var config_tinymce = {
force_br_newlines : false,
force_p_newlines : false,
forced_root_block : '',
plugins: ["table save code"],
menubar: "edit format table tools",
toolbar: "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent",
tools: "inserttable",
border_css: "/static/styles/style_tinymce.css",
content_css: "/static/styles/style_tinymce.css",
}
if (elements != null) {
config_tinymce['elements'] = elements;
config_tinymce['mode'] = "exact";
}
else
config_tinymce['mode'] = "textareas";
tinymce.init({
mode : "exact",
elements : "biografia-parlamentar,casa-informacoes"
});
tinymce.init(config_tinymce);
}
function removeTinymce() {
while (tinymce.editors.length > 0) {
tinymce.remove(tinymce.editors[0]);
}
}
function refreshDatePicker() {
$.datepicker.setDefaults($.datepicker.regional['pt-BR']);
@ -96,4 +119,5 @@ $(document).ready(function(){
refreshDatePicker();
refreshMask();
autorModal();
initTinymce("biografia-parlamentar,casa-informacoes");
});

225
static/js/compilacao.js

@ -1,20 +1,3 @@
function initTinymce() {
tinymce.init({
mode : "textareas",
force_br_newlines : false,
force_p_newlines : false,
forced_root_block : '',
plugins: ["table save code"],
menubar: "edit format table tools",
toolbar: "save | undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent",
tools: "inserttable",
save_onsavecallback: onSubmitEditForm,
border_css: "/static/styles/compilacao_tinymce.css",
content_css: "/static/styles/compilacao_tinymce.css"
});
}
function SetCookie(cookieName,cookieValue,nDays) {
var today = new Date();
var expire = new Date();
@ -38,3 +21,211 @@ function insertWaitAjax(element) {
//jQuery(element).append('<div style="text-align:center;"><img src="/static/img/ajax-loader.gif"></div>');
jQuery(element).append('<div style="text-align:center;"><i style="font-size: 200%;"class="fa fa-refresh fa-spin"></i></div>');
}
function DispostivoSearch(opts) {
$(function() {
var container_ds = $('body').children("#container_ds");
if (container_ds.length > 0)
$(container_ds).remove();
container_ds = $('<div id="container_ds"/>');
$('body').prepend(container_ds);
var fields = $("[data-sapl-ta='DispositivoSearch']");
fields.each(function() {
var field = $(this);
var data_type_selection = field.attr('data-type-selection');
var data_field = field.attr('data-field');
var data_function = field.attr('data-function');
var onChangeFieldSelects = function(event) {
if (data_type_selection == 'checkbox') {
var tas = field.find('input[name="ta_select_all"]'); //tas - Textos Articulados
tas.off();
tas.on('change', function(event) {
$(this).closest('ul').find('input[name="'+data_field+'"]').prop("checked", this.checked);
//$(this).prop("checked", false);
});
}
else {
var dpts = field.find('input');
dpts.off()
dpts.attr('type', 'hidden');
$('<a class="text-danger" href="#">')
.insertBefore(dpts)
.append($('<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>'))
.on('click', function() {
if ($(this).closest('ul').find('li').length == 2)
$(this).closest('ul').remove();
else
$(this).closest('li').remove();
});
}
}
onChangeFieldSelects();
var onChangeParamTA = function(event) {
var tipo_ta = $("select[name='tipo_ta']").val();
var tipo_model = $("select[name='tipo_model']").val();
var num_ta = $("input[name='num_ta']").val();
var ano_ta = $("input[name='ano_ta']").val();
var dispositivos_internos = $("input[name='dispositivos_internos']:checked").val();
var rotulo_dispositivo = $("input[name='rotulo_dispositivo']").val();
var texto_dispositivo = $("input[name='texto_dispositivo']").val();
var max_results = $("select[name='max_results']").val();
var url = '';
if (rotulo_dispositivo.length > 0 || texto_dispositivo.length > 0) {
$("input[name='dispositivos_internos']").prop('disabled', false);
$("input[name='dispositivos_internos']").closest('#div_id_dispositivos_internos').css('opacity','1');
}
else {
$("input[name='dispositivos_internos']").filter('[value="False"]').prop('checked', true);
$("input[name='dispositivos_internos']").prop('disabled', true);
$("input[name='dispositivos_internos']").closest('#div_id_dispositivos_internos').css('opacity','0.3');
dispositivos_internos = 'False';
}
var formData = {
'tipo_ta' : tipo_ta,
'tipo_model' : tipo_model,
'num_ta' : num_ta,
'ano_ta' : ano_ta,
'texto' : texto_dispositivo,
'rotulo' : rotulo_dispositivo,
'dispositivos_internos' : dispositivos_internos,
'max_results' : max_results,
'data_type_selection' : data_type_selection,
'data_field' : data_field,
'data_function' : data_function,
};
url = '/ta/search_fragment_form';
$('.result-busca-dispositivo').html('');
insertWaitAjax('.result-busca-dispositivo')
$.get(url, formData).done(function( data ) {
$('.result-busca-dispositivo').html(data);
if (data_type_selection == 'checkbox') {
var tas = $('.result-busca-dispositivo').find('input[name="ta_select_all"]');
tas.off();
tas.on('change', function(event) {
$(this).closest('ul').find('input[name="'+data_field+'"]').prop("checked", this.checked);
});
}
});
}
var onKeyPressRotuloBuscaTextual = function(event) {
var rotulo_dispositivo = $("input[name='rotulo_dispositivo']").val();
var texto_dispositivo = $("input[name='texto_dispositivo']").val();
var dispositivos_internos = $("input[name='dispositivos_internos']:checked").val();
if (rotulo_dispositivo.length > 0 || texto_dispositivo.length > 0) {
$("input[name='dispositivos_internos']").prop('disabled', false);
$("input[name='dispositivos_internos']").closest('#div_id_dispositivos_internos').css('opacity','1');
}
else {
$("input[name='dispositivos_internos']").filter('[value="False"]').prop('checked', true);
$("input[name='dispositivos_internos']").prop('disabled', true);
$("input[name='dispositivos_internos']").closest('#div_id_dispositivos_internos').css('opacity','0.3');
dispositivos_internos = 'False';
}
}
var button_ds = field.children("#button_ds");
if (button_ds.length > 0)
$(button_ds).remove();
button_ds = $('<div id="button_ds" class="clearfix"/>');
field.prepend(button_ds);
var btn_open_search = $('<button>')
.text(opts['text_button'])
.attr('type','button')
.attr('class','btn btn-sm btn-modal-open');
button_ds.append(btn_open_search);
btn_open_search.on('click', function() {
$.get(opts['url_form'], function(data) {
container_ds.html(data);
var modal_ds = $('#modal-ds');
modal_ds.find("select[name='tipo_ta']").change(function(event) {
var url = '';
url = '/ta/search_fragment_form?action=get_tipos&tipo_ta='+this.value;
modal_ds.find("label[for='id_tipo_model']").html('Tipos de ' + this.children[this.selectedIndex].innerHTML);
var select = modal_ds.find("select[name='tipo_model']");
select.empty();
$('<option value="">Carregando...</option>').appendTo(select);
$.get(url).done(function( data ) {
select.empty();
for(var item in data) {
for (var i in data[item])
select.append($("<option>").attr('value',i).text(data[item][i]));
}
//select.change(onChangeParamTA)
});
});
/*modal_ds.find("input[name='num_ta'], "
+"input[name='ano_ta'], "
+"select[name='tipo_model'], "
+"input[name='texto_dispositivo'], "
+"input[name='dispositivos_internos'], "
+"input[name='rotulo_dispositivo']"
).change(onChangeParamTA);*/
modal_ds.find("input[name='texto_dispositivo'], "
+"input[name='rotulo_dispositivo']")
.on('keyup', onKeyPressRotuloBuscaTextual)
modal_ds.find(".btn-busca").click(onChangeParamTA);
modal_ds.find("#btn-modal-select").click(function() {
// limpar selecionados se o tipo é radio
var listas = field.find('ul');
if (data_type_selection == 'radio')
listas.remove();
// adicionar itens selecionados na caixa modal
var selecionados = modal_ds.find('[name="'+data_field+'"]:checked');
// com base nos selecionados, limpa seus ta's removendo os não selecionados
selecionados.closest('ul').find('input:not(:checked)').filter('[name!="ta_select_all"]').closest('li').remove();
selecionados.closest('ul').each(function() {
//insere na lista de selecionados os ta's não presentes
var ul_lista = field.find('#'+this.id);
if (ul_lista.length == 0) {
field.append(this);
return;
}
//insere os dispositivos não presentes
var inputs_for_this = $(this).find('input');
inputs_for_this.each(function() {
if (ul_lista.find("#"+this.id).length > 0)
return;
ul_lista.append($(this).closest('li'));
});
});
onChangeFieldSelects();
modal_ds.modal('hide');
});
modal_ds.modal('show');
onChangeParamTA();
})
});
});
});
}

65
static/js/compilacao_edit.js

@ -95,7 +95,6 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
}
}
url = pk_refresh+'/refresh?edit='+pk_edit+url;
}
else if (_action.startsWith('add_')) {
@ -105,12 +104,16 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
$("#message_block").css("display", "block");
}
else if (_action.startsWith('set_')) {
url = pk_refresh+'/actions?action='+_action;
$("#message_block").css("display", "block");
}
else if (_action.startsWith('delete_')) {
var r = confirm("Confirma Exclusão deste dispositivo?");
if (r == true) {
x = "You pressed OK!";
} else {
if (!r) {
return
}
url = pk_refresh+'/actions?action='+_action;
@ -166,19 +169,19 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
if (flag_actions_vibible == null || flag_actions_vibible) {
$('#dpt'+pk_edit).addClass('dpt-selected');
try {
$('html, body').animate({
scrollTop: $('#dpt' + pk_edit ).offset().top - window.innerHeight / 9
}, 0);
}, 100);
}
catch(err) {
}
}
}
else if (_action == 'add_next' || _action == 'add_in') {
clearEditSelected();
if (data.pk != null) {
if (data.alert != null)
alert(data.alert)
refreshScreenFocusPk(data);
}
else {
@ -189,32 +192,60 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
$("#message_block").css("display", "block");
clearEditSelected();
if (data.pk != null) {
if (!modalMessage(data.message, 'alert-danger', function() {
//refreshScreenFocusPk(data);
}))
refreshScreenFocusPk(data);
}
else {
alert('Erro exclusão!');
alert('Erro exclusão de Dispositivo!');
}
}
else {
clearEditSelected();
reloadFunctionClicks();
modalMessage(data.message, 'alert-success', null);
}
}).always(function() {
$("#message_block").css("display", "none");
});
}
function refreshScreenFocusPk(data) {
function modalMessage(message, alert, closeFunction) {
if (message != null && message != '') {
$('#modal-message #message').html(message);
$('#modal-message').modal('show');
$('#modal-message, #modal-message .alert button').off();
$('#modal-message .alert').removeClass('alert-success alert-info alert-warning alert-danger alert-danger');
$('#modal-message .alert').addClass(alert);
if (closeFunction != null)
$('#modal-message').on('hidden.bs.modal', closeFunction);
for (var pai = 0; pai < data.pai.length; pai++)
if (data.pai[pai] != -1) {
clickUpdateDispositivo(null, data.pai[pai], data.pk, 'refresh', pai == 0, true);
$('#modal-message .alert button').on('click', function() {
$('#modal-message').modal('hide');
});
return true;
}
else {
return false;
}
function refreshScreenFocusPk(data) {
if (data.pai[0] == -1) {
$("#message_block").css("display", "block");
href = location.href.split('#')[0]
location.href = href+'#'+data.pk
location.href = href+'#'+data.pk;
location.reload(true)
}
else {
clickUpdateDispositivo(null, data.pai[0], data.pk, 'refresh', true, true);
setTimeout(function() {
for (var pai = 1; pai < data.pai.length; pai++)
clickUpdateDispositivo(null, data.pai[pai], data.pk, 'refresh', false, true);
}, 1000);
}
}
function clearEditSelected() {
@ -250,7 +281,7 @@ $(document).ready(function() {
$("#message_block").css("display", "none");
href = location.href.split('#')
if (href.length == 2) {
if (href.length == 2 && href[1] != '') {
clickUpdateDispositivo(null, href[1], href[1], 'refresh', true);
}

70
static/js/compilacao_notas.js

@ -5,9 +5,9 @@ function onEventsDneExec(pk, model) {
scrollTop: $('#dne' + pk ).offset().top - window.innerHeight / 5
}, 300);
refreshDatePicker()
refreshDatePicker();
$('#dne'+pk+" #button-id-submit-form").click(onSubmitEditForm);
$('#dne'+pk+" #button-id-submit-form").click(onSubmitEditNVForm);
$('#dne'+pk+" .btn-close-container").click(function(){
$(this).closest('.dne-nota').removeClass('dne-nota');
$(this).closest('.dne-form').html('');
@ -23,72 +23,14 @@ function onEventsDneExec(pk, model) {
});
}
else if (model == 'vide') {
$('#dne'+pk+" select[name='tipo_ta']").change(function(event) {
var url = '';
url = 'text/'+pk+'/vide/create?action=get_tipos&tipo_ta='+this.value;
$('#dne'+pk+" label[for='id_tipo_model']").html('Tipos de ' + this.children[this.selectedIndex].innerHTML);
var select = $('#dne'+pk+" select[name='tipo_model']");
select.empty();
$('<option value="">Carregando...</option>').appendTo(select);
$.get(url).done(function( data ) {
select.empty();
for(var item in data) {
for (var i in data[item])
$('<option value="'+i+'">'+data[item][i]+'</option>').appendTo(select);
}
});
});
$('#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);
configFormSearchTA('#dne'+pk, 'radio', 'select_for_vide');
onChangeParamNorma();
onChangeParamTA();
}
}
var onChangeParamNorma = function(event) {
var tipo_ta = $("select[name='tipo_ta']").val();
var tipo_model = $("select[name='tipo_model']").val();
var num_ta = $("input[name='num_ta']").val();
var ano_ta = $("input[name='ano_ta']").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_ta']").closest('.dne').attr('pk')
var formData = {
'tipo_ta' : tipo_ta,
'tipo_model' : tipo_model,
'num_ta' : num_ta,
'ano_ta' : ano_ta,
'busca' : busca_dispositivo,
'tipo_form' : 'radio',
'initial_ref' : dispositivo_ref
};
url = 'text/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 onSubmitEditNVForm = function(event) {
var url = '';
var model = 'nota';
@ -126,9 +68,7 @@ var onSubmitEditForm = function(event) {
}, 300);
}
catch(err) {
console.log(err.message);
}
}
}
}

8
static/js/compilacao_view.js

@ -1,11 +1,3 @@
$( window ).scroll(function() {
if (window.pageYOffset <= 180)
$( "section.vigencias" ).removeClass("fixed");
else if ( ! $( "section.vigencias" ).hasClass("fixed") )
$( "section.vigencias" ).addClass("fixed");
});
function isElementInViewport (el) {
//special bonus for those using jQuery

17
static/styles/app.scss

@ -120,3 +120,20 @@ body {
.checkbox input, .radio input {
display: initial;
}
.modal {
.alert {
margin-bottom: 0;
}
}
fieldset {
fieldset {
font-size: 95%;
legend {
font-size: 18px;
}
}
}

411
static/styles/compilacao.scss

@ -143,7 +143,9 @@ a:link:after, a:visited:after {
.cp {
.desativado, .desativado * {
.desativado {
.dtxt, .dtxt * {
text-decoration: line-through;
color: #999 !important;
@ -151,6 +153,7 @@ a:link:after, a:visited:after {
border: 1px dotted #ccc;
}
}
}
a {
text-decoration: none;
@ -172,9 +175,8 @@ a:link:after, a:visited:after {
transition: all 0.2s ease-in-out;
position: relative;
.ementa {
padding: 4em 0em 3em 35%;
padding: 2em 0em 2em 35%;
font-weight: bold;
}
@ -261,7 +263,6 @@ a:link:after, a:visited:after {
}
.bloco_alteracao {
padding-left: 10%;
font-style: italic;
@ -399,6 +400,8 @@ a:link:after, a:visited:after {
transform-origin: right;
transition: all 0.3s ease;
border-top: 1px solid $color_buttons;
ul.btns-action {
list-style: none;
padding: 0;
@ -435,62 +438,6 @@ a:link:after, a:visited:after {
margin: 1em -2em 0em;
text-align: left;
font-size: 1.6rem;
.container-busca {
ul{
list-style: none;
display: table;
margin-left: 0;
border-collapse:separate;
border-spacing:1px;
padding: 0px;
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%;
label {
line-height: 1;
font-family: "SourceSansPro", Helvetica, Arial, sans-serif;
}
}
}
}
.ta_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;
}
}
}
}
@ -505,166 +452,10 @@ a:link:after, a:visited:after {
transition-delay: 0s;
}
}
.dne-nota111 {
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);
position: relative;
transform: scaleX(1);
height: auto;
left: 0;
right: 0;
margin: 1em 0 2em 0;
padding: 0em;
border: 0px;
z-index: 19;
ul.btns-action {
display: none;
}
.dne-form111 {
.asterisk {
color: transparent;
&::before {
color: red;
content: "\2b25";
padding: 0 0.333em;
vertical-align: super;
}
}
.title_form {
font-size: 2.5em;
padding: 0.5em 0.3em 0.3em;
background: #e5e5e5;
color: #777;
margin-bottom: 0.4em;
border-bottom: 1px solid #aaa;
}
fieldset {
border: 0px;
}
select {
background: url(/static/img/down_arrow_select.jpg) no-repeat right #ddd;
border: 0px;
outline:0px;
}
.alert-box {
margin-bottom: 0;
}
.row:first-of-type {
margin-top: 1em;
display: inline-block;
}
.columns {
padding: 0 0.5rem;
}
.input {
border: 0px;
border-bottom: 1px solid #ccc;
margin: 0 0 0 0 ;
padding: 0.5em;
background: #eee;
height: auto;
box-shadow: 0 0 0;
@include placeholder(#777, 1, 100%, normal);
&:focus {
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']{
@extend .input;
font-size:130%;
font-weight: bold;
border-bottom: 0;
@include placeholder(#777, 1, 100%, bold);
&:focus {
background: #fafafa;
@include placeholder(#777, 1, 100%, bold);
}
}
.textarea {
@extend .input;
resize: vertical;
font-weight: normal;
}
.urlinput {
@extend .input;
margin-bottom: 1em;
}
.button {
width: 100%;
margin-top: 1.6em;
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;
}
}
} /* and dpt */
.itemlabel {
display: table-cell;
padding: 0.5em;
vertical-align: middle;
width: 100%;
}
}
}
.ta_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;
}
}
}
}
}
} /* and dpt */
.tipo-vigencias {
list-style: none;
position: fixed;
@ -708,7 +499,16 @@ a:link:after, a:visited:after {
margin-bottom: 15em;
margin-left: 0.8em;
.desativado, .desativado * {
text-decoration: line-through;
color: #999 !important;
table, table td {
border: 1px dotted #ccc;
}
}
a {
text-decoration: none;
@ -723,54 +523,36 @@ a:link:after, a:visited:after {
font-weight: bold;
color: #BFD1F6;
}
.artigo {
float: none;
}
.caput {
margin-top: 0;
}
& > .actions_left {
color: #fff;
left: 0em;
position: absolute;
left: -2.6em;
opacity: 0;
transition: all 0.4s ease-in-out;
z-index: 1;
a {
&.btn-edit {
@include background-top-down(#3498DB, #2980C9);
@include border-radius(7px);
color: #ffffff !important;
font-weight: bold;
padding: 2px 7px 2px 7px;
padding: 5px 7px 3px;
display: inline-block;
line-height: 1;
&:hover {
@include background-top-down(#3cb0fd, #3498DB);
}
}
}
}
&:hover > .actions_left {
opacity: 0.5;
background-color: transparent !important;
&::before {
content: "";
border: inset 0.375rem;
border-color: transparent transparent transparent #3cb0fd;
position: absolute;
display: block;
height: 0;
width: 0;
top: 0.4rem;
right: -0.73rem;
}
&:hover {
opacity: 1;
&::before {
border-color: transparent transparent transparent #3cf0ff;
}
}
}
.bloco {
display: block;
clear: both;
@ -782,26 +564,35 @@ a:link:after, a:visited:after {
}
}
.articulacao {
margin-left: -0.8em;
border-top: 2px solid #e5e5e5;
margin: 2em 0;
}
.bloco_alteracao {
border: 1px solid #ddd;
margin: -1px 0 0;
padding: 1em;
}
.articulacao1 {
margin-top: 2em;
&::before {
content: "Articulação";
background-color: #eee;
border-bottom: 1px solid #aaa;
border-bottom: 1px dotted #E88C8C;
padding: 0.333em;
padding-left: 1em;
display:block;
}
}
.bloco_alteracao {
@extend .articulacao;
margin: 0;
padding-top: 3em;
padding-left: 0em;
background: #ddd;
.bloco_alteracao1 {
@extend .articulacao1;
margin: -1px 0 0;
padding: 1em;
border: 1px dotted #E88C8C;
overflow: hidden;
&::before {
content: "Bloco de Alteração";
margin: -1em -1em 0;
display: block;
}
}
@ -837,16 +628,19 @@ a:link:after, a:visited:after {
a:hover {
background: transparent;
}
}
& > .bloco {
padding: 1em 0;
opacity: 1;
margin: 0 !important;
margin: 1em !important;
}
.bloco_alteracao {
padding-top: 2em;
}
& > .dpt {
padding: 0;
&:last-child {
@ -911,6 +705,7 @@ a:link:after, a:visited:after {
display: table;
li {
display: table-cell;
padding: 0 0.5em;
}
}
@ -993,11 +788,6 @@ a:link:after, a:visited:after {
left: 0em;
}
.actions_inserts {
background: transparent;
position: relative;
@ -1020,9 +810,7 @@ a:link:after, a:visited:after {
text-align: center;
white-space: nowrap;
&.btn-excluir {
text-align: left;
background: #A70808;
color: #c99;
@ -1099,7 +887,6 @@ a:link:after, a:visited:after {
display: block;
position: static;
& > ul {
right: 0.5em;
li {
@ -1188,6 +975,98 @@ a:link:after, a:visited:after {
}
}
.result-busca-dispositivo, .lista-dispositvo {
padding: 0 0 1em;
min-height: 3em;
ul {
list-style: none;
margin: 0;
padding: 1em 0 0;
transition: all 2s linear;
clear: both;
li {
display: table;
border-collapse:separate;
border-bottom: 1px solid white;
&.ta_title {
background-color: rgba(0, 0, 0, 0.15);
border-radius: 4px 4px 0 0;
width: 100%;
span {
padding: 0.5em;
}
}
&:last-child .itemlabel {
border-radius: 0 0 4px 0px;
margin: 0px;
}
&:last-child .iteminput {
border-radius: 0 0 0px 4px;
}
.iteminput {
background-color: rgba(0, 0, 0, 0.1);
border-right: 1px solid white;
display: table-cell;
padding: 0.5em;
vertical-align: middle;
text-align: center;
input {
margin: 0;
}
}
.itemlabel {
background-color: rgba(0, 0, 0, 0.1);
display: table-cell;
padding: 0.5em;
vertical-align: middle;
width: 100%;
label {
line-height: 1;
font-family: "SourceSansPro", Helvetica, Arial, sans-serif;
display: block;
margin: 0px;
}
}
}
}
.nomenclatura_heranca {
font-size: 90%;
color: #057dba;
display: inline;
}
}
.cp-nav-parents {
& > .dropdown-menu {
left: 0;
right: auto;
&::before {
content: '';
position: absolute;
top: -11px;
width: 100%;
height: 11px;
}
}
&:hover {
& > .dropdown-menu {
display: block;
}
}
}
.btn-modal-open {
float: right;
}
.class_color_container {
background: #ddd !important;
@ -1196,7 +1075,7 @@ a:link:after, a:visited:after {
clear:both;
}
.mce-panel {
border: 0px solid #ccc !important;
/*border: 0px solid #ccc !important;*/
}
.mce-btn button:hover {
background-color: rgba(0,0,0,0.1) !important;

2
static/styles/compilacao_tinymce.css → static/styles/style_tinymce.css

@ -1,5 +1,3 @@
.mce-content-body {
font-family: "Open Sans" "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
font-style: normal;

42
templates/compilacao/dispositivo_form.html

@ -0,0 +1,42 @@
{% extends "base.html" %}
{% load i18n crispy_forms_tags compilacao_filters staticfiles sass_tags %}
{% block head_content %}{{block.super}}
<link rel="stylesheet" href="{% sass_src 'styles/compilacao.scss' %}" type="text/css">
{% endblock %}
{% block sections_nav %}
<ul class="nav nav-pills navbar-right">
{% url 'compilacao:dispositivo_edit' object.ta_id object.pk as edit_url%}
{% url 'compilacao:dispositivo_edit_vigencia' object.ta_id object.pk as edit_vigencia_url %}
{% url 'compilacao:dispositivo_edit_alteracao' object.ta_id object.pk as edit_alteracao_url %}
{% url 'compilacao:dispositivo_edit_definidor_vigencia' object.ta_id object.pk as edit_definidor_vigencia_url %}
<li {% if request.get_full_path == edit_url %}class="active"{%endif%}><a class="btn-warning" href="{{ edit_url }}">{% trans 'Dados Básicos' %}</a></li>
<li {% if request.get_full_path == edit_vigencia_url %}class="active"{%endif%}><a class="btn-warning" href="{{ edit_vigencia_url }}" >{% trans 'Vigência' %}</a></li>
<li {% if request.get_full_path == edit_definidor_vigencia_url %}class="active"{%endif%}><a class="btn-danger" href="{{ edit_definidor_vigencia_url }}" >{% trans 'Definidor de Vigência' %}</a></li>
<li {% if request.get_full_path == edit_alteracao_url %}class="active"{%endif%}><a class="btn-danger" href="{{ edit_alteracao_url }}" >{% trans 'Alteração' %}</a></li>
<li><a href="#" class="btn-danger">{% trans 'Alterador' %}</a></li>
</ul>
{% endblock sections_nav %}{% trans '' %}
{% block title %}
<h1><small>{{object.ta}}</small><br>{% trans 'Edição de Dispositivo' %}</h1>
{% endblock%}
{% block base_content %}
<div class="btn-group btn-group-sm" role="group">
{%for parent in object.get_parents_asc %}
{%with node=parent active=False template_name='compilacao/dispositivo_form_parents.html' %}
{%include template_name%}
{%endwith%}
{%endfor %}
{%with node=object active=True template_name='compilacao/dispositivo_form_parents.html' %}
{%include template_name%}
{%endwith%}
</div>
<br><br>
{% crispy form %}
{% endblock %}
{% block extra_js %}
<script type="text/javascript" src="{% static 'js/compilacao.js' %}"></script>
{% endblock %}

12
templates/compilacao/dispositivo_form_alteracao.html

@ -0,0 +1,12 @@
{% extends "compilacao/dispositivo_form.html" %}
{% load i18n %}
{% block extra_js %}{{block.super}}
<script type="text/javascript">
DispostivoSearch({
'url_form': '{% url 'compilacao:dispositivo_search_form'%}',
'text_button': '{% trans 'Definir Dispositivo'%}'
});
initTinymce();
</script>
{% endblock %}

11
templates/compilacao/dispositivo_form_definidor_vigencia.html

@ -0,0 +1,11 @@
{% extends "compilacao/dispositivo_form.html" %}
{% load i18n %}
{% block extra_js %}{{block.super}}
<script type="text/javascript">
DispostivoSearch({
'url_form': '{% url 'compilacao:dispositivo_search_form'%}',
'text_button': '{% trans 'Adicionar Dispositivos'%}'
});
</script>
{% endblock %}

36
templates/compilacao/dispositivo_form_edicao_basica.html

@ -0,0 +1,36 @@
{% extends "compilacao/dispositivo_form.html" %}
{% load i18n %}
{% block extra_js %}{{block.super}}
<script type="text/javascript">
function atualizaRotulo() {
var formData = { // TODO: Simplificar com um laço
'dispositivo0' : $('[name="dispositivo0"]').val(),
'dispositivo1' : $('[name="dispositivo1"]').val(),
'dispositivo2' : $('[name="dispositivo2"]').val(),
'dispositivo3' : $('[name="dispositivo3"]').val(),
'dispositivo4' : $('[name="dispositivo4"]').val(),
'dispositivo5' : $('[name="dispositivo5"]').val(),
'action' : 'atualiza_rotulo'
};
var url = '#';
$.get(url, formData).done(function(data) {
if (data.rotulo != undefined) {
$('[name="rotulo"]').val(data.rotulo);
$('[name="dispositivo0"]').val(data.dispositivo0);
$('[name="dispositivo1"]').val(data.dispositivo1);
$('[name="dispositivo2"]').val(data.dispositivo2);
$('[name="dispositivo3"]').val(data.dispositivo3);
$('[name="dispositivo4"]').val(data.dispositivo4);
$('[name="dispositivo5"]').val(data.dispositivo5);
return;
}
});
}
initTinymce();
</script>
{% endblock %}

31
templates/compilacao/dispositivo_form_parents.html

@ -0,0 +1,31 @@
{% load i18n compilacao_filters %}
{% if not node.dispositivos_filhos_set.exists %}
<a href="{% url view.get_url_this_view node.ta_id node.pk %}" class="btn btn-default {%if active%}btn-primary{%endif%}">
{{node|nomenclatura}}
</a>
{% else %}
<div class="cp-nav-parents btn-group btn-group-sm" role="group">
<a href="{% url view.get_url_this_view node.ta_id node.pk %}" class="btn btn-default {%if active%}btn-primary{%endif%}">
{{node|nomenclatura}}
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>
{%for parent in node.dispositivos_filhos_set.all %}
<a href="{% url view.get_url_this_view parent.ta_id parent.pk %}">
{{parent|nomenclatura}} {% if parent.dispositivo_subsequente_id %}({% trans "Alterado" %}){% endif %}
</a>
{%endfor %}
</li>
</ul>
</div>
{% endif %}

19
templates/compilacao/dispositivo_form_search.html

@ -0,0 +1,19 @@
{% load i18n crispy_forms_tags %}
<div class="modal fade" id="modal-ds" tabindex="-1" role="dialog" aria-labelledby="gridSystemModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="{% trans 'Fechar' %}"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="gridSystemModalLabel">{% trans "Selecionar Dispositivo(s)" %}</h4>
</div>
<div class="modal-body">
{% crispy form form.helper%}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans 'Fechar' %}</button>
<button type="button" class="btn btn-primary" id="btn-modal-select">{% trans "Selecionar" %}</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->

125
templates/compilacao/dispositivo_form_search_fragment.html

@ -0,0 +1,125 @@
{% load i18n 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.ta%}
{% if not forloop.first %}</ul>{% endif %}
<ul class="cp" id="ta{{dpt.ta.pk}}">
{% if request.GET.data_type_selection == 'checkbox' %}
<li class="ta_title">
<div class="iteminput">
<input type="{{request.GET.data_type_selection}}" name="ta_select_all" id="ta_title{{dpt.ta.pk}}" value="{{dpt.ta.pk}}"/>
</div>
<div class="itemlabel">
<label for="ta_title{{dpt.ta.pk}}">{{dpt.ta}}</label>
</div>
</li>
{% else %}
<li class="ta_title"><span>{{dpt.ta}}</span></li>
{% endif %}
{% endifchanged %}
{% if dpt.tipo_dispositivo.dispositivo_de_alteracao or dpt.dispositivo_pai.nivel > 0 and dpt.is_relative_auto_insert and dpt.dispositivo_pai not in object_list %}
<li>
<div class="iteminput">
<input type="{{request.GET.data_type_selection}}" name="{{request.GET.data_field}}" id="dpt{{dpt.pk}}" value="{{dpt.pk}}"/>
</div>
<div class="itemlabel dpt">
{% if dpt.dispositivo_pai.nivel > 1 %}
<a class="clearfix" target="_blank" href="{% url 'compilacao:ta_text' dpt.dispositivo_pai.ta.pk%}#{{dpt.dispositivo_pai.pk}}" class="nomenclatura_heranca">{% trans "Herança:" %} {% heranca request dpt 1 0 %}</a>
{% endif %}
<div class="{{ dpt.dispositivo_pai.tipo_dispositivo.class_css }}">
<div class="dptt {% dispositivo_desativado dpt.dispositivo_pai None None %}" id="dptt{{dpt.dispositivo_pai.pk}}" >
{{ dpt.dispositivo_pai.tipo_dispositivo.rotulo_prefixo_html|safe }}
{{ dpt.dispositivo_pai.rotulo }}
{{ dpt.dispositivo_pai.tipo_dispositivo.rotulo_sufixo_html|safe }}
<span class="dtxt" id="d{% if not dpt.dispositivo_pai.dispositivo_subsequente_id and dpt.dispositivo_pai.dispositivo_substituido_id %}a{% endif %}{{dpt.dispositivo_pai.pk}}" pks="{{dpt.dispositivo_pai.dispositivo_substituido_id|default:''}}" pk="{{dpt.dispositivo_pai.pk}}">{{ dpt.dispositivo_pai.tipo_dispositivo.texto_prefixo_html|safe }}{%if dpt.dispositivo_pai.texto %}{{ dpt.dispositivo_pai.texto|safe }}{%else%}{%if not dpt.dispositivo_pai.tipo_dispositivo.dispositivo_de_articulacao %}&nbsp;{% endif %}{% endif %}</span>
{% if dpt.dispositivo_pai.ta_publicado_id %}
<a class="link_alterador" href="{%url 'compilacao:ta_text' dpt.dispositivo_pai.ta_publicado.pk %}#{{dpt.dispositivo_pai.dispositivo_atualizador_id}}">
{{ dpt.dispositivo_pai.tipo_dispositivo.nota_automatica_prefixo_html|safe }}
{% nota_automatica dpt.dispositivo_pai ta_pub_list %}
{{ dpt.dispositivo_pai.tipo_dispositivo.nota_automatica_sufixo_html|safe }}
</a>
{% endif %}
</div>
</div>
</div>
</li>
{% endif %}
<li>
<div class="iteminput">
<input type="{{request.GET.data_type_selection}}" name="{{request.GET.data_field}}" id="dpt{{dpt.pk}}" value="{{dpt.pk}}"/>
</div>
<div class="itemlabel dpt">
{% if dpt.nivel > 1 %}
<a class="clearfix" target="_blank" href="{% url 'compilacao:ta_text' dpt.ta.pk%}#{{dpt.pk}}" class="nomenclatura_heranca">{% trans "Herança:" %} {% heranca request dpt 1 0 %}</a>
{% endif %}
<div class="{{ dpt.tipo_dispositivo.class_css }}">
<div class="dptt {% dispositivo_desativado dpt None None %}" id="dptt{{dpt.pk}}" >
{{ dpt.tipo_dispositivo.rotulo_prefixo_html|safe }}
{% if dpt.rotulo or dpt.nivel = 1 %}{{ dpt.rotulo }}{%else%}[{{ dpt|nomenclatura}} {% trans "de" %} {{ dpt.dispositivo_pai.rotulo }}] - {% endif %}
{{ dpt.tipo_dispositivo.rotulo_sufixo_html|safe }}
<span class="dtxt"
id="d{% if not dpt.dispositivo_subsequente_id and dpt.dispositivo_substituido_id %}a{% endif %}{{dpt.pk}}"
pks="{{dpt.dispositivo_substituido_id|default:''}}"
pk="{{dpt.pk}}">{{ dpt.tipo_dispositivo.texto_prefixo_html|safe }}{%if dpt.texto %}{{ dpt.texto|safe }}{%else%}{%if not dpt.tipo_dispositivo.dispositivo_de_articulacao %}&nbsp;{% endif %}{% endif %}</span>
{% if dpt.ta_publicado_id %}
<a class="link_alterador" href="{%url 'compilacao:ta_text' dpt.ta_publicado.pk %}#{{dpt.dispositivo_atualizador_id}}">
{{ dpt.tipo_dispositivo.nota_automatica_prefixo_html|safe }}
{% nota_automatica dpt ta_pub_list %}
{{ dpt.tipo_dispositivo.nota_automatica_sufixo_html|safe }}
</a>
{% endif %}
</div>
{% if dpt.tipo_dispositivo.dispositivo_de_alteracao%}
{%with node=dpt template_name='compilacao/text_list_blocoalteracao.html' %}
{%include template_name%}
{%endwith%}
{% endif%}
</div>
</div>
</li>
{% if request.GET.dispositivos_internos == 'True' %}
{% for df in dpt.dispositivos_filhos_set.all %}
{% if df not in object_list %}
<li>
<div class="iteminput">
<input type="{{request.GET.data_type_selection}}" name="{{request.GET.data_field}}" id="dpt{{df.pk}}" value="{{df.pk}}"/>
</div>
<div class="itemlabel dpt">
{% if df.nivel > 1 %}
<a class="clearfix" target="_blank" href="{% url 'compilacao:ta_text' df.ta.pk%}#{{df.pk}}" class="nomenclatura_heranca">{% trans "Herança:" %} {% heranca request df 1 0 %}</a>
{% endif %}
<div class="{{ df.tipo_dispositivo.class_css }}">
<div class="dptt {% dispositivo_desativado dpt None None %}" id="dptt{{df.pk}}" >
{{ df.tipo_dispositivo.rotulo_prefixo_html|safe }}
<a name="{{df.pk}}" title="{{df.pk}}">{% if df.rotulo or df.nivel = 1%}{{ df.rotulo }}{%else%}[{{ df|nomenclatura}} {% trans "de" %} {{ df.dispositivo_pai.rotulo }}] - {% endif %}</a>
{{ df.tipo_dispositivo.rotulo_sufixo_html|safe }}
<span class="dtxt" id="d{% if not df.dispositivo_subsequente_id and df.dispositivo_substituido_id %}a{% endif %}{{df.pk}}" pks="{{df.dispositivo_substituido_id|default:''}}" pk="{{df.pk}}">{{ df.tipo_dispositivo.texto_prefixo_html|safe }}{%if df.texto %}{{ df.texto|safe }}{%else%}{%if not df.tipo_dispositivo.dispositivo_de_articulacao %}&nbsp;{% endif %}{% endif %}</span>
{% if df.ta_publicado_id %}
<a class="link_alterador" href="{%url 'compilacao:ta_text' df.ta_publicado.pk %}#{{df.dispositivo_atualizador_id}}">
{{ df.tipo_dispositivo.nota_automatica_prefixo_html|safe }}
{% nota_automatica df ta_pub_list %}
{{ df.tipo_dispositivo.nota_automatica_sufixo_html|safe }}
</a>
{% endif %}
</div>
</div>
</div>
</li>
{% endif %}
{% endfor %}
{% endif %}
{% if forloop.last %}</ul>{% endif %}
{% endfor %}

28
templates/compilacao/dispositivo_form_vigencia.html

@ -0,0 +1,28 @@
{% extends "compilacao/dispositivo_form.html" %}
{% load i18n %}
{% block extra_js %}{{block.super}}
<script type="text/javascript">
var change_inconstitucionalidade = function() {
var datas = $('.dateinput').filter('[name!="inicio_vigencia"]');
var _this = this;
if ($('[name="inconstitucionalidade"]:checked').val() == "True") {
datas.val($('[name="inicio_vigencia"]').val());
datas.attr("readonly", "readonly");
datas.datepicker( "destroy" );
}
else {
datas.removeAttr("readonly");
datas.datepicker();
}
}
$('[name="inconstitucionalidade"]').on('change', change_inconstitucionalidade);
$('[name="inicio_vigencia"]').on('change', change_inconstitucionalidade);
change_inconstitucionalidade();
DispostivoSearch({
'url_form': '{% url 'compilacao:dispositivo_search_form'%}',
'text_button': '{% trans 'Selecionar Dispositivo'%}'
});
</script>
{% endblock %}

39
templates/compilacao/dispositivo_search_fragment_form.html

@ -1,39 +0,0 @@
{% 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.ta%}
{% if not forloop.first %}</ul>{% endif %}
<div class="ta_title">{{dpt.ta}}</div>
<ul>
{% endifchanged %}
{% if dpt.is_relative_auto_insert 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:ta_text' dpt.ta.pk%}#{{dpt.pk}}" class="nomenclatura_heranca">{% nomenclatura_heranca dpt 1 1 %}</a>
</div>
</li>
{% elif not dpt.tipo_dispositivo.dispositivo_de_articulacao %}
<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:ta_text' dpt.ta.pk%}#{{dpt.pk}}" class="nomenclatura_heranca">{% nomenclatura_heranca dpt 1 1 %}</a>
</div>
</li>
{% endif%}
{% if forloop.last %}</ul>{% endif %}
{% endfor %}

6
templates/compilacao/form.html

@ -1,6 +0,0 @@
{% extends "base.html" %}
{% load i18n crispy_forms_tags %}
{% block base_content %}
{% crispy form %}
{% endblock %}

54
templates/compilacao/layout/dispositivo_checkbox.html

@ -0,0 +1,54 @@
{% load crispy_forms_filters %}
{% load i18n compilacao_filters common_tags%}
<div class="controls cp lista-dispositvo"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
{% include 'bootstrap/layout/field_errors_block.html' %}
{% for choice in field.field.choices %}
{% ifchanged choice.1.ta%}
{% if not forloop.first %}</ul>{% endif %}
<ul id="ta{{choice.1.ta.pk}}">
<li class="ta_title">
<div class="iteminput">
<input type="{{field.field.widget.attrs|lookup:"data-type-selection"}}" name="ta_select_all" id="ta_title{{choice.1.ta.pk}}" value="{{choice.1.ta.pk}}"/>
</div>
<div class="itemlabel">
<label for="ta_title{{choice.1.ta.pk}}">{{choice.1.ta}}</label>
</div>
</li>
{% endifchanged %}
<li>
<div class="iteminput">
<input type="{{field.field.widget.attrs|lookup:"data-type-selection"}}" name="{{ field.html_name }}" id="dpt{{choice.1.pk}}" value="{{choice.1.pk}}" {% if choice.0 in field.value or choice.0|stringformat:"s" in field.value or choice.0|stringformat:"s" == field.value|stringformat:"s" %} checked="checked"{% endif %} />
</div>
<div class="itemlabel dpt">
{% if choice.1.ta_publicado_id %}
<a target="_blank" href="{% url 'compilacao:ta_text' choice.1.ta.pk%}#{{choice.1.pk}}" class="nomenclatura_heranca">{% trans "Herança:" %} {% nomenclatura_heranca choice.1 1 1 %}</a>
{% endif %}
<div class="{{ choice.1.tipo_dispositivo.class_css }}">
<div class="dptt {% dispositivo_desativado choice.1 None None %}" id="dptt{{choice.1.pk}}" >
{{ choice.1.tipo_dispositivo.rotulo_prefixo_html|safe }}
<a name="{{choice.1.pk}}" title="{{choice.1.pk}}">{% if choice.1.rotulo %}{{ choice.1.rotulo }}{%else%}[{{ choice.1|nomenclatura}}{% if choice.1.dispositivo_pai %} {% trans "de" %} {{ choice.1.dispositivo_pai.rotulo }}{% endif %}] - {% endif %}</a>
{{ choice.1.tipo_dispositivo.rotulo_sufixo_html|safe }}
<span class="dtxt" id="d{% if not choice.1.dispositivo_subsequente_id and choice.1.dispositivo_substituido_id %}a{% endif %}{{choice.1.pk}}" pks="{{choice.1.dispositivo_substituido_id|default:''}}" pk="{{choice.1.pk}}">{{ choice.1.tipo_dispositivo.texto_prefixo_html|safe }}{%if choice.1.texto %}{{ choice.1.texto|safe }}{%else%}{%if not choice.1.tipo_dispositivo.dispositivo_de_articulacao %}&nbsp;{% endif %}{% endif %}</span>
{% if choice.1.ta_publicado_id and not choice.1.tipo_dispositivo.dispositivo_de_articulacao %}
<a class="link_alterador" target="_blank" href="{%url 'compilacao:ta_text' choice.1.ta_publicado.pk %}#{{choice.1.dispositivo_atualizador_id}}">
{{ choice.1.tipo_dispositivo.nota_automatica_prefixo_html|safe }}
{% nota_automatica choice.1 ta_pub_list %}
{{ choice.1.tipo_dispositivo.nota_automatica_sufixo_html|safe }}
</a>
{% endif %}
</div>
</div>
</div>
</li>
{% if forloop.last %}</ul>{% endif %}
{% endfor %}
{% include 'bootstrap/layout/help_text.html' %}
</div>

54
templates/compilacao/layout/dispositivo_checkbox_old.html

@ -0,0 +1,54 @@
{% load crispy_forms_filters %}
{% load i18n compilacao_filters common_tags%}
<div class="controls lista-dispositvo"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
{% include 'bootstrap/layout/field_errors_block.html' %}
{% for choice, dpt in field.field.choices %}
{% ifchanged dpt.ta%}
{% if not forloop.first %}</ul>{% endif %}
<ul id="ta{{dpt.ta.pk}}">
<li class="ta_title">{{dpt.ta}}</li>
{% endifchanged %}
{% if dpt.is_relative_auto_insert %}
<li>
<div class="iteminput">
<input type="{{field.field.widget.attrs|lookup:"data-type-selection"}}" name="{{ field.html_name }}" id="dpt{{dpt.pk}}" value="{{dpt.pk}}" {% if choice in field.value or choice|stringformat:"s" in field.value or choice|stringformat:"s" == field.value|stringformat:"s" %} checked="checked"{% endif %} />
</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:ta_text' dpt.ta.pk%}#{{dpt.pk}}" class="nomenclatura_heranca" title="{% trans 'Abrir Texto deste Dispositivo'%}">{% nomenclatura_heranca dpt 1 1 %}</a>
</div>
</li>
{% elif not dpt.tipo_dispositivo.dispositivo_de_articulacao and not dpt.is_relative_auto_insert %}
<li>
<div class="iteminput">
<input type="{{field.field.widget.attrs|lookup:"data-type-selection"}}" name="{{ field.html_name }}" id="dpt{{dpt.pk}}" value="{{dpt.pk}}" {% if choice in field.value or choice|stringformat:"s" in field.value or choice|stringformat:"s" == field.value|stringformat:"s" %} checked="checked"{% endif %} />
</div>
<div class="itemlabel">
<label for="r{{dpt.pk}}">{{dpt.rotulo|safe}} - {{dpt.texto|safe}}</label>
<a target="_blank" href="{% url 'compilacao:ta_text' dpt.ta.pk%}#{{dpt.pk}}" class="nomenclatura_heranca" title="{% trans 'Abrir Texto deste Dispositivo'%}">{% nomenclatura_heranca dpt 1 1 %}</a>
</div>
</li>
{% elif dpt.tipo_dispositivo.dispositivo_de_articulacao%}
<li>
<div class="iteminput">
<input type="{{field.field.widget.attrs|lookup:"data-type-selection"}}" name="{{ field.html_name }}" id="dpt{{dpt.pk}}" value="{{dpt.pk}}" {%if choice in field.value or choice|stringformat:"s" in field.value or choice|stringformat:"s" == field.value|stringformat:"s" %} checked="checked"{% endif %} />
</div>
<div class="itemlabel">
<label for="r{{dpt.pk}}">{{dpt.rotulo|safe}} - {% if dpt.tipo_dispositivo.dispositivo_de_articulacao %}{{dpt.dispositivos_filhos_set.all.first.texto|safe}}{% else %}{{dpt.texto|safe}}{% endif %}</label>
<a target="_blank" href="{% url 'compilacao:ta_text' dpt.ta.pk%}#{{dpt.pk}}" class="nomenclatura_heranca" title="{% trans 'Abrir Texto deste Dispositivo'%}">{% nomenclatura_heranca dpt 1 1 %}</a>
</div>
</li>
{% endif%}
{% if forloop.last %}</ul>{% endif %}
{% endfor %}
{% include 'bootstrap/layout/help_text.html' %}
</div>

43
templates/compilacao/layout/dispositivo_radio.html

@ -0,0 +1,43 @@
{% load crispy_forms_filters %}
{% load i18n compilacao_filters common_tags%}
<div class="controls lista-dispositvo"{% if flat_attrs %} {{ flat_attrs|safe }}{% endif %}>
{% include 'bootstrap/layout/field_errors_block.html' %}
{% for choice, dpt in field.field.choices %}
{% ifchanged dpt.ta%}
{% if not forloop.first %}</ul>{% endif %}
<ul id="ta{{dpt.ta.pk}}">
<li class="ta_title"><span>{{dpt.ta}}</span></li>
{% endifchanged %}
<li>
<div class="iteminput">
<input type="{{field.field.widget.attrs|lookup:"data-type-selection"}}" name="{{ field.html_name }}" id="dpt{{dpt.pk}}" value="{{dpt.pk}}" {% if choice|stringformat:"s" == field.value|stringformat:"s" %} checked="checked"{% endif %} />
</div>
<div class="itemlabel dpt">
{% if dpt.nivel > 1 %}
<a class="clearfix" target="_blank" href="{% url 'compilacao:ta_text' dpt.ta.pk%}#{{dpt.pk}}" class="nomenclatura_heranca">{% trans "Herança:" %} {% heranca request dpt 1 0 %}</a>
{% endif %}
<div class="{{ dpt.tipo_dispositivo.class_css }}">
<div class="dptt {% dispositivo_desativado dpt None None %}" id="dptt{{dpt.pk}}" >
{{ dpt.tipo_dispositivo.rotulo_prefixo_html|safe }}
{% if dpt.rotulo or dpt.nivel = 1 %}{{ dpt.rotulo }}{%else%}[{{ dpt|nomenclatura}} {% trans "de" %} {{ dpt.dispositivo_pai.rotulo }}] - {% endif %}
{{ dpt.tipo_dispositivo.rotulo_sufixo_html|safe }}
<span class="dtxt"
id="d{% if not dpt.dispositivo_subsequente_id and dpt.dispositivo_substituido_id %}a{% endif %}{{dpt.pk}}"
pks="{{dpt.dispositivo_substituido_id|default:''}}"
pk="{{dpt.pk}}">{{ dpt.tipo_dispositivo.texto_prefixo_html|safe }}{%if dpt.texto %}{{ dpt.texto|safe }}{%else%}{%if not dpt.tipo_dispositivo.dispositivo_de_articulacao %}&nbsp;{% endif %}{% endif %}</span>
</div>
</div>
</div>
</li>
{% if forloop.last %}</ul>{% endif %}
{% endfor %}
{% include 'bootstrap/layout/help_text.html' %}
</div>

3
templates/compilacao/publicacao_list.html

@ -9,9 +9,6 @@
<a href="{{ view.create_url }}" class="btn btn-default">
{% trans 'Adicionar'%} {%model_verbose_name 'compilacao.models.Publicacao'%}
</a>
<a href="{% url 'compilacao:ta_text' view.kwargs.ta_id %}" class="btn btn-default">
{% trans 'Voltar' %}
</a>
</div>
{% if not object_list %}

92
templates/compilacao/text_edit.html

@ -14,7 +14,6 @@
<h1><b>Edição:</b> {{ view.title }} - <i>{% trans 'Texto Multivigente' %}</i></h1>
{% endblock %}
<div id="message_block"><div id="msg">{% trans 'Aguarde... Atualizando informações!!!'%}</div></div>
{% block actions %}
<div class="clearfix">
<div class="actions btn-toolbar pull-right" role="toolbar">
@ -28,10 +27,101 @@
{% block base_content %}{{block.super}}
<div id="message_block"><div id="msg">{% trans 'Aguarde... Atualizando informações!!!'%}</div></div>
<div id="modal-message" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="alert" role="alert">
<button type="button" class="close fa-times fa" aria-label="Close"></button>
<div id="message"></div>
</div>
</div>
</div>
</div>
<div class="cp cpe">
{% include 'compilacao/text_edit_bloco.html'%}
</div>
<div class="modal fade" id="modal-help" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog modal-xs modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="{% trans "Fechar" %}"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Orientações Gerais <small>Dicas e Boas Práticas</small></h4>
</div>
<div class="modal-body">
{% blocktrans %}
<ol>
<li>As opções de inserção e exclusão tem precedência sobre qualquer alteração feita na edição avançada.
</li>
<li>Os Perfis Estruturais controlam as possibilidades do inserção do Editor. Perfis Estruturais servem para guiar as permissões de inserções relativas e podem, caso configurados de acordo, guiar a construção do Texto para se enquadrar em legislação e/ou regras específicas.</li>
<li>O Editor pode estar em quatro modos:
<ol>
<li><strong>(E) Editor Simples:</strong> Edição Básica de Texto, além de novas inserções e exclusões. É recomendável o uso deste sempre que possível.</li>
<li><strong>(E+) Editor Rico:</strong> Edição do texto com o editor TinyMCE. Neste editor é possível registro de tabelas e textos customizados</li>
<li><strong>(E*) Editor Avançado:</strong> Edição e Lançamento de Dispositivos Originais, Alterados e Alteradores, além de todos os dados que controlam a compilação. </li>
<li><strong>(C) Construtor Estrutural:</strong> Neste modo, o editor foca na inserção de Dispositivos e busca deixar mais acessíveis estas ações.</li>
</ol></li>
<li>A Edição Avançada é complexa e sensível a erros de edição. É recomendável o uso cuidadoso e consciente das funcionalidades. Ela será tratada num tópico aparte.</li>
<li>Gere toda a estrutura básica sem adicionar texto, isso evitará erros estruturais e otimizará seu trabalho por:
<ol>
<li>Facilitar o trabalho local aí, de seu navegador.</li>
<li>Diminuir o tráfego de rede.</li>
<li>Desonerar os servidores que processam e armazenam seus dados.</li>
</ol>
</li>
<li>Inserir os Dispositivos na sequência natural é mais produtivo para você, além de ser também mais simples para o algorítmo que controla este processo. Quanto maior a mudança estutural, mais lento será o procedimento. </li>
<li>A Opção DVt (Dispositivo de Vigência do Texto) redefine o dispositivo em seleção como o dispositivo de vigência de todos os outros, inclusive os dispositivos alterados, caso se trate de um Texto Alterador.
<ol>
<li>O Dispositivo de Vigência de Dispositivos Alterados é, quase sempre, o Dispositivo do Texto Alterador, e não do Texto Alterado.</li>
<li>Ao usar a opção DVt, todas as datas de início de vigência serão reenquadradas para a data de vigência do dispositivo de vigência. Posteriormente, alterações manuais poderão ser feitas.</li>
<li>Ao fazer alterações de dispositivos, a opção DVt manipula automáticamente as datas de fim de vigência dos Dispositivos substituidos, ou seja, ao definir um Dispositivo de Vigência de um Dispositivo Alterado, automaticamente será encerrado a vigência de seu antecessor. O mesmo ocorre para dispositivos que possuem sucessores. </li>
<li>Após usar a opção DVt, alterações manuais poderão ser feitas no Editor Avançado e, não sendo usado novamente a opção Dvt, essas alterações manuais serão mantidas.</li>
</ol>
</li>
<li>A criação de Tipos de Dispositivos é dinâmica e deverão estar amarrados por perfis estuturais configuráveis. Por serem tarefas técnicas e complicadas, criar/editar tipos de dispositivos e perfis estuturais estão disponíveis apenas na área de edição técnica do SAPL (admin).
</li>
</ol>
<ul>
<li>As exclusões e inserções, quando acionadas, renumeram e redefinem os rótulos, tanto de dispositivos locais, quanto os DCC's.</li>
</ul>
<hr>
<h4>Exclusões</h4>
<ol>
<li>A exclusão de Dispositivos é um processo moroso e complicado, principalmente se o que está sendo excluido for, ou envolver, os DCC's - Dispositivos de Contagem Continua, como é o caso do Tipo de Dispositivo (Artigo), que é um tipo comum nos Textos Articulados Brasileiros.
As exclusões podem ser diretas, individuais ou em bloco:
<ol>
<li><strong>Diretas:</strong> Dispositivos que não possuam itens internos são excluidos diretamente.</li>
<li><strong>Individuais:</strong> Dispositivos que possuam itens internos e estes podem ser reenquadrados no Dispositivo imediatamente anterior
<ul>
<li>Ainda Não foi implementado a transferência de conteúdo na exclusão individual de DCC's que estão estruturalmente separados. Ex: Um artigo possui parágrafos, se seu artigo imediatamente anterior estiver no mesmo sub-grupo, esses parágrafos, na exclusão individual, serão transferidos para o artigo anterior, no entanto, se estiverem em sub-grupo separados, o artigo será completamente excluido como em uma exclusão em bloco.</li>
</ul>
</li>
<li><strong>Em Bloco:</strong> Todo o conteúdo incluído no Dispositivo em edição será excluído.</li>
</ol>
</li>
</ol>
<hr>
<h4>Edição Avançada</h4>
<ol>
<li>...
</li>
</ol>
{% endblocktrans %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Fechar" %}</button>
</div>
</div>
</div>
</div>
{% endblock base_content %}
{% block foot_js %}

54
templates/compilacao/text_edit_bloco.html

@ -9,7 +9,7 @@
{% close_div view.flag_nivel_old dpt.nivel 0 %}
{% endif%}
{% if forloop.first and view|isinst:'DispositivoEditView' %}
{% if forloop.first and view|isinst:'DispositivoSimpleEditView' %}
{% else %}
<div class="dpt" id="dpt{{dpt.pk}}" pk="{{dpt.pk}}">
{% endif%}
@ -22,16 +22,21 @@
<li class="edt-textarea"><a class="btn-top btn-action" pk="{{dpt.pk}}" action="refresh:textarea" title="{% trans 'Edição simples apenas do texto'%}">E</a></li>
<li class="edt-tinymce"><a class="btn-top btn-action" pk="{{dpt.pk}}" action="refresh:tinymce" title="{% trans 'Editar o texto com TinyMCE'%}">E+</a></li>
{%endif%}
<li class="edt-detail"><a class="btn-top btn-action" pk="{{dpt.pk}}" action="refresh:detail" title="{% trans 'TODO: Edição detalhada'%}">E*</a></li>
<li class="edt-detail"><a class="btn-top" href="{% url 'compilacao:dispositivo_edit' dpt.ta_id dpt.pk %}" title="{% trans 'Edição Avançada'%}">E*</a></li>
<li class="edt-construct"><a class="btn-top btn-action" pk="{{dpt.pk}}" action="refresh:construct" title="{% trans 'Construçao da estrutura do Texto Articulado'%}">C</a></li>
</ul>
<ul class="btns-action actions_right">
<li><a class="btn-right btn-action" pk="{{dpt.pk}}" action="set_dvt" title="{% trans 'Definir como Dispositivo de Vigência para todos os Dispositivos Originais deste Texto, bem como, dos Textos Anteriores alterados por este Texto!'%}">DVt</a></li>
{% comment %}
<li><a class="btn-right btn-action" pk="{{dpt.pk}}" action="refresh" title="{% trans 'TODO: Reduzir nível do Dispositivo'%}">&#10092;</a></li>
<li><a class="btn-right btn-action" pk="{{dpt.pk}}" action="refresh" title="{% trans 'TODO: Aumentar nível do Dispositivo'%}">&#10093;</a></li>
<li><a class="btn-right btn-action" pk="{{dpt.pk}}" action="refresh" title="{% trans 'TODO: Subir uma posição'%}">&#8593;</a></li>
<li><a class="btn-right btn-action" pk="{{dpt.pk}}" action="refresh" title="{% trans 'TODO: Descer uma posição'%}">&#8595;</a></li>
<li><a class="btn-right btn-action" pk="{{dpt.pk}}" action="refresh" title="{% trans 'TODO: Subir uma posição com todos os subniveis'%}">&#8648;</a></li>
<li><a class="btn-right btn-action" pk="{{dpt.pk}}" action="refresh" title="{% trans 'TODO: Descer uma posição com todos os subniveis'%}">&#8650;</a></li>
{% endcomment %}
</ul>
<ul class="btns-action actions_left">
@ -46,13 +51,16 @@
<ul class="actions_inserts {% if not dpt.tipo_dispositivo.dispositivo_de_articulacao %}menu_flutuante{%endif%}">
{% if dpt.dispositivo_subsequente == None %}
{% for inserts in view|select_provaveis_inserts:request %}
{% if inserts.itens %}
<li class="{{inserts.action}}"><a class="btn-inserts" action="" pk="{{dpt.pk}}">{{inserts.icone|safe}}<span>{{inserts.tipo_insert}}</span></a>
<ul id="afe{{dpt.id}}" >
{% for item in inserts.itens %}
<li><a class="btn-inserts btn-action" action="{{inserts|lookup:'action'}}" pk="{{item.dispositivo_base}}" variacao="{{item.variacao}}" tipo_pk="{{item.tipo_pk}}">{{item.provavel}}</a></li>
<li><a class="btn-inserts btn-action" action="{{inserts.action}}" pk="{{item.dispositivo_base}}" variacao="{{item.variacao}}" tipo_pk="{{item.tipo_pk}}">{{item.provavel}}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
{%endif%}
@ -60,8 +68,8 @@
<li class="menu_excluir"><a {% if not dpt.dispositivos_filhos_set.exists %}class="btn-excluir btn-action" action="delete_item_dispositivo" pk={{dpt.pk}}{%else%}class="btn-excluir"{%endif%}>&nbsp;<span>Excluir</span></a>
{% if dpt.dispositivos_filhos_set.exists %}
<ul>
<li><a href="#" class="btn-excluir btn-action" action="delete_item_dispositivo_todo" pk={{dpt.pk}}>TODO: Excluir apenas este dispositivo</a></li>
<li><a href="#" class="btn-excluir btn-action" action="delete_bloco_dispositivo" pk={{dpt.pk}}>Excluir toda a estrutura deste dispositivo</a></li>
<li><a href="#" class="btn-excluir btn-action" action="delete_item_dispositivo" pk={{dpt.pk}}>{% trans 'Excluir apenas este dispositivo'%}</a></li>
<li><a href="#" class="btn-excluir btn-action" action="delete_bloco_dispositivo" pk={{dpt.pk}}>{% trans 'Excluir este dispositivo e toda sua estrutura'%}</a></li>
</ul>
{% endif %}
</li>
@ -79,8 +87,28 @@
</div>
<ul class="label_status" >
<li>Ordem: {{dpt.ordem}}, Nivel: {{dpt.nivel}}, Número: {{dpt.get_numero_completo}}</li>
<li><a>.</a></li>
<li>p: {{dpt.dispositivo_substituido_id|default:''}}</li>
<li>&#8226;</li>
<li>n: {{dpt.dispositivo_subsequente_id|default:''}}</li>
<li>&#8226;</li>
<li>Ordem: {{dpt.ordem}}</li>
<li>&#8226;</li>
<li>Nivel: {{dpt.nivel}}</li>
<li>&#8226;</li>
<li>Número: {{dpt.get_numero_completo}}</li>
{% if dpt.dispositivo_vigencia %}
<li>&#8226;</li>
<li>{% field_verbose_name dpt 'dispositivo_vigencia'%}: <a href="{% url 'compilacao:ta_text_edit' dpt.dispositivo_vigencia.ta_id %}#{{ dpt.dispositivo_vigencia_id }}" action="refresh" pk="{{dpt.dispositivo_vigencia.pk}}" title="{% field_verbose_name dpt 'dispositivo_vigencia'%} {% trans 'em' %}:&#013;{{dpt.dispositivo_vigencia.ta}}">{{dpt.dispositivo_vigencia|nomenclatura}}</a> </li>
{% endif %}
<li>&#8226;</li>
<li><a type="button" data-toggle="modal" data-target="#modal-help">
?
</a>
</li>
</ul>
<ul class="btns-action actions_parents">
@ -95,23 +123,23 @@
{% endif%}
{% if view.pk_view == 0 and view.pk_edit == 0 or view.pk_edit != view.pk_view %}
{% if not dpt.rotulo and not dpt.texto %}
{% if not dpt.rotulo and not dpt.texto and dpt.tipo_dispositivo.dispositivo_de_articulacao%}
<div class="btns-action actions_left">
<a class="btn-edit" pk="{{dpt.pk}}" title="Edição do dispositivo: {{ dpt.tipo_dispositivo.nome }} {{ dpt.rotulo }}">E</a>
<a class="btn-edit" pk="{{dpt.pk}}">{% trans 'Editar'%} {{ dpt.tipo_dispositivo.nome }} {{ dpt.rotulo }}</a>
</div>
{% endif %}
<div class="bloco {% dispositivo_desativado dpt view.inicio_vigencia view.fim_vigencia %} {{ dpt.tipo_dispositivo.class_css }}">
{% spaceless %}
<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>
<div class="de" id="id{{dpt.id}}" pk="{{dpt.pk}}" ordem="{{dpt.ordem}}" name="{{dpt.pk}}" title="{{dpt.pk}} - {{dpt.ordem}}">{{ 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.ta_publicado_id != None and not dpt.tipo_dispositivo.dispositivo_de_articulacao %}
<a class="link_alterador" href="compilacao:ta_text_edit' dpt.ta_publicado.pk %}#{{dpt.dispositivo_atualizador_id}}">
<a class="link_alterador" href="{% url 'compilacao:ta_text_edit' dpt.ta_publicado.pk %}#{{dpt.dispositivo_atualizador_id}}">
{{ dpt.tipo_dispositivo.nota_automatica_prefixo_html|safe }}
{% nota_automatica dpt ta_pub_list %}
{{ dpt.tipo_dispositivo.nota_automatica_sufixo_html|safe }}
</a>
{% endif %}
{% endspaceless %}
{% if view.is_ta_alterador and dpt.tipo_dispositivo.class_css == 'bloco_alteracao'%}
{% if dpt.tipo_dispositivo.class_css == 'bloco_alteracao'%}
{%with node=dpt template_name='compilacao/text_edit_blocoalteracao.html' %}
{%include template_name%}
{%endwith%}
@ -123,7 +151,7 @@
{% endfor %}
{% if view|isinst:'DispositivoEditView' %}
{% if view|isinst:'DispositivoSimpleEditView' %}
{% close_div view.flag_nivel_old view.flag_nivel_ini -1 %}
{% else %}
{% close_div view.flag_nivel_old view.flag_nivel_ini 0 %}

3
templates/compilacao/text_edit_blocoalteracao.html

@ -1,10 +1,11 @@
{% load compilacao_filters %}
{% load common_tags %}
aaaaa
{% for ch in dpt.pk|get_bloco_atualizador %}
{% spaceless %}
<div class="dpt" id="d{{ch.id}}">
<div class="{{ ch.tipo_dispositivo.class_css }}" id="id{{ch.id}}" nivel="{{ch.nivel}}">
{{ ch.tipo_dispositivo.rotulo_prefixo_html|safe }}<a name="{{ch.pk}}" href="compilacao:ta_text_edit' ch.ta.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:ta_text_edit' ch.ta.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>
{% endspaceless %}

27
templates/compilacao/text_list.html

@ -45,27 +45,28 @@
{% elif forloop.last %}
{% for dispositivo in values %}
<li class="{% if not view.inicio_vigencia%}active{% endif %}">
<a href="{%url 'compilacao:ta_text' dispositivo.ta_id %}" title="{% trans 'Compilação atual'%}.&#013;{% trans 'Vigência a partir de'%} {{dispositivo.inicio_vigencia}}&#013;{% if dispositivo.ta_publicado_id in ta_pub_list %}{{ ta_pub_list|lookup:dispositivo.ta_publicado_id }}{%else%}{{dispositivo.ta_publicado}}{%endif%}">{% trans 'Texto Atual'%}</a>
<a href="{%url 'compilacao:ta_text' dispositivo.ta_id %}" title="{% trans 'Compilação atual'%}.&#013;{% trans 'Vigência a partir de'%} {{dispositivo.inicio_vigencia}}&#013;{% if dispositivo.ta_publicado_id in ta_pub_list %}{{ ta_pub_list|lookup:dispositivo.ta_publicado_id }}{%else%}{%if dispositivo.ta_publicado %}{{dispositivo.ta_publicado}}{%else%}{{dispositivo.ta}}{%endif%}{%endif%}">{% trans 'Texto Atual'%}</a>
</li>
{% if forloop.parentloop.last %}
</ul>
{% if view.inicio_vigencia and view.fim_vigencia %}
<span class="vigencia-active">
{% blocktrans with inicio_vigencia=view.inicio_vigencia fim_vigencia=view.fim_vigencia ta_publicado=dispositivo.ta_publicado%}
{% if view.inicio_vigencia and view.fim_vigencia %}
{% blocktrans with inicio_vigencia=view.inicio_vigencia fim_vigencia=view.fim_vigencia%}
Vigência entre <b>{{inicio_vigencia}}</b> e <b>{{fim_vigencia}}</b>.
<br>
<small>Dada pela {{ta_publicado}}</small>
</span>
{% endblocktrans%}
{% else%}
<span class="vigencia-active">
{% blocktrans with inicio_vigencia=dispositivo.inicio_vigencia ta_publicado=dispositivo.ta_publicado%}
{% blocktrans with inicio_vigencia=dispositivo.inicio_vigencia%}
Vigência a partir de <b>{{inicio_vigencia}}</b>.
<br>
<small>Dada pela {{ta_publicado}}</small>
{% endblocktrans%}
</span>
{% endif %}
<br>
{% if view.ta_vigencia %}
<small>{% trans 'Dada por '%}<a href="{%url 'compilacao:ta_text' view.ta_vigencia %}">{{ta_pub_list|lookup:view.ta_vigencia}}</a></small>
{% elif view.ta_vigencia != 0 %}
<small>{% trans 'Dada por '%}<a href="{%url 'compilacao:ta_text' dispositivo.ta_publicado.pk %}">{{dispositivo.ta_publicado}}</a></small>
{% endif %}
</span>
{% endif%}
{% endfor %}
{% else %}
@ -74,7 +75,7 @@
{% for dispositivo in values %}
<li>
{% if not forloop.parentloop.first %}
<a href="{%url 'compilacao:ta_vigencia' dispositivo.ta_id dispositivo|get_sign_vigencia %}" title="{% if dispositivo.ta_publicado_id in ta_pub_list%}{{ ta_pub_list|lookup:dispositivo.ta_publicado_id }}{%else%}{{dispositivo.ta_publicado}}{%endif%}">{% trans 'Vigência entre'%} {{dispositivo.inicio_vigencia}} {% trans 'e'%} {{dispositivo.fim_vigencia}}</a>
<a href="{%url 'compilacao:ta_vigencia' dispositivo.ta_id dispositivo|get_sign_vigencia %}" title="{% if dispositivo.ta_publicado_id in ta_pub_list%}{{ ta_pub_list|lookup:dispositivo.ta_publicado_id }}{%else%}{%if dispositivo.ta_publicado %}{{dispositivo.ta_publicado}}{%else%}{{dispositivo.ta}}{%endif%}{%endif%}">{% trans 'Vigência entre'%} {{dispositivo.inicio_vigencia}} {% trans 'e'%} {{dispositivo.fim_vigencia}}</a>
{% endif %}
</li>
{% endfor %}
@ -86,7 +87,7 @@
<ul class="tipo-vigencias">
<li><a class="selected" onclick="textoMultiVigente(this, false);" title="{% trans 'Texto Multivigente Sequencial'%}">{% trans 'TMS'%}</a></li>
<li><a onclick="textoMultiVigente(this, true);" title="{% trans 'Texto Multivigente Integrado com Realce de Alterações'%}">{% trans 'TMI'%}</a></li>
<li><a onclick="textoVigente(this, true);" title="{% trans 'Texto Vigente COM Links para Textos Alteradores'%}">{% trans 'TVL'%}</a></li>
<li><a onclick="textoMultiVigente(this, false); textoVigente(this, true);" title="{% trans 'Texto Vigente COM Links para Textos Alteradores'%}">{% trans 'TVL'%}</a></li>
<li><a onclick="textoVigente(this, false);" title="{% trans 'Texto Vigente'%}">{% trans 'TVT'%}</a></li>
</ul>

6
templates/compilacao/text_list_bloco.html

@ -9,7 +9,7 @@
{% close_div view.flag_nivel_old dpt.nivel 0 %}
{% endif%}
{% if forloop.first and view|isinst:'DispositivoView' %}
{% if forloop.first and not view|isinst:'TextView' %}
{% else %}
<div class="dpt {%if dpt.tipo_dispositivo.class_css == 'bloco_alteracao'%}bloco_alteracao{% endif %}" nivel="{{dpt.nivel}}">
{% endif%}
@ -163,7 +163,7 @@
{% endif%}
</div>
{% endspaceless %}
{% if dpt.tipo_dispositivo.class_css == 'bloco_alteracao'%}
{% if dpt.tipo_dispositivo.dispositivo_de_alteracao%}
{%with node=dpt template_name='compilacao/text_list_blocoalteracao.html' %}
{%include template_name%}
{%endwith%}
@ -171,7 +171,7 @@
{% set_nivel_old view dpt.nivel %}
{% endfor %}
{% if view|isinst:'DispositivoView' %}
{% if not view|isinst:'TextView' %}
{% close_div view.flag_nivel_old view.flag_nivel_ini -1 %}
{% else %}
{% close_div view.flag_nivel_old view.flag_nivel_ini 0 %}

2
templates/compilacao/textoarticulado_detail.html

@ -14,7 +14,7 @@
{%endif%}
</li>
<li><a href="{% url 'compilacao:ta_pub_list' object.pk %}">{% model_verbose_name_plural 'compilacao.models.Publicacao' %}</a></li>
<li><a href="{% url 'compilacao:ta_text' object.pk %}">{% trans 'Texto da Norma' %}</a></li>
<li><a href="{% url 'compilacao:ta_text' object.pk %}">{% trans 'Texto' %}</a></li>
{%endif %}
</ul>
{% endblock %}

8
templates/compilacao/textoarticulado_menu_config.html

@ -6,10 +6,10 @@
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="{% url 'compilacao:tipo_ta_list' %}">{%model_verbose_name_plural 'compilacao.models.TipoTextoArticulado'%}</a></li>
<li><a href="{% url 'tipopublicacao:list' %}">{%model_verbose_name_plural 'compilacao.models.TipoPublicacao'%}</a></li>
<li><a href="{% url 'veiculopublicacao:list' %}">{%model_verbose_name_plural 'compilacao.models.VeiculoPublicacao'%}</a></li>
<li><a href="{% url 'tiponota:list' %}">{%model_verbose_name_plural 'compilacao.models.TipoNota'%}</a></li>
<li><a href="{% url 'tipovide:list' %}">{%model_verbose_name_plural 'compilacao.models.TipoVide'%}</a></li>
<li><a href="{% url 'compilacao:tipopublicacao_list' %}">{%model_verbose_name_plural 'compilacao.models.TipoPublicacao'%}</a></li>
<li><a href="{% url 'compilacao:veiculopublicacao_list' %}">{%model_verbose_name_plural 'compilacao.models.VeiculoPublicacao'%}</a></li>
<li><a href="{% url 'compilacao:tiponota_list' %}">{%model_verbose_name_plural 'compilacao.models.TipoNota'%}</a></li>
<li><a href="{% url 'compilacao:tipovide_list' %}">{%model_verbose_name_plural 'compilacao.models.TipoVide'%}</a></li>
<li><a href="#">TODO: Tipo de Dispositivo</a></li>
<li><a href="#">TODO: Perfil Estrutural de Textos Articulados</a></li>
</ul>

Loading…
Cancel
Save