135 lines
5.0 KiB
Vue
135 lines
5.0 KiB
Vue
<script setup lang="ts">
|
||
import { object, string, type InferType } from 'yup'
|
||
import { apiBase } from '~/helpers';
|
||
import type { ApiTypeExternal } from '~/helpers';
|
||
import type { FormSubmitEvent } from '#ui/types'
|
||
|
||
type ExternalDataType = {
|
||
partner?: ApiTypeExternal[],
|
||
categories?: ApiTypeExternal[][],
|
||
element?: ApiTypeExternal[],
|
||
}
|
||
type StateDataType = {
|
||
partner?: string
|
||
categories?: string[]
|
||
inventory?: string
|
||
element?: string
|
||
element_id?: string
|
||
}
|
||
const loading = ref(false)
|
||
const state = reactive<StateDataType>({
|
||
partner: undefined,
|
||
categories: [],
|
||
inventory: undefined,
|
||
element: undefined,
|
||
element_id: undefined
|
||
})
|
||
const external_data = reactive<ExternalDataType>({
|
||
partner: [],
|
||
categories: [],
|
||
element: [],
|
||
})
|
||
const schema = object({
|
||
element: string().required('Required'),
|
||
element_id: string().required('Required')
|
||
})
|
||
type Schema = InferType<typeof schema>
|
||
|
||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||
const data = await $fetch(`${apiBase}/element/`, { method: 'POST', body: JSON.stringify(event.data) })
|
||
if(data.partner) {
|
||
// navigateTo(`/organization/${data.partner.id}`)
|
||
}
|
||
}
|
||
|
||
const searchInExternal = (q: string) => {
|
||
if (!q.length) {
|
||
return external_data.partner?.splice(0, 10)
|
||
}
|
||
return external_data.partner?.filter(el => {
|
||
return el.Description.toLowerCase().indexOf(q.toLowerCase()) !== -1
|
||
}).slice(0, 10)
|
||
}
|
||
|
||
const loadPartners = async () => {
|
||
loading.value = true
|
||
const data = await $fetch<ApiTypeExternal[]>(`${apiBase}/partner/external/`)
|
||
if (data) {
|
||
external_data.partner = data
|
||
}
|
||
loading.value = false
|
||
}
|
||
const loadCategories = async () => {
|
||
loading.value = true
|
||
|
||
const lastCat = state.categories?.at(-1) || ''
|
||
const data = await $fetch<ApiTypeExternal[]>(`${apiBase}/element/external_categories/${lastCat}`)
|
||
if (data.length) {
|
||
external_data.categories?.push(data)
|
||
} else {
|
||
await loadElements()
|
||
}
|
||
loading.value = false
|
||
}
|
||
const loadElements = async () => {
|
||
loading.value = true
|
||
|
||
const lastCat = state.categories?.at(-1) || ''
|
||
const data = await $fetch<ApiTypeExternal[]>(`${apiBase}/element/external/${lastCat}`)
|
||
if (data) {
|
||
external_data.element = data
|
||
}
|
||
loading.value = false
|
||
}
|
||
const loadDeepCategories = async (i: number) => {
|
||
if ((i + 1) <= (state.categories as string[]).length) {
|
||
state.categories = state.categories?.slice(0, i + 1)
|
||
external_data.categories = external_data.categories?.slice(0, i + 1)
|
||
|
||
state.element = undefined
|
||
external_data.element = []
|
||
}
|
||
|
||
loadCategories()
|
||
}
|
||
onMounted(async () => {
|
||
await loadPartners()
|
||
await loadCategories()
|
||
})
|
||
</script>
|
||
<template>
|
||
<div class="grid grid-cols-10 gap-4">
|
||
<div class="col-span-3">
|
||
<UForm :state="state" class="flex flex-col gap-4" @submit="onSubmit">
|
||
<UFormGroup label="Выбрать организацию" name="organization">
|
||
<USelectMenu v-model="state.partner" :options="external_data.partner" value-attribute="Ref_Key"
|
||
option-attribute="Description" :searchable="searchInExternal"
|
||
searchable-placeholder="Выберите организацию из списка контрагентов" :loading="loading" />
|
||
</UFormGroup>
|
||
<UFormGroup label="Добавить элемент инвентаризации" v-if="state.partner">
|
||
<template v-for="(item, i) in external_data.categories">
|
||
<USelectMenu v-model="(state.categories as string[])[i]" :options="item"
|
||
value-attribute="Ref_Key" option-attribute="Description" :searchable="true"
|
||
:loading="loading" :placeholder="`Категории (${item.length})`"
|
||
@change="loadDeepCategories(i)" />
|
||
</template>
|
||
<USelectMenu v-if="external_data.element?.length" v-model="state.element"
|
||
:options="external_data.element" value-attribute="Ref_Key" option-attribute="Description"
|
||
:searchable="true" :loading="loading"
|
||
:placeholder="`Элементы (${external_data.element.length})`" />
|
||
</UFormGroup>
|
||
<UFormGroup v-if="state.element"
|
||
:label="`Данные об элементе «${external_data.element?.find(el => el['Ref_Key'] === state.element)?.Description}»`">
|
||
<UInput placeholder="ID" v-model="state.element_id" />
|
||
</UFormGroup>
|
||
|
||
<UButton type="submit" :disabled="!state.element_id">
|
||
Сохранить
|
||
</UButton>
|
||
</UForm>
|
||
</div>
|
||
<div class="col-span-7">
|
||
<h2>{{ external_data.partner?.find(el => el["Ref_Key"] == state.partner)?.Description }}</h2>
|
||
</div>
|
||
</div>
|
||
</template> |