117 lines
4.0 KiB
Vue
117 lines
4.0 KiB
Vue
<script setup lang="ts">
|
||
type location = { id: number, name: string }
|
||
type tmc_field = { name: string, comment: string, id: number, text: string, file_id: string, image_aws_url: string, }
|
||
|
||
type api_field = {
|
||
id: number;
|
||
name: string;
|
||
comment: string;
|
||
}
|
||
type api_tmc_field = {
|
||
id: number;
|
||
text: string;
|
||
file_id?: any;
|
||
image_aws_url?: any;
|
||
field: api_field;
|
||
}
|
||
type api_tmc_list = {
|
||
id: number;
|
||
name?: any;
|
||
field: api_tmc_field[];
|
||
tmc: {
|
||
id: number,
|
||
name: string,
|
||
fields: api_field[]
|
||
}
|
||
}
|
||
const route = useRoute()
|
||
const item = ref()
|
||
const terdeep = ref()
|
||
const state = reactive({} as
|
||
{
|
||
id: string, name?: string,
|
||
location: location,
|
||
tmc: {
|
||
name: string, id: number,
|
||
fields: tmc_field[]
|
||
}[]
|
||
})
|
||
|
||
const loadData = async () => {
|
||
const items_data = await apiCall<any>(`tgbot/${route.params.id}/`)
|
||
item.value = items_data
|
||
state.id = items_data.id
|
||
state.name = items_data.name
|
||
state.location = items_data.location
|
||
state.tmc = items_data.tmc.map((el: api_tmc_list) => {
|
||
return {
|
||
name: el.tmc.name,
|
||
id: el.id,
|
||
fields: el.field.map(item => {
|
||
return {
|
||
name: item.field.name,
|
||
comment: item.field.comment,
|
||
id: item.id,
|
||
text: item.text,
|
||
file_id: item.file_id,
|
||
image_aws_url: item.image_aws_url,
|
||
}
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
const search = async (q: string) => {
|
||
const terdeep_data = await apiCall<ApiPaged<{ id: number, name: string }>>(`tmc/terdeep/?search=${q}`)
|
||
terdeep.value = [toRaw(state.location), ...terdeep_data.results]
|
||
return terdeep.value
|
||
}
|
||
onMounted(async () => {
|
||
await loadData()
|
||
terdeep.value = [toRaw(state.location)]
|
||
})
|
||
const patchField = async (field: { id: number, text: string }) => {
|
||
await apiCall(`tgbot_items/${field.id}/`, 'patch', { text: field.text })
|
||
}
|
||
const patchItem = async () => {
|
||
await apiCall(`tgbot/${state.id}/`, 'patch', { name: state.name, location_id: state.location })
|
||
}
|
||
</script>
|
||
<template>
|
||
<UForm :state="state" v-if="item">
|
||
<div class="grid grid-cols-4 gap-2 items-end">
|
||
<div class="col-span-2">
|
||
<div class="flex items-end gap-2">
|
||
<UFormGroup label="Название" class="grow">
|
||
<UInput v-model="state.name" />
|
||
</UFormGroup>
|
||
<UButton @click="patchItem">Сохранить</UButton>
|
||
</div>
|
||
</div>
|
||
<div class="col-span-2">
|
||
<UFormGroup label="Локация" class="col-span-3">
|
||
<USelectMenu v-model="state.location.id" :options="terdeep" :searchable="search"
|
||
value-attribute="id" option-attribute="name" :disabled="true" />
|
||
</UFormGroup>
|
||
</div>
|
||
<UFormGroup label="ТМЦ" v-if="state.tmc" class="col-span-4">
|
||
<div v-for="el in state.tmc" class="ml-4">
|
||
<strong>{{ el.name }}</strong>
|
||
<ul>
|
||
<li v-for="field in el.fields" class="grid grid-cols-3 gap-4">
|
||
<span class="col-span-1 flex flex-col gap-2 items-start">
|
||
{{ field.name }}
|
||
<UInput v-model="field.text"
|
||
:placeholder="`Введите ${field.comment || 'с изображения'}`" />
|
||
<UButton @click="patchField(field)">Сохранить</UButton>
|
||
</span>
|
||
<span class="col-span-2 max-w-80">
|
||
<GetImage :file_id="field.file_id" :image_aws_url="field.image_aws_url" type="img" />
|
||
</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</UFormGroup>
|
||
</div>
|
||
</UForm>
|
||
</template> |