Добавил поис на странице реестра добавил еск для сброса фильтров
All checks were successful
Deploy MES Core / deploy (push) Successful in 11s
All checks were successful
Deploy MES Core / deploy (push) Successful in 11s
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<div class="card border-secondary mb-3 shadow-sm">
|
||||
<div class="card-body py-2">
|
||||
<form method="get" id="filter-form" class="row g-2 align-items-center">
|
||||
<form method="get" id="filter-form" class="row g-1 align-items-center">
|
||||
<input type="hidden" name="filtered" value="1">
|
||||
|
||||
{% if user_role != 'operator' %}
|
||||
@@ -53,8 +53,21 @@
|
||||
<input type="date" name="end_date" class="form-control form-control-sm bg-body text-body border-secondary registry-filter-date" value="{{ end_date }}" onchange="this.form.submit()">
|
||||
</div>
|
||||
|
||||
<div class="col-md-1 text-end mt-auto">
|
||||
<a href="{% url 'registry' %}?reset=1" class="btn btn-outline-secondary btn-sm w-100" id="registryResetBtn" title="Сброс">
|
||||
<div class="col-md-auto">
|
||||
<label class="small text-muted mb-1 fw-bold">Поиск:</label>
|
||||
<input
|
||||
type="text"
|
||||
name="q"
|
||||
class="form-control form-control-sm bg-body text-body border-secondary registry-filter-q"
|
||||
value="{{ q|default:'' }}"
|
||||
placeholder="№ сделки / наименование / материал"
|
||||
onkeydown="if(event.key==='Enter'){event.preventDefault(); this.form.submit();}"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-auto text-end">
|
||||
<label class="small text-muted mb-1 fw-bold d-block" style="visibility:hidden;">Сброс</label>
|
||||
<a href="{% url 'registry' %}?reset=1" class="btn btn-outline-secondary btn-sm" id="registryResetBtn" title="Сброс">
|
||||
<i class="bi bi-arrow-counterclockwise me-1"></i>Сброс
|
||||
</a>
|
||||
</div>
|
||||
@@ -80,10 +93,12 @@
|
||||
|
||||
function saveFilters(){
|
||||
if (!form) return;
|
||||
const qEl = form.querySelector('input[name="q"]');
|
||||
const data = {
|
||||
statuses: Array.from(form.querySelectorAll('input[name="statuses"]:checked')).map(i=>i.value),
|
||||
m_ids: Array.from(form.querySelectorAll('input[name="m_ids"]:checked')).map(i=>i.value),
|
||||
start_date: s ? s.value : ''
|
||||
start_date: s ? s.value : '',
|
||||
q: qEl ? (qEl.value || '') : ''
|
||||
};
|
||||
try { localStorage.setItem('registry_filters', JSON.stringify(data)); } catch(_){}
|
||||
}
|
||||
@@ -107,6 +122,9 @@
|
||||
if (Array.isArray(data.m_ids)){
|
||||
form.querySelectorAll('input[name="m_ids"]').forEach(i=>{ i.checked = data.m_ids.includes(i.value); });
|
||||
}
|
||||
const qEl = form.querySelector('input[name="q"]');
|
||||
if (qEl) qEl.value = data.q || '';
|
||||
|
||||
if (s) s.value = data.start_date || weekAgo;
|
||||
if (e) e.value = today;
|
||||
const filtered = form.querySelector('input[name="filtered"]');
|
||||
@@ -116,18 +134,31 @@
|
||||
}
|
||||
|
||||
if (form){
|
||||
form.addEventListener('change', saveFilters, true);
|
||||
form.addEventListener('change', saveFilters, true);
|
||||
|
||||
const resetBtn = document.getElementById('registryResetBtn');
|
||||
if (resetBtn) {
|
||||
resetBtn.addEventListener('click', function () {
|
||||
try { localStorage.removeItem('registry_filters'); } catch(_) {}
|
||||
});
|
||||
const resetBtn = document.getElementById('registryResetBtn');
|
||||
if (resetBtn) {
|
||||
resetBtn.addEventListener('click', function () {
|
||||
try { localStorage.removeItem('registry_filters'); } catch(_) {}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key !== 'Escape') return;
|
||||
if (e.defaultPrevented) return;
|
||||
const active = document.activeElement;
|
||||
if (active && (active.tagName || '').toLowerCase() === 'textarea') return;
|
||||
if (document.querySelector('.modal.show')) return;
|
||||
|
||||
if (resetBtn) {
|
||||
e.preventDefault();
|
||||
resetBtn.click();
|
||||
}
|
||||
}, true);
|
||||
|
||||
restoreFilters();
|
||||
}
|
||||
|
||||
restoreFilters();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
@@ -435,6 +435,8 @@ class RegistryView(LoginRequiredMixin, ListView):
|
||||
# Диапазон дат, задаваемый пользователем. Если фильтры не активны или явно указан reset=1 — используем дефолты
|
||||
start_date = self.request.GET.get('start_date')
|
||||
end_date = self.request.GET.get('end_date')
|
||||
|
||||
q = (self.request.GET.get('q') or '').strip()
|
||||
# Дефолтный режим: последние 7 дней и только статус "В работе"
|
||||
is_default = (not filtered) or bool(reset)
|
||||
|
||||
@@ -451,6 +453,16 @@ class RegistryView(LoginRequiredMixin, ListView):
|
||||
|
||||
|
||||
# Ограничения по ролям
|
||||
if q:
|
||||
queryset = queryset.filter(
|
||||
Q(task__deal__number__icontains=q)
|
||||
| Q(task__drawing_name__icontains=q)
|
||||
| Q(task__entity__name__icontains=q)
|
||||
| Q(task__entity__drawing_number__icontains=q)
|
||||
| Q(task__material__name__icontains=q)
|
||||
| Q(task__material__full_name__icontains=q)
|
||||
)
|
||||
|
||||
if role == 'operator':
|
||||
user_machines = profile.machines.all() if profile else Machine.objects.none()
|
||||
queryset = queryset.filter(machine__in=user_machines)
|
||||
@@ -470,6 +482,7 @@ class RegistryView(LoginRequiredMixin, ListView):
|
||||
context['user_role'] = role
|
||||
context['user_roles'] = sorted(roles)
|
||||
context['is_readonly'] = bool(getattr(profile, 'is_readonly', False)) if profile else False
|
||||
context['q'] = (self.request.GET.get('q') or '').strip()
|
||||
|
||||
allowed_ws = list(profile.allowed_workshops.values_list('id', flat=True)) if profile else []
|
||||
context['allowed_workshop_ids'] = allowed_ws
|
||||
@@ -511,6 +524,16 @@ class RegistryView(LoginRequiredMixin, ListView):
|
||||
|
||||
work_qs = WorkItem.objects.select_related('deal', 'deal__company', 'entity', 'entity__planned_material', 'operation', 'machine', 'workshop')
|
||||
|
||||
q = (self.request.GET.get('q') or '').strip()
|
||||
if q:
|
||||
work_qs = work_qs.filter(
|
||||
Q(deal__number__icontains=q)
|
||||
| Q(entity__name__icontains=q)
|
||||
| Q(entity__drawing_number__icontains=q)
|
||||
| Q(entity__planned_material__name__icontains=q)
|
||||
| Q(entity__planned_material__full_name__icontains=q)
|
||||
)
|
||||
|
||||
m_ids = [int(i) for i in self.request.GET.getlist('m_ids') if str(i).isdigit()]
|
||||
if m_ids:
|
||||
work_qs = work_qs.filter(Q(machine_id__in=m_ids) | Q(machine_id__isnull=True))
|
||||
|
||||
@@ -161,6 +161,16 @@ body {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.registry-filter-q {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.registry-filter-q {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Специальный класс для центрирования окна логина (вернем его только там) */
|
||||
.sf-attention {
|
||||
animation: sfAttentionPulse 1.6s ease-in-out infinite;
|
||||
|
||||
Reference in New Issue
Block a user