filter dashboard indikator pertanian

This commit is contained in:
2026-08-20 17:24:31 +07:00
parent a3f7cb4669
commit 118cda625a
@@ -14,41 +14,37 @@
margin-bottom: .35rem;
}
.indicator-filter-row {
padding-bottom: 1.5rem;
padding-top: 1.5rem;
}
.indicator-filter-bar {
align-items: end;
display: block;
}
.indicator-filter-line {
align-items: center;
display: flex;
flex-wrap: wrap;
gap: .75rem;
margin-bottom: 1.25rem;
gap: .5rem;
}
.indicator-filter-group {
flex: 1 1 150px;
min-width: 150px;
}
.indicator-filter-actions {
.indicator-filter-section-label {
align-items: center;
display: flex;
flex: 999 1 240px;
gap: .75rem;
justify-content: space-between;
font-weight: 500;
margin-right: .5rem;
white-space: nowrap;
}
.indicator-filter-primary-actions {
display: flex;
gap: .75rem;
}
.indicator-filter-label {
color: var(--bs-body-color);
font-size: .75rem;
font-weight: 600;
margin-bottom: .3rem;
.indicator-filter-export-action {
margin-left: auto;
}
.indicator-filter-bar .form-select,
.indicator-filter-bar .btn {
min-height: 38px;
min-height: 31px;
}
.indicator-filter-bar .form-select {
@@ -56,15 +52,10 @@
border-color: var(--bs-border-color);
border-radius: var(--bs-border-radius);
color: var(--bs-body-color);
font-size: .8125rem;
padding-bottom: .375rem;
padding-top: .375rem;
}
.indicator-filter-bar .btn {
font-size: .8125rem;
padding-bottom: .375rem;
padding-top: .375rem;
white-space: nowrap;
}
.indicator-filter-bar .form-select:focus {
@@ -90,29 +81,16 @@
color: var(--bs-body-color);
display: flex;
font-size: .8125rem;
min-height: 38px;
padding: .375rem .75rem;
min-height: 31px;
padding: .25rem .75rem;
}
.indicator-filter-bar .input-group-text {
background: var(--bs-paper-bg);
border-color: var(--bs-border-color);
color: var(--bs-secondary-color);
padding-left: .625rem;
padding-right: .625rem;
}
.indicator-export-btn {
border-color: #28a745;
color: #28a745;
white-space: nowrap;
}
.indicator-export-btn:hover,
.indicator-export-btn:focus {
background: rgba(40, 167, 69, .08);
border-color: #28a745;
color: #28a745;
padding-left: .5rem;
padding-right: .5rem;
}
.indicator-summary-value {
@@ -190,16 +168,18 @@
}
@media (max-width: 767.98px) {
.indicator-filter-bar,
.indicator-filter-actions,
.indicator-filter-primary-actions {
.indicator-filter-line {
display: grid;
grid-template-columns: 1fr;
width: 100%;
}
.indicator-filter-group {
min-width: 100%;
.indicator-filter-section-label {
margin-right: 0;
}
.indicator-filter-export-action {
margin-left: 0;
}
.indicator-filter-bar .btn {
@@ -225,96 +205,133 @@
</p>
</div>
<div class="indicator-filter-bar" id="indicator-filter-bar" aria-label="Filter dashboard indikator pertanian">
@foreach ($filterOptions as $filter)
<div class="indicator-filter-group">
<label for="filter-{{ $filter['key'] }}" class="indicator-filter-label">
{{ $filter['label'] }}
</label>
@php
$filtersByKey = collect($filterOptions)->keyBy('key');
@endphp
@if (!empty($filter['icon']))
<div class="input-group">
<span class="input-group-text" aria-hidden="true">
<i class="ti {{ $filter['icon'] }}"></i>
</span>
@if (!empty($filter['readonly']))
@php
$selectedOption = collect($filter['options'])
->firstWhere('value', $initialFilters[$filter['key']]);
@endphp
<div
id="filter-{{ $filter['key'] }}"
class="form-control indicator-filter-static"
data-filter-key="{{ $filter['key'] }}"
data-filter-value="{{ $initialFilters[$filter['key']] }}"
aria-label="Filter {{ $filter['label'] }}"
role="text"
>
{{ $selectedOption['label'] ?? 'Ngada' }}
<div class="row g-6 indicator-filter-row">
<div class="col-12">
<div class="card card-border-shadow-primary">
<div class="card-body py-3">
<div class="indicator-filter-bar" id="indicator-filter-bar" aria-label="Filter dashboard indikator pertanian">
<div class="indicator-filter-line">
<div class="indicator-filter-section-label">
<i class="icon-base ti tabler-map-2 me-2"></i>
<span>Wilayah</span>
</div>
@else
<select
id="filter-{{ $filter['key'] }}"
class="form-select indicator-filter-select"
data-filter-key="{{ $filter['key'] }}"
aria-label="Filter {{ $filter['label'] }}"
>
@foreach ($filter['options'] as $option)
<option
value="{{ $option['value'] }}"
@selected($initialFilters[$filter['key']] === $option['value'])
@foreach (['kabupaten', 'kecamatan', 'desa'] as $filterKey)
@php
$filter = $filtersByKey[$filterKey];
@endphp
<div class="filter-item">
@if (!empty($filter['readonly']))
@php
$selectedOption = collect($filter['options'])
->firstWhere('value', $initialFilters[$filter['key']]);
@endphp
<div
id="filter-{{ $filter['key'] }}"
class="form-control form-control-sm indicator-filter-static"
data-filter-key="{{ $filter['key'] }}"
data-filter-value="{{ $initialFilters[$filter['key']] }}"
aria-label="Filter {{ $filter['label'] }}"
role="text"
>
{{ $selectedOption['label'] ?? 'Ngada' }}
</div>
@else
<select
id="filter-{{ $filter['key'] }}"
class="form-select form-select-sm indicator-filter-select"
data-filter-key="{{ $filter['key'] }}"
aria-label="Filter {{ $filter['label'] }}"
@disabled($filter['key'] === 'desa' && $initialFilters['kecamatan'] === 'all')
>
@foreach ($filter['options'] as $option)
<option
value="{{ $option['value'] }}"
@if (isset($option['parent'])) data-parent="{{ $option['parent'] }}" @endif
@selected($initialFilters[$filter['key']] === $option['value'])
>
{{ $option['label'] }}
</option>
@endforeach
</select>
@endif
</div>
@endforeach
</div>
<hr class="my-3">
<div class="indicator-filter-line">
<div class="indicator-filter-section-label">
<i class="icon-base ti tabler-adjustments-horizontal me-2"></i>
<span>Data</span>
</div>
@foreach (['komoditas', 'segmentasi'] as $filterKey)
@php
$filter = $filtersByKey[$filterKey];
@endphp
<div class="filter-item">
<select
id="filter-{{ $filter['key'] }}"
class="form-select form-select-sm indicator-filter-select"
data-filter-key="{{ $filter['key'] }}"
aria-label="Filter {{ $filter['label'] }}"
>
{{ $option['label'] }}
</option>
@endforeach
</select>
@endif
</div>
@else
<select
id="filter-{{ $filter['key'] }}"
class="form-select indicator-filter-select"
data-filter-key="{{ $filter['key'] }}"
aria-label="Filter {{ $filter['label'] }}"
@disabled($filter['key'] === 'desa' && $initialFilters['kecamatan'] === 'all')
>
@foreach ($filter['options'] as $option)
<option
value="{{ $option['value'] }}"
@if (isset($option['parent'])) data-parent="{{ $option['parent'] }}" @endif
@selected($initialFilters[$filter['key']] === $option['value'])
@foreach ($filter['options'] as $option)
<option
value="{{ $option['value'] }}"
@selected($initialFilters[$filter['key']] === $option['value'])
>
{{ $option['label'] }}
</option>
@endforeach
</select>
</div>
@endforeach
<button
type="button"
class="btn btn-outline-secondary btn-sm"
id="indicator-apply-filter"
aria-label="Terapkan filter indikator pertanian"
>
{{ $option['label'] }}
</option>
@endforeach
</select>
@endif
</div>
@endforeach
<i class="icon-base ti tabler-filter me-1"></i>
Filter
</button>
<div class="indicator-filter-actions">
<div class="indicator-filter-primary-actions">
<button
type="button"
class="btn btn-outline-secondary"
id="indicator-reset-filter"
aria-label="Reset filter indikator pertanian"
>
<i class="ti tabler-rotate-clockwise-2 me-1"></i>
Reset Filter
</button>
</div>
<button
type="button"
class="btn btn-outline-secondary btn-sm"
id="indicator-reset-filter"
aria-label="Reset filter indikator pertanian"
>
<i class="icon-base ti tabler-refresh me-1"></i>
Reset
</button>
<button
type="button"
class="btn btn-outline-success indicator-export-btn"
id="indicator-export-data"
aria-label="Export data indikator pertanian"
>
<i class="ti tabler-download me-1"></i>
Export Data
</button>
<div class="indicator-filter-export-action">
<button
type="button"
class="btn btn-outline-secondary btn-sm"
id="indicator-export-data"
aria-label="Export data indikator pertanian"
>
<i class="icon-base ti tabler-download me-1"></i>
Export Data
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -685,6 +702,7 @@
const komoditasSelect = document.querySelector('[data-filter-key="komoditas"]');
const segmentasiSelect = document.querySelector('[data-filter-key="segmentasi"]');
const selectedKabupaten = kabupatenFilter?.dataset.filterValue || initialFilters.kabupaten || 'all';
const applyFilterButton = document.getElementById('indicator-apply-filter');
const resetButton = document.getElementById('indicator-reset-filter');
const exportButton = document.getElementById('indicator-export-data');
const chartInstances = {};
@@ -729,6 +747,10 @@
resetButton.disabled = isLoading;
}
if (applyFilterButton) {
applyFilterButton.disabled = isLoading;
}
if (exportButton) {
exportButton.disabled = isLoading;
}
@@ -970,11 +992,13 @@
filters.desa = 'all';
await loadDesaOptions('all');
}
loadIndicatorData();
});
});
applyFilterButton?.addEventListener('click', function () {
loadIndicatorData();
});
resetButton?.addEventListener('click', async function () {
Object.assign(filters, {
kecamatan: 'all',