Добавил поис на странице реестра добавил еск для сброса фильтров
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 border-secondary mb-3 shadow-sm">
|
||||||
<div class="card-body py-2">
|
<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">
|
<input type="hidden" name="filtered" value="1">
|
||||||
|
|
||||||
{% if user_role != 'operator' %}
|
{% 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()">
|
<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>
|
||||||
|
|
||||||
<div class="col-md-1 text-end mt-auto">
|
<div class="col-md-auto">
|
||||||
<a href="{% url 'registry' %}?reset=1" class="btn btn-outline-secondary btn-sm w-100" id="registryResetBtn" title="Сброс">
|
<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>Сброс
|
<i class="bi bi-arrow-counterclockwise me-1"></i>Сброс
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -80,10 +93,12 @@
|
|||||||
|
|
||||||
function saveFilters(){
|
function saveFilters(){
|
||||||
if (!form) return;
|
if (!form) return;
|
||||||
|
const qEl = form.querySelector('input[name="q"]');
|
||||||
const data = {
|
const data = {
|
||||||
statuses: Array.from(form.querySelectorAll('input[name="statuses"]:checked')).map(i=>i.value),
|
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),
|
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(_){}
|
try { localStorage.setItem('registry_filters', JSON.stringify(data)); } catch(_){}
|
||||||
}
|
}
|
||||||
@@ -107,6 +122,9 @@
|
|||||||
if (Array.isArray(data.m_ids)){
|
if (Array.isArray(data.m_ids)){
|
||||||
form.querySelectorAll('input[name="m_ids"]').forEach(i=>{ i.checked = data.m_ids.includes(i.value); });
|
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 (s) s.value = data.start_date || weekAgo;
|
||||||
if (e) e.value = today;
|
if (e) e.value = today;
|
||||||
const filtered = form.querySelector('input[name="filtered"]');
|
const filtered = form.querySelector('input[name="filtered"]');
|
||||||
@@ -125,6 +143,19 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -435,6 +435,8 @@ class RegistryView(LoginRequiredMixin, ListView):
|
|||||||
# Диапазон дат, задаваемый пользователем. Если фильтры не активны или явно указан reset=1 — используем дефолты
|
# Диапазон дат, задаваемый пользователем. Если фильтры не активны или явно указан reset=1 — используем дефолты
|
||||||
start_date = self.request.GET.get('start_date')
|
start_date = self.request.GET.get('start_date')
|
||||||
end_date = self.request.GET.get('end_date')
|
end_date = self.request.GET.get('end_date')
|
||||||
|
|
||||||
|
q = (self.request.GET.get('q') or '').strip()
|
||||||
# Дефолтный режим: последние 7 дней и только статус "В работе"
|
# Дефолтный режим: последние 7 дней и только статус "В работе"
|
||||||
is_default = (not filtered) or bool(reset)
|
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':
|
if role == 'operator':
|
||||||
user_machines = profile.machines.all() if profile else Machine.objects.none()
|
user_machines = profile.machines.all() if profile else Machine.objects.none()
|
||||||
queryset = queryset.filter(machine__in=user_machines)
|
queryset = queryset.filter(machine__in=user_machines)
|
||||||
@@ -470,6 +482,7 @@ class RegistryView(LoginRequiredMixin, ListView):
|
|||||||
context['user_role'] = role
|
context['user_role'] = role
|
||||||
context['user_roles'] = sorted(roles)
|
context['user_roles'] = sorted(roles)
|
||||||
context['is_readonly'] = bool(getattr(profile, 'is_readonly', False)) if profile else False
|
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 []
|
allowed_ws = list(profile.allowed_workshops.values_list('id', flat=True)) if profile else []
|
||||||
context['allowed_workshop_ids'] = allowed_ws
|
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')
|
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()]
|
m_ids = [int(i) for i in self.request.GET.getlist('m_ids') if str(i).isdigit()]
|
||||||
if m_ids:
|
if m_ids:
|
||||||
work_qs = work_qs.filter(Q(machine_id__in=m_ids) | Q(machine_id__isnull=True))
|
work_qs = work_qs.filter(Q(machine_id__in=m_ids) | Q(machine_id__isnull=True))
|
||||||
|
|||||||
@@ -161,6 +161,16 @@ body {
|
|||||||
width: 120px;
|
width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.registry-filter-q {
|
||||||
|
width: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
.registry-filter-q {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Специальный класс для центрирования окна логина (вернем его только там) */
|
/* Специальный класс для центрирования окна логина (вернем его только там) */
|
||||||
.sf-attention {
|
.sf-attention {
|
||||||
animation: sfAttentionPulse 1.6s ease-in-out infinite;
|
animation: sfAttentionPulse 1.6s ease-in-out infinite;
|
||||||
|
|||||||
Reference in New Issue
Block a user