wagtail-enap-designsystem 1.2.1.195__py3-none-any.whl → 1.2.1.196__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of wagtail-enap-designsystem might be problematic. Click here for more details.
- enap_designsystem/blocks/form.py +45 -28
- enap_designsystem/blocks/html_blocks.py +15 -17
- enap_designsystem/templates/enap_designsystem/form_templates/formulario_page.html +147 -21
- enap_designsystem/templates/enap_designsystem/includes/form_field.html +94 -119
- enap_designsystem/wagtail_hooks.py +150 -38
- {wagtail_enap_designsystem-1.2.1.195.dist-info → wagtail_enap_designsystem-1.2.1.196.dist-info}/METADATA +1 -1
- {wagtail_enap_designsystem-1.2.1.195.dist-info → wagtail_enap_designsystem-1.2.1.196.dist-info}/RECORD +10 -10
- {wagtail_enap_designsystem-1.2.1.195.dist-info → wagtail_enap_designsystem-1.2.1.196.dist-info}/WHEEL +0 -0
- {wagtail_enap_designsystem-1.2.1.195.dist-info → wagtail_enap_designsystem-1.2.1.196.dist-info}/licenses/LICENSE +0 -0
- {wagtail_enap_designsystem-1.2.1.195.dist-info → wagtail_enap_designsystem-1.2.1.196.dist-info}/top_level.txt +0 -0
enap_designsystem/blocks/form.py
CHANGED
|
@@ -1312,7 +1312,7 @@ class FormularioPage(Page):
|
|
|
1312
1312
|
return super().serve(request, *args, **kwargs)
|
|
1313
1313
|
|
|
1314
1314
|
def process_form_submission(self, request):
|
|
1315
|
-
"""Processa os dados do formulário"""
|
|
1315
|
+
"""Processa os dados do formulário com suporte para múltiplos arquivos"""
|
|
1316
1316
|
form_data = {}
|
|
1317
1317
|
files_data = {} # ← Separar arquivos dos dados
|
|
1318
1318
|
|
|
@@ -1327,21 +1327,49 @@ class FormularioPage(Page):
|
|
|
1327
1327
|
|
|
1328
1328
|
# PROCESSAR UPLOAD DE ARQUIVOS SEPARADAMENTE
|
|
1329
1329
|
if block.block_type == 'file_upload_field':
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
}
|
|
1330
|
+
# Verificar se é um campo que aceita múltiplos arquivos
|
|
1331
|
+
is_multiple = block.value.get('multiple_files', False)
|
|
1332
|
+
|
|
1333
|
+
if is_multiple:
|
|
1334
|
+
# O nome do campo no HTML tem [] anexado
|
|
1335
|
+
field_id_arr = f"{field_id}[]"
|
|
1336
|
+
# Usar getlist para pegar todos os arquivos
|
|
1337
|
+
uploaded_files = request.FILES.getlist(field_id_arr)
|
|
1339
1338
|
|
|
1340
|
-
|
|
1341
|
-
|
|
1339
|
+
if uploaded_files:
|
|
1340
|
+
# Lista para metadados de múltiplos arquivos
|
|
1341
|
+
files_info = []
|
|
1342
|
+
|
|
1343
|
+
# Processar cada arquivo
|
|
1344
|
+
for i, uploaded_file in enumerate(uploaded_files):
|
|
1345
|
+
# Metadados do arquivo
|
|
1346
|
+
file_info = {
|
|
1347
|
+
'filename': uploaded_file.name,
|
|
1348
|
+
'size': uploaded_file.size,
|
|
1349
|
+
'content_type': uploaded_file.content_type,
|
|
1350
|
+
}
|
|
1351
|
+
files_info.append(file_info)
|
|
1352
|
+
|
|
1353
|
+
# Cada arquivo tem sua própria chave
|
|
1354
|
+
files_data[f"{field_id}_{i}"] = uploaded_file
|
|
1355
|
+
|
|
1356
|
+
# Armazenar a lista com todos os metadados
|
|
1357
|
+
form_data[field_id] = files_info
|
|
1358
|
+
else:
|
|
1359
|
+
# Código original para campo com um único arquivo
|
|
1360
|
+
if field_id in request.FILES:
|
|
1361
|
+
uploaded_file = request.FILES[field_id]
|
|
1362
|
+
|
|
1363
|
+
form_data[field_id] = {
|
|
1364
|
+
'filename': uploaded_file.name,
|
|
1365
|
+
'size': uploaded_file.size,
|
|
1366
|
+
'content_type': uploaded_file.content_type,
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
files_data[field_id] = uploaded_file
|
|
1342
1370
|
continue
|
|
1343
1371
|
|
|
1344
|
-
#
|
|
1372
|
+
# O restante do código permanece igual
|
|
1345
1373
|
if block.block_type == 'checkbox_multiple_field':
|
|
1346
1374
|
values = request.POST.getlist(field_id)
|
|
1347
1375
|
if values:
|
|
@@ -1351,7 +1379,7 @@ class FormularioPage(Page):
|
|
|
1351
1379
|
if value:
|
|
1352
1380
|
form_data[field_id] = value
|
|
1353
1381
|
|
|
1354
|
-
#
|
|
1382
|
+
# O restante da função permanece igual
|
|
1355
1383
|
errors = self.validate_form_data(form_data, request)
|
|
1356
1384
|
if errors:
|
|
1357
1385
|
context = self.get_context(request)
|
|
@@ -1359,23 +1387,12 @@ class FormularioPage(Page):
|
|
|
1359
1387
|
context['form_data'] = form_data
|
|
1360
1388
|
return render(request, self.get_template(request), context)
|
|
1361
1389
|
|
|
1362
|
-
# Salvar submissão
|
|
1363
1390
|
submission = self.save_form_submission(form_data, files_data, request)
|
|
1364
|
-
|
|
1365
|
-
# 📧 ENVIAR EMAILS COM SIMPLEEEMAILSERVICE
|
|
1366
1391
|
email_results = self.send_emails_with_service(form_data, submission)
|
|
1367
1392
|
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
# Redirecionar com status dos emails
|
|
1372
|
-
success_url = f'{request.path}?success=1'
|
|
1373
|
-
if email_results.get('user_sent'):
|
|
1374
|
-
success_url += '&email_sent=1'
|
|
1375
|
-
if email_results.get('admin_sent'):
|
|
1376
|
-
success_url += '&admin_notified=1'
|
|
1377
|
-
|
|
1378
|
-
return redirect(success_url)
|
|
1393
|
+
logger.info(f"Submissão {submission.id} processada.")
|
|
1394
|
+
# Redirecionar para página de sucesso
|
|
1395
|
+
return redirect(self.url + '?success=1')
|
|
1379
1396
|
|
|
1380
1397
|
def send_emails_with_service(self, form_data, submission):
|
|
1381
1398
|
"""Envia emails usando SimpleEmailService"""
|
|
@@ -2444,14 +2444,14 @@ class ENAPNoticia(Page):
|
|
|
2444
2444
|
),
|
|
2445
2445
|
]
|
|
2446
2446
|
|
|
2447
|
-
def save(self, *args, **kwargs):
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
def desmarcar_destaques(self):
|
|
2453
|
-
|
|
2454
|
-
|
|
2447
|
+
# def save(self, *args, **kwargs):
|
|
2448
|
+
# if self.destaque_fixo:
|
|
2449
|
+
# self.desmarcar_destaques()
|
|
2450
|
+
# super().save(*args, **kwargs)
|
|
2451
|
+
|
|
2452
|
+
# def desmarcar_destaques(self):
|
|
2453
|
+
# ENAPNoticia.objects.all().update(destaque_fixo=False)
|
|
2454
|
+
# self.destaque_fixo=True
|
|
2455
2455
|
|
|
2456
2456
|
@property
|
|
2457
2457
|
def titulo_filter(self):
|
|
@@ -2555,14 +2555,13 @@ class ENAPNoticia(Page):
|
|
|
2555
2555
|
return cls.objects.filter(
|
|
2556
2556
|
live=True,
|
|
2557
2557
|
destaque_fixo=True
|
|
2558
|
-
).first()
|
|
2558
|
+
).order_by('-date_display', '-first_published_at').first()
|
|
2559
2559
|
|
|
2560
2560
|
@classmethod
|
|
2561
2561
|
def get_noticias_normais(cls, limit=5):
|
|
2562
2562
|
"""Retorna outras notícias (sem a de destaque) ordenadas por data"""
|
|
2563
2563
|
return cls.objects.filter(
|
|
2564
|
-
live=True
|
|
2565
|
-
destaque_fixo=False
|
|
2564
|
+
live=True
|
|
2566
2565
|
).order_by('-date_display', '-first_published_at')[:limit]
|
|
2567
2566
|
|
|
2568
2567
|
@classmethod
|
|
@@ -2572,13 +2571,12 @@ class ENAPNoticia(Page):
|
|
|
2572
2571
|
depois as outras por ordem cronológica
|
|
2573
2572
|
"""
|
|
2574
2573
|
destaque = cls.get_noticia_destaque()
|
|
2575
|
-
normais = cls.get_noticias_normais(limit
|
|
2574
|
+
normais = list(cls.get_noticias_normais(limit))
|
|
2576
2575
|
|
|
2577
|
-
if destaque:
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
else
|
|
2581
|
-
return list(normais)
|
|
2576
|
+
if destaque and destaque in normais:
|
|
2577
|
+
normais.remove(destaque)
|
|
2578
|
+
|
|
2579
|
+
return [destaque] + normais if destaque else normais
|
|
2582
2580
|
|
|
2583
2581
|
search_fields = Page.search_fields + [
|
|
2584
2582
|
index.SearchField("title", boost=3),
|
|
@@ -1843,20 +1843,14 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1843
1843
|
}
|
|
1844
1844
|
|
|
1845
1845
|
if (e.target.classList.contains('phone-field')) {
|
|
1846
|
-
// Remove todos os caracteres não numéricos
|
|
1847
1846
|
let value = e.target.value.replace(/[^\d]/g, '');
|
|
1848
|
-
|
|
1849
|
-
// Formato com apenas espaços
|
|
1850
1847
|
if (value.length <= 10) {
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
value = value.replace(/(\d{2})(\d{0,4})(\d{0,4})/, '$1 $2 $3').trim();
|
|
1854
|
-
}
|
|
1848
|
+
value = value.replace(/(\d{2})(\d)/, '$1 $2');
|
|
1849
|
+
value = value.replace(/(\d{4})(\d)/, '$1 $2');
|
|
1855
1850
|
} else {
|
|
1856
|
-
|
|
1857
|
-
value = value.replace(/(\d{
|
|
1851
|
+
value = value.replace(/(\d{2})(\d)/, '$1 $2');
|
|
1852
|
+
value = value.replace(/(\d{5})(\d)/, '$1 $2');
|
|
1858
1853
|
}
|
|
1859
|
-
|
|
1860
1854
|
e.target.value = value;
|
|
1861
1855
|
}
|
|
1862
1856
|
});
|
|
@@ -1893,37 +1887,169 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1893
1887
|
});
|
|
1894
1888
|
|
|
1895
1889
|
// FUNÇÕES DE UPLOAD (mantém as existentes)
|
|
1890
|
+
// Variável global para armazenar arquivos
|
|
1891
|
+
const selectedFilesMap = new Map();
|
|
1892
|
+
|
|
1893
|
+
// Função para atualizar o nome do arquivo
|
|
1896
1894
|
function updateFileName(input) {
|
|
1897
1895
|
const fieldId = input.id;
|
|
1898
1896
|
const displayDiv = document.getElementById(`file-display-${fieldId}`);
|
|
1899
1897
|
const errorDiv = document.getElementById(`file-error-${fieldId}`);
|
|
1900
1898
|
const dropzone = document.getElementById(`dropzone-${fieldId}`);
|
|
1901
1899
|
|
|
1900
|
+
// Inicializar o armazenamento para este campo se não existir
|
|
1901
|
+
if (!selectedFilesMap.has(fieldId)) {
|
|
1902
|
+
selectedFilesMap.set(fieldId, new DataTransfer());
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
// Obter o armazenamento atual
|
|
1906
|
+
let dataTransfer = selectedFilesMap.get(fieldId);
|
|
1907
|
+
|
|
1908
|
+
// Limpar mensagens de erro
|
|
1902
1909
|
errorDiv.style.display = 'none';
|
|
1903
1910
|
errorDiv.textContent = '';
|
|
1904
1911
|
|
|
1912
|
+
// Verificar novos arquivos
|
|
1905
1913
|
if (input.files && input.files.length > 0) {
|
|
1906
1914
|
const maxSize = parseInt(input.dataset.maxSize) * 1024 * 1024;
|
|
1907
|
-
const
|
|
1915
|
+
const maxFiles = parseInt(input.dataset.maxFiles || 5);
|
|
1908
1916
|
|
|
1909
|
-
|
|
1910
|
-
|
|
1917
|
+
// Verificar se excederia o limite de arquivos
|
|
1918
|
+
if (dataTransfer.files.length + input.files.length > maxFiles) {
|
|
1919
|
+
errorDiv.textContent = `Máximo de ${maxFiles} arquivo(s) permitido(s)`;
|
|
1911
1920
|
errorDiv.style.display = 'block';
|
|
1912
|
-
input.value = '';
|
|
1913
1921
|
return;
|
|
1914
1922
|
}
|
|
1915
1923
|
|
|
1924
|
+
// Validar e adicionar cada novo arquivo
|
|
1925
|
+
for (let i = 0; i < input.files.length; i++) {
|
|
1926
|
+
const file = input.files[i];
|
|
1927
|
+
|
|
1928
|
+
// Verificar tamanho
|
|
1929
|
+
if (file.size > maxSize) {
|
|
1930
|
+
errorDiv.textContent = `Arquivo "${file.name}" excede ${input.dataset.maxSize}MB`;
|
|
1931
|
+
errorDiv.style.display = 'block';
|
|
1932
|
+
continue;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
// Verificar se já existe um arquivo com esse nome
|
|
1936
|
+
let fileExists = false;
|
|
1937
|
+
for (let j = 0; j < dataTransfer.files.length; j++) {
|
|
1938
|
+
if (dataTransfer.files[j].name === file.name) {
|
|
1939
|
+
fileExists = true;
|
|
1940
|
+
break;
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
if (!fileExists) {
|
|
1945
|
+
// Adicionar ao DataTransfer
|
|
1946
|
+
dataTransfer.items.add(file);
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
// Atualizar o campo de input com os arquivos acumulados
|
|
1951
|
+
input.files = dataTransfer.files;
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
// Atualizar a exibição dos arquivos
|
|
1955
|
+
updateFilesDisplay(fieldId);
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
// Função para atualizar a exibição dos arquivos
|
|
1959
|
+
function updateFilesDisplay(fieldId) {
|
|
1960
|
+
const displayDiv = document.getElementById(`file-display-${fieldId}`);
|
|
1961
|
+
const input = document.getElementById(fieldId);
|
|
1962
|
+
const dataTransfer = selectedFilesMap.get(fieldId);
|
|
1963
|
+
|
|
1964
|
+
if (!dataTransfer || dataTransfer.files.length === 0) {
|
|
1965
|
+
displayDiv.innerHTML = '';
|
|
1966
|
+
displayDiv.style.display = 'none';
|
|
1967
|
+
return;
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
let html = '';
|
|
1971
|
+
let totalSize = 0;
|
|
1972
|
+
|
|
1973
|
+
// Criar HTML para cada arquivo
|
|
1974
|
+
for (let i = 0; i < dataTransfer.files.length; i++) {
|
|
1975
|
+
const file = dataTransfer.files[i];
|
|
1976
|
+
totalSize += file.size;
|
|
1977
|
+
|
|
1916
1978
|
const fileSize = (file.size / (1024 * 1024)).toFixed(2);
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
<span style="
|
|
1922
|
-
<span style="
|
|
1979
|
+
const fileIcon = getFileIcon(file.name);
|
|
1980
|
+
|
|
1981
|
+
html += `
|
|
1982
|
+
<div class="file-item" style="display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem; background: #f8f9fa; border-radius: 4px; margin-bottom: 0.5rem;">
|
|
1983
|
+
<span style="font-size: 1.2rem;">${fileIcon}</span>
|
|
1984
|
+
<span style="flex: 1; overflow: hidden; text-overflow: ellipsis;">${file.name}</span>
|
|
1985
|
+
<span style="color: #666; font-size: 0.8rem; white-space: nowrap;">${fileSize}MB</span>
|
|
1986
|
+
<button type="button" class="remove-file-btn"
|
|
1987
|
+
style="background: #dc3545; color: white; border: none; width: 24px; height: 24px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; font-weight: bold;"
|
|
1988
|
+
onclick="removeFile('${fieldId}', ${i})">×</button>
|
|
1989
|
+
</div>
|
|
1990
|
+
`;
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
// Adicionar resumo para múltiplos arquivos
|
|
1994
|
+
if (dataTransfer.files.length > 1) {
|
|
1995
|
+
const totalSizeMB = (totalSize / (1024 * 1024)).toFixed(2);
|
|
1996
|
+
html += `
|
|
1997
|
+
<div style="text-align: right; margin-top: 5px; padding: 3px 8px; background: #f0f0f0; border-radius: 4px;">
|
|
1998
|
+
<span style="font-size: 0.9rem; font-weight: 500;">${dataTransfer.files.length} arquivos (${totalSizeMB}MB total)</span>
|
|
1923
1999
|
</div>
|
|
1924
2000
|
`;
|
|
1925
|
-
displayDiv.style.display = 'block';
|
|
1926
2001
|
}
|
|
2002
|
+
|
|
2003
|
+
// Atualizar o display
|
|
2004
|
+
displayDiv.innerHTML = html;
|
|
2005
|
+
displayDiv.style.display = 'block';
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
// Função para remover um arquivo específico
|
|
2009
|
+
function removeFile(fieldId, index) {
|
|
2010
|
+
if (!selectedFilesMap.has(fieldId)) return;
|
|
2011
|
+
|
|
2012
|
+
const dataTransfer = selectedFilesMap.get(fieldId);
|
|
2013
|
+
const newDataTransfer = new DataTransfer();
|
|
2014
|
+
|
|
2015
|
+
// Copiar todos os arquivos exceto o que deve ser removido
|
|
2016
|
+
for (let i = 0; i < dataTransfer.files.length; i++) {
|
|
2017
|
+
if (i !== index) {
|
|
2018
|
+
newDataTransfer.items.add(dataTransfer.files[i]);
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
// Atualizar a lista de arquivos
|
|
2023
|
+
selectedFilesMap.set(fieldId, newDataTransfer);
|
|
2024
|
+
|
|
2025
|
+
// Atualizar o campo input
|
|
2026
|
+
const input = document.getElementById(fieldId);
|
|
2027
|
+
input.files = newDataTransfer.files;
|
|
2028
|
+
|
|
2029
|
+
// Atualizar a exibição
|
|
2030
|
+
updateFilesDisplay(fieldId);
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
// Função para tratar o drop de arquivos
|
|
2034
|
+
function handleFileDrop(e, inputId) {
|
|
2035
|
+
e.preventDefault();
|
|
2036
|
+
e.stopPropagation();
|
|
2037
|
+
|
|
2038
|
+
const input = document.getElementById(inputId);
|
|
2039
|
+
const files = e.dataTransfer.files;
|
|
2040
|
+
|
|
2041
|
+
// Criar uma cópia dos arquivos para o input
|
|
2042
|
+
const tempTransfer = new DataTransfer();
|
|
2043
|
+
for (let i = 0; i < files.length; i++) {
|
|
2044
|
+
tempTransfer.items.add(files[i]);
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
input.files = tempTransfer.files;
|
|
2048
|
+
updateFileName(input);
|
|
2049
|
+
|
|
2050
|
+
// Resetar visual
|
|
2051
|
+
e.currentTarget.style.borderColor = '#C8D1E0';
|
|
2052
|
+
e.currentTarget.style.background = '#f8f9fa';
|
|
1927
2053
|
}
|
|
1928
2054
|
|
|
1929
2055
|
function getFileIcon(filename) {
|
|
@@ -1196,14 +1196,14 @@
|
|
|
1196
1196
|
|
|
1197
1197
|
<input
|
|
1198
1198
|
type="file"
|
|
1199
|
-
id="{{
|
|
1200
|
-
name="{{
|
|
1199
|
+
id="{{ block.block_type }}_{{ block.id }}"
|
|
1200
|
+
name="{{ block.block_type }}_{{ block.id }}"
|
|
1201
1201
|
style="display: none;"
|
|
1202
|
-
{% if
|
|
1203
|
-
{% if
|
|
1204
|
-
accept="
|
|
1205
|
-
data-max-size="{{
|
|
1206
|
-
{% if
|
|
1202
|
+
{% if block.value.required %}required{% endif %}
|
|
1203
|
+
{% if block.value.multiple_files|default:False %}multiple{% endif %}
|
|
1204
|
+
accept="..."
|
|
1205
|
+
data-max-size="{{ block.value.max_size_mb }}"
|
|
1206
|
+
{% if block.value.multiple_files|default:False %}data-max-files="{{ block.value.max_files|default:3 }}"{% endif %}
|
|
1207
1207
|
onchange="updateFileName(this)"
|
|
1208
1208
|
>
|
|
1209
1209
|
|
|
@@ -1971,7 +1971,7 @@
|
|
|
1971
1971
|
<input
|
|
1972
1972
|
type="file"
|
|
1973
1973
|
id="{{ block.block_type }}_{{ block.id }}"
|
|
1974
|
-
name="{{ block.block_type }}_{{ block.id }}"
|
|
1974
|
+
name="{{ block.block_type }}_{{ block.id }}{% if block.value.multiple_files|default:False %}[]{% endif %}"
|
|
1975
1975
|
style="display: none;"
|
|
1976
1976
|
{% if block.value.required %}required{% endif %}
|
|
1977
1977
|
{% if block.value.multiple_files|default:False %}multiple{% endif %}
|
|
@@ -2353,129 +2353,104 @@
|
|
|
2353
2353
|
{% endif %}
|
|
2354
2354
|
|
|
2355
2355
|
<script>
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2356
|
+
// FUNÇÃO DE UPLOAD CORRIGIDA
|
|
2357
|
+
function updateFileName(input) {
|
|
2358
|
+
console.log("Função updateFileName chamada"); // Log para debug
|
|
2359
|
+
|
|
2360
|
+
const fieldId = input.id;
|
|
2361
|
+
const displayDiv = document.getElementById(`file-display-${fieldId}`);
|
|
2362
|
+
const errorDiv = document.getElementById(`file-error-${fieldId}`);
|
|
2363
|
+
const dropzone = document.getElementById(`dropzone-${fieldId}`);
|
|
2364
|
+
|
|
2365
|
+
console.log("Files selecionados:", input.files.length); // Log para debug
|
|
2366
|
+
console.log("Multiple?", input.multiple); // Log para debug
|
|
2367
|
+
|
|
2368
|
+
// Limpar erros anteriores
|
|
2369
|
+
errorDiv.style.display = 'none';
|
|
2370
|
+
errorDiv.textContent = '';
|
|
2371
|
+
displayDiv.innerHTML = ''; // Limpar a área de exibição
|
|
2372
|
+
|
|
2373
|
+
if (input.files && input.files.length > 0) {
|
|
2374
|
+
const maxSize = parseInt(input.dataset.maxSize) * 1024 * 1024;
|
|
2375
|
+
const maxFiles = input.multiple ? (parseInt(input.dataset.maxFiles) || 5) : 1;
|
|
2361
2376
|
|
|
2362
|
-
//
|
|
2363
|
-
|
|
2364
|
-
|
|
2377
|
+
// Verificar se excedeu o número máximo de arquivos
|
|
2378
|
+
if (input.files.length > maxFiles) {
|
|
2379
|
+
errorDiv.textContent = `Máximo de ${maxFiles} arquivo(s) permitido(s)`;
|
|
2380
|
+
errorDiv.style.display = 'block';
|
|
2381
|
+
input.value = '';
|
|
2382
|
+
return;
|
|
2383
|
+
}
|
|
2365
2384
|
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
errorMessages.push(`Máximo ${maxFiles} arquivo(s) permitido(s)`);
|
|
2376
|
-
hasError = true;
|
|
2377
|
-
}
|
|
2385
|
+
// Verificar tamanho de cada arquivo
|
|
2386
|
+
let totalSize = 0;
|
|
2387
|
+
let fileHtml = '';
|
|
2388
|
+
let errors = [];
|
|
2389
|
+
|
|
2390
|
+
// Processar cada arquivo
|
|
2391
|
+
for (let i = 0; i < input.files.length; i++) {
|
|
2392
|
+
const file = input.files[i];
|
|
2393
|
+
totalSize += file.size;
|
|
2378
2394
|
|
|
2379
|
-
// Verificar
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
// Verificar tamanho
|
|
2385
|
-
if (file.size > maxSize) {
|
|
2386
|
-
errorMessages.push(`"${file.name}" excede ${input.dataset.maxSize}MB`);
|
|
2387
|
-
hasError = true;
|
|
2388
|
-
continue;
|
|
2389
|
-
}
|
|
2390
|
-
|
|
2391
|
-
validFiles.push(file);
|
|
2395
|
+
// Verificar tamanho individual
|
|
2396
|
+
if (file.size > maxSize) {
|
|
2397
|
+
errors.push(`Arquivo "${file.name}" excede ${input.dataset.maxSize}MB`);
|
|
2398
|
+
continue;
|
|
2392
2399
|
}
|
|
2393
2400
|
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
dropzone.style.borderColor = '#dc3545';
|
|
2398
|
-
dropzone.style.background = '#fff5f5';
|
|
2399
|
-
input.value = ''; // Limpar seleção
|
|
2400
|
-
displayDiv.style.display = 'none';
|
|
2401
|
-
return;
|
|
2402
|
-
}
|
|
2401
|
+
// Adicionar à lista de exibição
|
|
2402
|
+
const fileSize = (file.size / (1024 * 1024)).toFixed(2);
|
|
2403
|
+
const fileIcon = getFileIcon(file.name);
|
|
2403
2404
|
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
displayDiv.style.display = 'block';
|
|
2421
|
-
|
|
2422
|
-
// Atualizar visual do dropzone
|
|
2423
|
-
dropzone.style.borderColor = '#28a745';
|
|
2424
|
-
dropzone.style.background = '#f8fff8';
|
|
2425
|
-
|
|
2426
|
-
} else {
|
|
2427
|
-
displayDiv.style.display = 'none';
|
|
2428
|
-
dropzone.style.borderColor = '#C8D1E0';
|
|
2429
|
-
dropzone.style.background = '#f8f9fa';
|
|
2405
|
+
fileHtml += `
|
|
2406
|
+
<div style="display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem; background: #f8f9fa; border-radius: 4px; margin-bottom: 0.5rem;">
|
|
2407
|
+
<span style="font-size: 1.2rem;">${fileIcon}</span>
|
|
2408
|
+
<span style="flex: 1; overflow: hidden; text-overflow: ellipsis;">${file.name}</span>
|
|
2409
|
+
<span style="color: #666; font-size: 0.8rem; white-space: nowrap;">${fileSize}MB</span>
|
|
2410
|
+
<span style="color: #28a745; font-weight: bold;">✓</span>
|
|
2411
|
+
</div>
|
|
2412
|
+
`;
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
// Se houver erros, mostrar e abortar
|
|
2416
|
+
if (errors.length > 0) {
|
|
2417
|
+
errorDiv.textContent = errors.join('; ');
|
|
2418
|
+
errorDiv.style.display = 'block';
|
|
2419
|
+
input.value = '';
|
|
2420
|
+
return;
|
|
2430
2421
|
}
|
|
2431
|
-
}
|
|
2432
|
-
|
|
2433
|
-
// Função para obter ícone baseado na extensão
|
|
2434
|
-
function getFileIcon(filename) {
|
|
2435
|
-
const ext = filename.split('.').pop().toLowerCase();
|
|
2436
|
-
const icons = {
|
|
2437
|
-
'pdf': '📄',
|
|
2438
|
-
'doc': '📝', 'docx': '📝',
|
|
2439
|
-
'xls': '📊', 'xlsx': '📊',
|
|
2440
|
-
'jpg': '🖼️', 'jpeg': '🖼️', 'png': '🖼️', 'gif': '🖼️',
|
|
2441
|
-
'txt': '📄',
|
|
2442
|
-
'csv': '📋'
|
|
2443
|
-
};
|
|
2444
|
-
return icons[ext] || '📎';
|
|
2445
|
-
}
|
|
2446
|
-
|
|
2447
|
-
// Drag and Drop
|
|
2448
|
-
function handleDragOver(e) {
|
|
2449
|
-
e.preventDefault();
|
|
2450
|
-
e.stopPropagation();
|
|
2451
|
-
e.currentTarget.style.borderColor = '#007bff';
|
|
2452
|
-
e.currentTarget.style.background = '#f0f8ff';
|
|
2453
|
-
}
|
|
2454
|
-
|
|
2455
|
-
function handleDragLeave(e) {
|
|
2456
|
-
e.preventDefault();
|
|
2457
|
-
e.stopPropagation();
|
|
2458
|
-
e.currentTarget.style.borderColor = '#C8D1E0';
|
|
2459
|
-
e.currentTarget.style.background = '#f8f9fa';
|
|
2460
|
-
}
|
|
2461
|
-
|
|
2462
|
-
function handleFileDrop(e, inputId) {
|
|
2463
|
-
e.preventDefault();
|
|
2464
|
-
e.stopPropagation();
|
|
2465
2422
|
|
|
2466
|
-
|
|
2467
|
-
|
|
2423
|
+
// Se tudo estiver ok, exibir os arquivos
|
|
2424
|
+
displayDiv.innerHTML = fileHtml;
|
|
2468
2425
|
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2426
|
+
// Adicionar resumo para múltiplos arquivos
|
|
2427
|
+
if (input.files.length > 1) {
|
|
2428
|
+
const totalSizeMB = (totalSize / (1024 * 1024)).toFixed(2);
|
|
2429
|
+
const summaryDiv = document.createElement('div');
|
|
2430
|
+
summaryDiv.style.textAlign = 'right';
|
|
2431
|
+
summaryDiv.style.padding = '0.3rem 0.5rem';
|
|
2432
|
+
summaryDiv.style.fontSize = '0.9rem';
|
|
2433
|
+
summaryDiv.style.fontWeight = 'bold';
|
|
2434
|
+
summaryDiv.style.color = '#2A5E2C';
|
|
2435
|
+
summaryDiv.style.background = '#f0f8f0';
|
|
2436
|
+
summaryDiv.style.borderRadius = '4px';
|
|
2437
|
+
summaryDiv.style.marginTop = '0.5rem';
|
|
2438
|
+
summaryDiv.textContent = `${input.files.length} arquivos (${totalSizeMB}MB total)`;
|
|
2439
|
+
displayDiv.appendChild(summaryDiv);
|
|
2473
2440
|
}
|
|
2474
2441
|
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2442
|
+
displayDiv.style.display = 'block';
|
|
2443
|
+
|
|
2444
|
+
// Atualizar visual do dropzone
|
|
2445
|
+
dropzone.style.borderColor = '#28a745';
|
|
2446
|
+
dropzone.style.background = '#f8fff8';
|
|
2447
|
+
} else {
|
|
2448
|
+
// Não há arquivos selecionados
|
|
2449
|
+
displayDiv.style.display = 'none';
|
|
2450
|
+
dropzone.style.borderColor = '#C8D1E0';
|
|
2451
|
+
dropzone.style.background = '#f8f9fa';
|
|
2478
2452
|
}
|
|
2453
|
+
}
|
|
2479
2454
|
|
|
2480
2455
|
// Atualizar texto de rating
|
|
2481
2456
|
document.addEventListener('click', function(e) {
|
|
@@ -17,7 +17,7 @@ from django.conf import settings
|
|
|
17
17
|
import os
|
|
18
18
|
from wagtail import hooks
|
|
19
19
|
from django.contrib.contenttypes.models import ContentType
|
|
20
|
-
|
|
20
|
+
import re
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
|
|
@@ -63,7 +63,7 @@ def add_export_button():
|
|
|
63
63
|
# VIEWS DE DOWNLOAD DE ARQUIVOS - CORRIGIDAS
|
|
64
64
|
# ===============================================
|
|
65
65
|
def download_form_file(request, page_id, submission_id, field_name):
|
|
66
|
-
"""Download de arquivo do FormularioSubmission tradicional - CORRIGIDA"""
|
|
66
|
+
"""Download de arquivo do FormularioSubmission tradicional - CORRIGIDA PARA MÚLTIPLOS ARQUIVOS"""
|
|
67
67
|
try:
|
|
68
68
|
print(f"🚀 INICIANDO DOWNLOAD:")
|
|
69
69
|
print(f" submission_id: {submission_id}")
|
|
@@ -78,6 +78,33 @@ def download_form_file(request, page_id, submission_id, field_name):
|
|
|
78
78
|
print("❌ ERRO: Usuário sem permissão")
|
|
79
79
|
raise Http404("Sem permissão")
|
|
80
80
|
|
|
81
|
+
# Verificar se é parte de um campo de múltiplos arquivos
|
|
82
|
+
is_multiple_item = '_' in field_name and field_name.split('_')[-1].isdigit()
|
|
83
|
+
original_filename = None
|
|
84
|
+
|
|
85
|
+
if is_multiple_item:
|
|
86
|
+
# Extrair o nome base do campo e índice
|
|
87
|
+
parts = field_name.split('_')
|
|
88
|
+
index = int(parts[-1])
|
|
89
|
+
base_field_name = '_'.join(parts[:-1])
|
|
90
|
+
|
|
91
|
+
print(f"🔍 Campo múltiplo detectado: base={base_field_name}, índice={index}")
|
|
92
|
+
|
|
93
|
+
# Buscar no campo base que contém a lista de arquivos
|
|
94
|
+
if base_field_name in submission.form_data:
|
|
95
|
+
files_list = submission.form_data[base_field_name]
|
|
96
|
+
if isinstance(files_list, list) and len(files_list) > index:
|
|
97
|
+
file_info = files_list[index]
|
|
98
|
+
if isinstance(file_info, dict) and 'filename' in file_info:
|
|
99
|
+
original_filename = file_info['filename']
|
|
100
|
+
print(f"✅ Nome encontrado na lista: {original_filename}")
|
|
101
|
+
|
|
102
|
+
# Se não conseguiu determinar o nome, usar lógica padrão
|
|
103
|
+
if not original_filename:
|
|
104
|
+
form_data = submission.form_data or {}
|
|
105
|
+
field_data = form_data.get(field_name, {})
|
|
106
|
+
original_filename = field_data.get('filename', os.path.basename(field_name)) if isinstance(field_data, dict) else os.path.basename(field_name)
|
|
107
|
+
|
|
81
108
|
print("🔍 Chamando find_file_path_traditional...")
|
|
82
109
|
file_path = find_file_path_traditional(submission, field_name, page_id)
|
|
83
110
|
print(f"📂 Resultado: {file_path}")
|
|
@@ -85,7 +112,7 @@ def download_form_file(request, page_id, submission_id, field_name):
|
|
|
85
112
|
if not file_path:
|
|
86
113
|
print("❌ ERRO: Arquivo não encontrado")
|
|
87
114
|
|
|
88
|
-
folder_path = os.path.join(settings.MEDIA_ROOT, 'form_submissions', str(submission_id))
|
|
115
|
+
folder_path = os.path.join(settings.MEDIA_ROOT, 'form_submissions', str(page_id), str(submission_id))
|
|
89
116
|
print(f"🔍 Verificando pasta: {folder_path}")
|
|
90
117
|
|
|
91
118
|
if os.path.exists(folder_path):
|
|
@@ -101,11 +128,6 @@ def download_form_file(request, page_id, submission_id, field_name):
|
|
|
101
128
|
|
|
102
129
|
raise Http404("Arquivo não encontrado")
|
|
103
130
|
|
|
104
|
-
# Nome original do arquivo
|
|
105
|
-
form_data = submission.form_data or {}
|
|
106
|
-
field_data = form_data.get(field_name, {})
|
|
107
|
-
original_filename = field_data.get('filename', os.path.basename(file_path)) if isinstance(field_data, dict) else os.path.basename(file_path)
|
|
108
|
-
|
|
109
131
|
print(f"📎 Nome original: {original_filename}")
|
|
110
132
|
print(f"🎯 Retornando arquivo: {file_path}")
|
|
111
133
|
|
|
@@ -120,6 +142,7 @@ def download_form_file(request, page_id, submission_id, field_name):
|
|
|
120
142
|
import traceback
|
|
121
143
|
print(f"🔥 TRACEBACK: {traceback.format_exc()}")
|
|
122
144
|
raise Http404(f"Erro ao baixar arquivo: {e}")
|
|
145
|
+
|
|
123
146
|
|
|
124
147
|
|
|
125
148
|
def verificar_arquivos_tradicionais():
|
|
@@ -377,53 +400,142 @@ def find_file_path_dynamic(submission, field_name):
|
|
|
377
400
|
def format_field_value_for_csv(field_name, value, page_id, submission=None, request=None):
|
|
378
401
|
"""Formata valores para CSV com links de download quando possível"""
|
|
379
402
|
|
|
380
|
-
|
|
381
|
-
|
|
403
|
+
# DEPURAÇÃO: Imprimir tipo e valor para diagnóstico
|
|
404
|
+
print(f"CSV: Campo {field_name}, tipo: {type(value)}, valor: {value}")
|
|
382
405
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
406
|
+
# CASO 1: Lista de dicionários (múltiplos arquivos)
|
|
407
|
+
if isinstance(value, list) and len(value) > 0 and isinstance(value[0], dict) and 'filename' in value[0]:
|
|
408
|
+
print(f"📋 Processando LISTA de arquivos para campo: {field_name}")
|
|
386
409
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
410
|
+
file_entries = []
|
|
411
|
+
for i, file_dict in enumerate(value):
|
|
412
|
+
filename = file_dict.get('filename', '')
|
|
413
|
+
size = file_dict.get('size', 0)
|
|
414
|
+
|
|
415
|
+
# Formatar tamanho
|
|
416
|
+
size_info = ""
|
|
417
|
+
if size:
|
|
418
|
+
size_mb = round(size / (1024 * 1024), 2)
|
|
419
|
+
size_info = f" ({size_mb} MB)"
|
|
420
|
+
|
|
421
|
+
# Inicializar download_url
|
|
422
|
+
download_url = None
|
|
423
|
+
|
|
424
|
+
# Tentar criar URL de download
|
|
425
|
+
if submission and request:
|
|
426
|
+
try:
|
|
427
|
+
# Usar índice específico no nome do campo
|
|
394
428
|
download_url = request.build_absolute_uri(
|
|
395
429
|
reverse('download_form_file', kwargs={
|
|
430
|
+
'page_id': page_id,
|
|
396
431
|
'submission_id': submission.id,
|
|
397
|
-
'field_name': field_name
|
|
398
|
-
'page_id': page_id
|
|
399
|
-
})
|
|
400
|
-
)
|
|
401
|
-
else:
|
|
402
|
-
# FormularioDinamicoSubmission
|
|
403
|
-
download_url = request.build_absolute_uri(
|
|
404
|
-
reverse('download_dynamic_file', kwargs={
|
|
405
|
-
'submission_id': submission.id,
|
|
406
|
-
'field_name': field_name,
|
|
407
|
-
'page_id': page_id
|
|
432
|
+
'field_name': f"{field_name}_{i}"
|
|
408
433
|
})
|
|
409
434
|
)
|
|
410
|
-
|
|
411
|
-
|
|
435
|
+
except Exception as e:
|
|
436
|
+
print(f"⚠️ Erro ao criar URL de download para {filename}: {e}")
|
|
437
|
+
|
|
438
|
+
# Adicionar entrada formatada
|
|
439
|
+
if download_url:
|
|
440
|
+
file_entries.append(f"{filename}{size_info} - DOWNLOAD: {download_url}")
|
|
441
|
+
else:
|
|
442
|
+
file_entries.append(f"ARQUIVO: {filename}{size_info}")
|
|
443
|
+
|
|
444
|
+
# Juntar todas as entradas com separador
|
|
445
|
+
return " | ".join(file_entries)
|
|
446
|
+
|
|
447
|
+
# CASO 2: Verificar submissão diretamente para arquivos múltiplos
|
|
448
|
+
# Este caso é para quando os arquivos estão armazenados individualmente na submissão
|
|
449
|
+
elif submission and submission.form_data:
|
|
450
|
+
multiple_files = []
|
|
451
|
+
pattern = re.compile(f"^{re.escape(field_name)}_\\d+$")
|
|
452
|
+
|
|
453
|
+
# Procurar por campos de múltiplos arquivos (field_name_0, field_name_1, etc.)
|
|
454
|
+
for key in submission.form_data.keys():
|
|
455
|
+
if pattern.match(key):
|
|
456
|
+
file_data = submission.form_data[key]
|
|
457
|
+
if isinstance(file_data, dict) and 'filename' in file_data:
|
|
458
|
+
try:
|
|
459
|
+
index = int(key.split('_')[-1])
|
|
460
|
+
|
|
461
|
+
filename = file_data.get('filename', '')
|
|
462
|
+
size = file_data.get('size', 0)
|
|
463
|
+
|
|
464
|
+
size_info = ""
|
|
465
|
+
if size:
|
|
466
|
+
size_mb = round(size / (1024 * 1024), 2)
|
|
467
|
+
size_info = f" ({size_mb} MB)"
|
|
468
|
+
|
|
469
|
+
# Tentar criar URL de download
|
|
470
|
+
download_url = None
|
|
471
|
+
if request:
|
|
472
|
+
try:
|
|
473
|
+
download_url = request.build_absolute_uri(
|
|
474
|
+
reverse('download_form_file', kwargs={
|
|
475
|
+
'page_id': page_id,
|
|
476
|
+
'submission_id': submission.id,
|
|
477
|
+
'field_name': key
|
|
478
|
+
})
|
|
479
|
+
)
|
|
480
|
+
except Exception as e:
|
|
481
|
+
print(f"⚠️ Erro ao criar URL para {filename}: {e}")
|
|
482
|
+
|
|
483
|
+
if download_url:
|
|
484
|
+
multiple_files.append((index, f"{filename}{size_info} - DOWNLOAD: {download_url}"))
|
|
485
|
+
else:
|
|
486
|
+
multiple_files.append((index, f"ARQUIVO: {filename}{size_info}"))
|
|
487
|
+
except Exception as e:
|
|
488
|
+
print(f"Erro ao processar arquivo múltiplo {key}: {e}")
|
|
412
489
|
|
|
413
|
-
#
|
|
490
|
+
# Se encontrou múltiplos arquivos, formatar juntos
|
|
491
|
+
if multiple_files:
|
|
492
|
+
print(f"📋 Encontrados {len(multiple_files)} arquivos para {field_name}")
|
|
493
|
+
# Ordenar por índice
|
|
494
|
+
multiple_files.sort(key=lambda x: x[0])
|
|
495
|
+
return " | ".join([item[1] for item in multiple_files])
|
|
496
|
+
|
|
497
|
+
# CASO 3: Arquivo único como dicionário
|
|
498
|
+
if isinstance(value, dict) and 'filename' in value:
|
|
499
|
+
print(f"📄 Processando arquivo único: {field_name}")
|
|
500
|
+
|
|
501
|
+
filename = value.get('filename', '')
|
|
502
|
+
size = value.get('size', 0)
|
|
503
|
+
|
|
504
|
+
# Formatar tamanho
|
|
505
|
+
size_info = ""
|
|
414
506
|
if size:
|
|
415
507
|
size_mb = round(size / (1024 * 1024), 2)
|
|
416
508
|
size_info = f" ({size_mb} MB)"
|
|
417
|
-
else:
|
|
418
|
-
size_info = ""
|
|
419
509
|
|
|
510
|
+
# Inicializar download_url
|
|
511
|
+
download_url = None
|
|
512
|
+
|
|
513
|
+
# Tentar criar link de download
|
|
514
|
+
if submission and request:
|
|
515
|
+
try:
|
|
516
|
+
download_url = request.build_absolute_uri(
|
|
517
|
+
reverse('download_form_file', kwargs={
|
|
518
|
+
'page_id': page_id,
|
|
519
|
+
'submission_id': submission.id,
|
|
520
|
+
'field_name': field_name
|
|
521
|
+
})
|
|
522
|
+
)
|
|
523
|
+
except Exception as e:
|
|
524
|
+
print(f"⚠️ Erro ao criar URL de download: {e}")
|
|
525
|
+
|
|
526
|
+
# Formatar resposta
|
|
420
527
|
if download_url:
|
|
421
528
|
return f"{filename}{size_info} - DOWNLOAD: {download_url}"
|
|
422
529
|
else:
|
|
423
530
|
return f"ARQUIVO: {filename}{size_info}"
|
|
424
531
|
|
|
425
|
-
|
|
426
|
-
|
|
532
|
+
# CASO 4: Lista genérica (não de arquivos)
|
|
533
|
+
elif isinstance(value, list):
|
|
534
|
+
return ', '.join(str(v) for v in value if v)
|
|
535
|
+
|
|
536
|
+
# CASO 5: Valor padrão para outros tipos
|
|
537
|
+
return str(value) if value else ''
|
|
538
|
+
|
|
427
539
|
|
|
428
540
|
# ===============================================
|
|
429
541
|
# VIEWS DE EXPORTAÇÃO CSV
|
|
@@ -6,13 +6,13 @@ enap_designsystem/settings.py,sha256=gCkWCK4QZlD8i82G8v7aHhKz954KFkY6xdhKNw9CCpw
|
|
|
6
6
|
enap_designsystem/signals.py,sha256=oaHpZms4Dkc97ql-55Q0QxU7-45jwg2Y1XoRDOJ45tc,1978
|
|
7
7
|
enap_designsystem/urls.py,sha256=EJ52w-55BysQU5pTZR4ltMtZM7aSKyjZdnQDGFipDXY,2219
|
|
8
8
|
enap_designsystem/views.py,sha256=7C-juv7sLLDiF8UfZthzbA0lkH1yIYVqiYZK-76lKCk,78334
|
|
9
|
-
enap_designsystem/wagtail_hooks.py,sha256=
|
|
9
|
+
enap_designsystem/wagtail_hooks.py,sha256=0SU5gtFY_9JFRqTKG6QsU8Hzh1qwZvmIydbaw6rlMA4,76939
|
|
10
10
|
enap_designsystem/blocks/__init__.py,sha256=jtlNAEIsIo_KipwQcUMVQuR4vdt4AjrLjag6CFURD6E,39527
|
|
11
11
|
enap_designsystem/blocks/base_blocks.py,sha256=ZuqVWn4PEAvD3pKM1ST7wjo4lwv98ooen_rs15rRJbg,10866
|
|
12
12
|
enap_designsystem/blocks/chatbot_blocks.py,sha256=YeCznrXMbFa9MP9vjdTYl53ZhKsywkGOXvFK2bwcqW0,1133
|
|
13
13
|
enap_designsystem/blocks/content_blocks.py,sha256=X8Ldf6eMRhjhIYxC2rLssb151r2iFFFQ8XxwPpBbjyI,17282
|
|
14
|
-
enap_designsystem/blocks/form.py,sha256=
|
|
15
|
-
enap_designsystem/blocks/html_blocks.py,sha256=
|
|
14
|
+
enap_designsystem/blocks/form.py,sha256=rQ_KfMgafbA7NSBGneUsregEhphKCxfNh4rG8s6FEWI,90007
|
|
15
|
+
enap_designsystem/blocks/html_blocks.py,sha256=YE8xNA8HQ5iavP_UIlJrhwIUpgtfVMQTP3XVk2dg4J0,281986
|
|
16
16
|
enap_designsystem/blocks/layout_blocks.py,sha256=qND7aUna3VL3PK7sAKE7PiPfSvahMwHK_lZoKUkudeo,23461
|
|
17
17
|
enap_designsystem/blocks/security.py,sha256=QA7lmQ_eQ6iopunatl_DrHkEegAwMZJGwXunRulbCjk,2099
|
|
18
18
|
enap_designsystem/blocks/semana_blocks.py,sha256=AfaxJQmStvFkw6yrPeKyZurC6jzCxWxyzmdny_pret0,70929
|
|
@@ -834,7 +834,7 @@ enap_designsystem/templates/enap_designsystem/blocks/suap/apisuap_courses_block.
|
|
|
834
834
|
enap_designsystem/templates/enap_designsystem/blocks/suap/suap_courses_block.html,sha256=_7AC4WBH4qCXmwlKqnRLbPeUnAopLGeKUIrd6FYcvps,16036
|
|
835
835
|
enap_designsystem/templates/enap_designsystem/blocks/suap/suap_events_block.html,sha256=mL2DFQeAuDIx_GyCoEURKmME-Mmd-zQ_NZkO7YW9Z2k,20182
|
|
836
836
|
enap_designsystem/templates/enap_designsystem/form_templates/form_report.html,sha256=WXf4HgNQY0M6zZ-tERqf01mHbGflqWXT96RaJYjCxFA,16081
|
|
837
|
-
enap_designsystem/templates/enap_designsystem/form_templates/formulario_page.html,sha256=
|
|
837
|
+
enap_designsystem/templates/enap_designsystem/form_templates/formulario_page.html,sha256=kDdB_pSFU5_Z4Kh81oSyItDs6xy6U88rJFTfFv91ld0,64367
|
|
838
838
|
enap_designsystem/templates/enap_designsystem/form_templates/formulario_page_landing.html,sha256=2dVaFwunBrHsq0b3rP1buEFxO6hfplFH3-GoUuyLJPo,7598
|
|
839
839
|
enap_designsystem/templates/enap_designsystem/form_templates/formulario_page_success.html,sha256=jFE9GYRxy19ha37pVvucEVYDKTeU56Nav2Fd3phqmZ4,9363
|
|
840
840
|
enap_designsystem/templates/enap_designsystem/form_templates/home_page.html,sha256=BYV5TV6xp0uY3SWtNsAf8p-aDqPiHfM8j4pWbqTUV2M,42329
|
|
@@ -843,7 +843,7 @@ enap_designsystem/templates/enap_designsystem/form_templates/welcome_page.html,s
|
|
|
843
843
|
enap_designsystem/templates/enap_designsystem/includes/chatbot_global.html,sha256=CO7wXrGx1l_icY8vb9OdrILCUXEFBomJPPxQz_e9hq4,12308
|
|
844
844
|
enap_designsystem/templates/enap_designsystem/includes/cookie_banner.html,sha256=vyrvj1W_haSA4oKmQiyjFpjoTFqjPSZfz3u5nfr-P2g,10871
|
|
845
845
|
enap_designsystem/templates/enap_designsystem/includes/footer.html,sha256=qsDmN413A_NNOhRFZz1Uxym1j5UPVhEDuRRDLTgRMPA,4063
|
|
846
|
-
enap_designsystem/templates/enap_designsystem/includes/form_field.html,sha256=
|
|
846
|
+
enap_designsystem/templates/enap_designsystem/includes/form_field.html,sha256=4yT3b5GfhZVST9VEBq1vKtzraW2CPVJY5gRVquadJmU,134614
|
|
847
847
|
enap_designsystem/templates/enap_designsystem/pages/404.html,sha256=v_vUTG27_ohx0_YLcOBrxMG4MYdDT92g3boJE9m8Mrg,2885
|
|
848
848
|
enap_designsystem/templates/enap_designsystem/pages/area_aluno.html,sha256=aWDmOE3Ti0Ct-ztxh7tcgIDGvdij7Heq5gzMyHLjjR0,15775
|
|
849
849
|
enap_designsystem/templates/enap_designsystem/pages/article_index_page.html,sha256=6VjJ3_EroEPCidFCW5gBDzvbi81UcFX9lGpbc4j6r9U,11482
|
|
@@ -934,8 +934,8 @@ enap_designsystem/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
|
934
934
|
enap_designsystem/utils/decorators.py,sha256=aq6SbLn0LcH2rfE3ZFit8jkD7pSx9fLVBUUwVB747hg,335
|
|
935
935
|
enap_designsystem/utils/services.py,sha256=6dG5jLSbwH49jpZV9ZNpWlaZqI49gTlwlr1vaerxdiU,5824
|
|
936
936
|
enap_designsystem/utils/sso.py,sha256=vjAuoYgoLeQAa_dkkyQ6-LmHvKMaVCxizNFpe5y3iUA,1145
|
|
937
|
-
wagtail_enap_designsystem-1.2.1.
|
|
938
|
-
wagtail_enap_designsystem-1.2.1.
|
|
939
|
-
wagtail_enap_designsystem-1.2.1.
|
|
940
|
-
wagtail_enap_designsystem-1.2.1.
|
|
941
|
-
wagtail_enap_designsystem-1.2.1.
|
|
937
|
+
wagtail_enap_designsystem-1.2.1.196.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
|
|
938
|
+
wagtail_enap_designsystem-1.2.1.196.dist-info/METADATA,sha256=Qd_mzE5YjJ5qBZjg23cPheMlCtDXuaeUTxIvSqwrgUQ,3651
|
|
939
|
+
wagtail_enap_designsystem-1.2.1.196.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
940
|
+
wagtail_enap_designsystem-1.2.1.196.dist-info/top_level.txt,sha256=RSFgMASxoA-hVftm5i4Qd0rArlX4Dq08lLv5G4sYD-g,18
|
|
941
|
+
wagtail_enap_designsystem-1.2.1.196.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|