2026-05-12 15:14:18 +03:00
|
|
|
|
<template>
|
|
|
|
|
|
<v-dialog v-model="open" max-width="560">
|
|
|
|
|
|
<v-card>
|
|
|
|
|
|
<v-card-title>Регионы — для {{ count }} проектов</v-card-title>
|
|
|
|
|
|
<v-card-text>
|
2026-05-17 14:35:16 +03:00
|
|
|
|
<p class="text-caption text-medium-emphasis mb-4">
|
2026-06-17 05:17:12 +03:00
|
|
|
|
Изменения применяются к каждому из {{ count }} выбранных проектов: выбранные субъекты добавляются к
|
|
|
|
|
|
их регионам или убираются из них.
|
2026-05-17 14:35:16 +03:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="mb-2">
|
|
|
|
|
|
<div class="text-caption text-success font-weight-medium mb-2">➕ Добавить регионы</div>
|
|
|
|
|
|
<v-autocomplete
|
|
|
|
|
|
v-model="addRegions"
|
|
|
|
|
|
:items="selectableRegions"
|
|
|
|
|
|
item-title="name"
|
|
|
|
|
|
item-value="code"
|
|
|
|
|
|
label="Субъекты РФ"
|
|
|
|
|
|
multiple
|
|
|
|
|
|
chips
|
2026-05-23 10:21:10 +03:00
|
|
|
|
closable-chips
|
2026-05-17 14:35:16 +03:00
|
|
|
|
clearable
|
|
|
|
|
|
density="comfortable"
|
|
|
|
|
|
data-testid="region-add-select"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #item="{ props: itemProps, item }">
|
|
|
|
|
|
<v-list-item v-bind="itemProps">
|
|
|
|
|
|
<template #subtitle>
|
|
|
|
|
|
{{ FEDERAL_DISTRICT_NAMES[item.raw.federalDistrict] || '' }}
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</v-list-item>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</v-autocomplete>
|
2026-05-12 15:14:18 +03:00
|
|
|
|
</div>
|
2026-05-17 14:35:16 +03:00
|
|
|
|
|
2026-05-12 15:14:18 +03:00
|
|
|
|
<div>
|
2026-05-17 14:35:16 +03:00
|
|
|
|
<div class="text-caption text-error font-weight-medium mb-2">➖ Убрать регионы</div>
|
|
|
|
|
|
<v-autocomplete
|
|
|
|
|
|
v-model="removeRegions"
|
|
|
|
|
|
:items="selectableRegions"
|
|
|
|
|
|
item-title="name"
|
|
|
|
|
|
item-value="code"
|
|
|
|
|
|
label="Субъекты РФ"
|
|
|
|
|
|
multiple
|
|
|
|
|
|
chips
|
2026-05-23 10:21:10 +03:00
|
|
|
|
closable-chips
|
2026-05-17 14:35:16 +03:00
|
|
|
|
clearable
|
|
|
|
|
|
density="comfortable"
|
|
|
|
|
|
data-testid="region-remove-select"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #item="{ props: itemProps, item }">
|
|
|
|
|
|
<v-list-item v-bind="itemProps">
|
|
|
|
|
|
<template #subtitle>
|
|
|
|
|
|
{{ FEDERAL_DISTRICT_NAMES[item.raw.federalDistrict] || '' }}
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</v-list-item>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</v-autocomplete>
|
2026-05-12 15:14:18 +03:00
|
|
|
|
</div>
|
|
|
|
|
|
</v-card-text>
|
|
|
|
|
|
<v-card-actions>
|
|
|
|
|
|
<v-spacer />
|
|
|
|
|
|
<v-btn data-testid="cancel" @click="open = false">Отмена</v-btn>
|
2026-05-17 14:35:16 +03:00
|
|
|
|
<v-btn
|
|
|
|
|
|
color="primary"
|
|
|
|
|
|
data-testid="apply"
|
|
|
|
|
|
:disabled="addRegions.length === 0 && removeRegions.length === 0"
|
|
|
|
|
|
@click="apply"
|
2026-05-12 20:24:33 +03:00
|
|
|
|
>Применить к {{ count }}</v-btn
|
|
|
|
|
|
>
|
2026-05-12 15:14:18 +03:00
|
|
|
|
</v-card-actions>
|
|
|
|
|
|
</v-card>
|
|
|
|
|
|
</v-dialog>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
import { ref, watch } from 'vue';
|
2026-05-17 14:35:16 +03:00
|
|
|
|
import { REGIONS, FEDERAL_DISTRICT_NAMES } from '../../constants/regions';
|
2026-05-12 15:14:18 +03:00
|
|
|
|
|
|
|
|
|
|
const props = defineProps<{ modelValue: boolean; count: number }>();
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
|
|
'update:modelValue': [value: boolean];
|
2026-05-17 14:35:16 +03:00
|
|
|
|
apply: [payload: { add_regions: number[]; remove_regions: number[] }];
|
2026-05-12 15:14:18 +03:00
|
|
|
|
}>();
|
|
|
|
|
|
|
2026-05-17 14:35:16 +03:00
|
|
|
|
// code:0 — sentinel «Вся РФ»; в bulk add/remove субъектов не выбирается.
|
|
|
|
|
|
const selectableRegions = REGIONS.filter((r) => r.code !== 0);
|
|
|
|
|
|
|
2026-05-12 15:14:18 +03:00
|
|
|
|
const open = ref(props.modelValue);
|
2026-05-17 14:35:16 +03:00
|
|
|
|
const addRegions = ref<number[]>([]);
|
|
|
|
|
|
const removeRegions = ref<number[]>([]);
|
2026-05-12 15:14:18 +03:00
|
|
|
|
|
2026-05-12 20:24:33 +03:00
|
|
|
|
watch(
|
|
|
|
|
|
() => props.modelValue,
|
|
|
|
|
|
(val) => {
|
|
|
|
|
|
open.value = val;
|
|
|
|
|
|
if (val) {
|
2026-05-17 14:35:16 +03:00
|
|
|
|
addRegions.value = [];
|
|
|
|
|
|
removeRegions.value = [];
|
2026-05-12 20:24:33 +03:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
);
|
2026-05-17 14:35:16 +03:00
|
|
|
|
watch(open, (val) => emit('update:modelValue', val));
|
2026-05-12 15:14:18 +03:00
|
|
|
|
|
|
|
|
|
|
function apply() {
|
2026-05-17 14:35:16 +03:00
|
|
|
|
emit('apply', { add_regions: [...addRegions.value], remove_regions: [...removeRegions.value] });
|
|
|
|
|
|
addRegions.value = [];
|
|
|
|
|
|
removeRegions.value = [];
|
2026-05-12 15:14:18 +03:00
|
|
|
|
open.value = false;
|
|
|
|
|
|
}
|
2026-05-17 14:35:16 +03:00
|
|
|
|
|
|
|
|
|
|
defineExpose({ addRegions, removeRegions, apply });
|
2026-05-12 15:14:18 +03:00
|
|
|
|
</script>
|