feat: add raw material selection dropdown to CuttingPosCombinationDialog, allowing users to filter materials and enhancing the search functionality

This commit is contained in:
Yoga Pangestu 2026-07-09 15:31:37 +07:00
parent b93a200284
commit 9aba51db93

View File

@ -14,6 +14,13 @@ import {
DialogTitle, DialogTitle,
} from '@/components/ui/dialog'; } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { apiFetch } from '@/lib/api'; import { apiFetch } from '@/lib/api';
import draft_combinations from '@/routes/admin/manage/cuttings/draft_combinations'; import draft_combinations from '@/routes/admin/manage/cuttings/draft_combinations';
@ -50,19 +57,28 @@ const emit = defineEmits<{
}>(); }>();
const search = ref(''); const search = ref('');
const selectedRawMaterialId = ref('all');
const selectedMaterials = ref<SelectedMaterial[]>([]); const selectedMaterials = ref<SelectedMaterial[]>([]);
const combinationResult = ref<string>(''); const combinationResult = ref<string>('');
const loading = ref(false); const loading = ref(false);
const selectPortalTarget = ref<HTMLElement>();
const filteredRawMaterials = computed(() => { const filteredRawMaterials = computed(() => {
const keyword = search.value.trim().toLowerCase(); const keyword = search.value.trim().toLowerCase();
const rawMaterialId = selectedRawMaterialId.value;
const catalog = props.rawMaterialCatalog; const catalog = props.rawMaterialCatalog;
if (!keyword) { let items = catalog;
return catalog; if (rawMaterialId !== 'all') {
const idNum = Number(rawMaterialId);
items = catalog.filter((rawMaterial) => rawMaterial.id === idNum);
} }
return catalog if (!keyword) {
return items;
}
return items
.map((rawMaterial) => { .map((rawMaterial) => {
const matchingPrices = rawMaterial.prices.filter((price) => const matchingPrices = rawMaterial.prices.filter((price) =>
price.variant.toLowerCase().includes(keyword), price.variant.toLowerCase().includes(keyword),
@ -110,6 +126,7 @@ function removeSelected(priceId: number) {
function resetForm() { function resetForm() {
search.value = ''; search.value = '';
selectedRawMaterialId.value = 'all';
selectedMaterials.value = []; selectedMaterials.value = [];
combinationResult.value = ''; combinationResult.value = '';
} }
@ -218,10 +235,25 @@ watch(open, (value) => {
</div> </div>
</div> </div>
<div class="relative"> <div class="flex flex-col gap-2 sm:flex-row sm:items-center">
<Search class="absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" /> <div class="relative flex-1">
<Input v-model="search" placeholder="Cari bahan baku lain untuk dikombinasikan..." <Search class="absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" />
class="pl-9" /> <Input v-model="search" placeholder="Cari bahan baku lain untuk dikombinasikan..."
class="pl-9" />
</div>
<div class="w-full sm:w-60">
<Select v-model:model-value="selectedRawMaterialId">
<SelectTrigger class="w-full">
<SelectValue placeholder="Semua Bahan Baku" />
</SelectTrigger>
<SelectContent :to="selectPortalTarget">
<SelectItem value="all">Semua Bahan Baku</SelectItem>
<SelectItem v-for="item in rawMaterialCatalog" :key="item.id" :value="String(item.id)">
{{ item.name }}
</SelectItem>
</SelectContent>
</Select>
</div>
</div> </div>
<div v-if="filteredRawMaterials.length === 0" <div v-if="filteredRawMaterials.length === 0"
@ -287,6 +319,7 @@ watch(open, (value) => {
</Button> </Button>
</div> </div>
</div> </div>
<div ref="selectPortalTarget" class="contents"></div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
</template> </template>