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