@topvisor/ui 1.5.9-pnpm.5 → 1.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.chunks/formsExt-DtFeVRvE.es.amd.js +2 -0
  2. package/.chunks/formsExt-DtFeVRvE.es.amd.js.map +1 -0
  3. package/.chunks/{formsExt-BD8Sap5u.es.js → formsExt-DtFeVRvE.es.js} +155 -155
  4. package/.chunks/formsExt-DtFeVRvE.es.js.map +1 -0
  5. package/assets/schedule.css +1 -1
  6. package/assets/themes/dark-th.css +1 -1
  7. package/assets/themes/dark.css +1 -1
  8. package/assets/themes/light.css +1 -1
  9. package/autoload-css-manifest.amd.json +1 -1
  10. package/autoload-css-manifest.json +1 -1
  11. package/formsExt/formsExt.amd.js +1 -1
  12. package/formsExt/formsExt.amd.js.map +1 -1
  13. package/formsExt/formsExt.js +1 -1
  14. package/package.json +2 -1
  15. package/project/project.amd.js +1 -1
  16. package/project/project.amd.js.map +1 -1
  17. package/project/project.js +349 -348
  18. package/project/project.js.map +1 -1
  19. package/schedule/schedule.amd.js +1 -1
  20. package/schedule/schedule.amd.js.map +1 -1
  21. package/schedule/schedule.js +159 -154
  22. package/schedule/schedule.js.map +1 -1
  23. package/src/components/project/groupSelector/groups/utils.d.ts +0 -1
  24. package/src/components/project/projectSelector/utils.d.ts +8 -2
  25. package/src/components/project/regionSelector/types.d.ts +17 -10
  26. package/src/components/project/regionSelector/utils/utils.d.ts +14 -14
  27. package/src/components/schedule/schedule/{compoents → components}/calendar/types.d.ts +1 -3
  28. package/src/components/schedule/schedule/{compoents → components}/emails/selector/types.d.ts +6 -2
  29. package/src/components/schedule/schedule/composables/useModeOptions.d.ts +7 -0
  30. package/src/components/schedule/schedule/composables/useModelByModeCache.d.ts +9 -0
  31. package/src/components/schedule/schedule/stories/play/play.d.ts +5 -0
  32. package/src/components/schedule/schedule/types.d.ts +9 -9
  33. package/src/components/schedule/schedule/utils.d.ts +1 -6
  34. package/src/components/schedule/schedule.d.ts +2 -2
  35. package/.chunks/formsExt-BD8Sap5u.es.amd.js +0 -2
  36. package/.chunks/formsExt-BD8Sap5u.es.amd.js.map +0 -1
  37. package/.chunks/formsExt-BD8Sap5u.es.js.map +0 -1
  38. /package/src/components/schedule/schedule/{compoents → components}/calendar/composables/useDaysByCalendarMode.d.ts +0 -0
  39. /package/src/components/schedule/schedule/{compoents → components}/emails/types.d.ts +0 -0
  40. /package/src/components/schedule/schedule/{compoents → components}/socials/types.d.ts +0 -0
  41. /package/src/components/schedule/schedule/{compoents → components}/timeSelector/types.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"schedule.js","names":[],"sources":["../../src/components/schedule/schedule/compoents/calendar/composables/useDaysByCalendarMode.ts","../../src/components/schedule/schedule/compoents/timeSelector/timeSelector.vue","../../src/components/schedule/schedule/compoents/timeSelector/timeSelector.vue","../../src/components/schedule/schedule/compoents/calendar/calendar.vue","../../src/components/schedule/schedule/compoents/calendar/calendar.vue","../../src/components/schedule/schedule/utils.ts","../../src/components/schedule/schedule/schedule.vue","../../src/components/schedule/schedule/schedule.vue","../../src/components/schedule/schedule/compoents/emails/selector/selector.vue","../../src/components/schedule/schedule/compoents/emails/selector/selector.vue","../../src/components/schedule/schedule/compoents/emails/emails.vue","../../src/components/schedule/schedule/compoents/emails/emails.vue","../../src/components/schedule/schedule/compoents/socials/socials.vue","../../src/components/schedule/schedule/compoents/socials/socials.vue"],"sourcesContent":["import { computed, type MaybeRefOrGetter, toValue } from 'vue';\nimport type { Day, Props } from '../types';\nimport { useI18n } from '@/core/app';\n\n/**\n * Формирует список дней для выбранного режима календаря.\n */\nexport const useDaysByCalendarMode = (mode: MaybeRefOrGetter<Props['mode']>) => {\n\tconst i18n = useI18n();\n\n\treturn computed<Day[]>(() => {\n\t\tswitch (toValue(mode)) {\n\t\t\t// Дни месяца\n\t\t\tcase 'dayOfMonth': {\n\t\t\t\tconst days: Day[] = Array.from({ length: 27 }, (_, index) => ({\n\t\t\t\t\tvalue: String(index + 1) as Day['value'],\n\t\t\t\t\ttitle: String(index + 1),\n\t\t\t\t}));\n\n\t\t\t\tdays.push({\n\t\t\t\t\tvalue: 'LAST_OF_MONTH',\n\t\t\t\t\ttitle: '',\n\t\t\t\t\tisIcon: true,\n\t\t\t\t});\n\n\t\t\t\treturn days;\n\t\t\t}\n\n\t\t\t// Дни недели\n\t\t\tcase 'dayOfWeek':\n\t\t\t\treturn [\n\t\t\t\t\t{ value: 'MONDAY', title: i18n.Calendar.Dw_1 },\n\t\t\t\t\t{ value: 'TUESDAY', title: i18n.Calendar.Dw_2 },\n\t\t\t\t\t{ value: 'WEDNESDAY', title: i18n.Calendar.Dw_3 },\n\t\t\t\t\t{ value: 'THURSDAY', title: i18n.Calendar.Dw_4 },\n\t\t\t\t\t{ value: 'FRIDAY', title: i18n.Calendar.Dw_5 },\n\t\t\t\t\t{ value: 'SATURDAY', title: i18n.Calendar.Dw_6 },\n\t\t\t\t\t{ value: 'SUNDAY', title: i18n.Calendar.Dw_7 },\n\t\t\t\t];\n\n\t\t\tdefault:\n\t\t\t\treturn [];\n\t\t}\n\t});\n};\n","<script setup lang=\"ts\">\nimport type { Props } from '@/components/schedule/schedule/compoents/timeSelector/types';\n\nconst props = defineProps<Props>();\n\nconst times = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\n/**\n * Варианты выбора часа от 00 до 23.\n */\nconst hourOptions = Array.from({ length: 24 }, (_, index) => ({\n\tvalue: String(index),\n\ttitle: String(index).padStart(2, '0'),\n}));\n\n/**\n * Предустановленные варианты минут.\n *\n * Поддерижвает вставку произвольного значения через `modelValue`.\n */\nconst minuteOptions = Array.from({ length: 4 }, (_, index) => {\n\tconst minute = index * 15;\n\n\treturn {\n\t\tvalue: String(minute),\n\t\ttitle: String(minute).padStart(2, '0'),\n\t};\n});\n\nconst updateTimeByIndex = (index: number, patch: Partial<Props['modelValue'][number]>) => {\n\tconst nextTimes = [...times.value];\n\tnextTimes[index] = { ...nextTimes[index], ...patch };\n\n\ttimes.value = nextTimes;\n};\n\nconst addTime = () => {\n\ttimes.value = [\n\t\t{\n\t\t\thour: '0',\n\t\t\tminute: '0',\n\t\t},\n\t\t...times.value,\n\t];\n};\n\nconst delTime = (index: number) => {\n\ttimes.value = times.value.filter((_, timeIndex) => timeIndex !== index);\n};\n\n</script>\n\n<template>\n\t<div class=\"top-scheduleTimeSelector\">\n\t\t<div v-for=\"(time, index) in times\" :key=\"index\" class=\"top-scheduleTimeSelector_item\">\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-scheduleTimeSelector_hour\"\n\t\t\t\t:modelValue=\"time.hour\"\n\t\t\t\t:options=\"hourOptions\"\n\t\t\t\t@update:modelValue=\"updateTimeByIndex(index, { hour: $event as Props['modelValue'][number]['hour'] })\"\n\t\t\t/>\n\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-scheduleTimeSelector_minute\"\n\t\t\t\t:modelValue=\"time.minute\"\n\t\t\t\t:options=\"minuteOptions\"\n\t\t\t\tavailableCustomValue\n\t\t\t\t@update:modelValue=\"updateTimeByIndex(index, { minute: $event as Props['modelValue'][number]['minute'] })\"\n\t\t\t/>\n\n\t\t\t<TopButton\n\t\t\t\tv-if=\"props.multipleTimes || times.length > 1\"\n\t\t\t\t@click=\"index ? delTime(index) : addTime()\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\t:icon=\"index ? '' : ''\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Props } from '@/components/schedule/schedule/compoents/timeSelector/types';\n\nconst props = defineProps<Props>();\n\nconst times = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\n/**\n * Варианты выбора часа от 00 до 23.\n */\nconst hourOptions = Array.from({ length: 24 }, (_, index) => ({\n\tvalue: String(index),\n\ttitle: String(index).padStart(2, '0'),\n}));\n\n/**\n * Предустановленные варианты минут.\n *\n * Поддерижвает вставку произвольного значения через `modelValue`.\n */\nconst minuteOptions = Array.from({ length: 4 }, (_, index) => {\n\tconst minute = index * 15;\n\n\treturn {\n\t\tvalue: String(minute),\n\t\ttitle: String(minute).padStart(2, '0'),\n\t};\n});\n\nconst updateTimeByIndex = (index: number, patch: Partial<Props['modelValue'][number]>) => {\n\tconst nextTimes = [...times.value];\n\tnextTimes[index] = { ...nextTimes[index], ...patch };\n\n\ttimes.value = nextTimes;\n};\n\nconst addTime = () => {\n\ttimes.value = [\n\t\t{\n\t\t\thour: '0',\n\t\t\tminute: '0',\n\t\t},\n\t\t...times.value,\n\t];\n};\n\nconst delTime = (index: number) => {\n\ttimes.value = times.value.filter((_, timeIndex) => timeIndex !== index);\n};\n\n</script>\n\n<template>\n\t<div class=\"top-scheduleTimeSelector\">\n\t\t<div v-for=\"(time, index) in times\" :key=\"index\" class=\"top-scheduleTimeSelector_item\">\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-scheduleTimeSelector_hour\"\n\t\t\t\t:modelValue=\"time.hour\"\n\t\t\t\t:options=\"hourOptions\"\n\t\t\t\t@update:modelValue=\"updateTimeByIndex(index, { hour: $event as Props['modelValue'][number]['hour'] })\"\n\t\t\t/>\n\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-scheduleTimeSelector_minute\"\n\t\t\t\t:modelValue=\"time.minute\"\n\t\t\t\t:options=\"minuteOptions\"\n\t\t\t\tavailableCustomValue\n\t\t\t\t@update:modelValue=\"updateTimeByIndex(index, { minute: $event as Props['modelValue'][number]['minute'] })\"\n\t\t\t/>\n\n\t\t\t<TopButton\n\t\t\t\tv-if=\"props.multipleTimes || times.length > 1\"\n\t\t\t\t@click=\"index ? delTime(index) : addTime()\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\t:icon=\"index ? '' : ''\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Props } from '@/components/schedule/schedule/compoents/calendar/types';\nimport { useDaysByCalendarMode } from './composables/useDaysByCalendarMode';\nimport { numberEnding } from '@/core/utils/string';\nimport { computed } from 'vue';\nimport TopScheduleTimeSelector from '@/components/schedule/schedule/compoents/timeSelector/timeSelector.vue';\n\nconst props = defineProps<Props>();\n\nconst selectedDays = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\nconst times = defineModel<Props['times']>('times', {\n\trequired: true,\n});\n\nif (!times.value.length) times.value = [{ hour: '0', minute: '0' }];\n\nconst days = useDaysByCalendarMode(() => props.mode);\n\nconst isAllDaysSelected = computed(() => selectedDays.value.includes('ALL') || selectedDays.value.length === days.value.length);\n\nconst toggleDay = (day: Props['modelValue'][number]) => {\n\tconst nextDays = selectedDays.value.includes('ALL') ? days.value.map(item => item.value) : [...selectedDays.value];\n\tconst dayIndex = nextDays.indexOf(day);\n\n\tif (dayIndex === -1) {\n\t\tnextDays.push(day);\n\t} else {\n\t\tnextDays.splice(dayIndex, 1);\n\t}\n\n\tselectedDays.value = nextDays.length === days.value.length ? ['ALL'] : nextDays;\n};\n\nconst toggleSelectAll = () => {\n\tselectedDays.value = isAllDaysSelected.value ? [] : ['ALL'];\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleCalendar\">\n\t\t<div class=\"top-scheduleCalendar_header\">\n\t\t\t<TopScheduleTimeSelector v-model=\"times\" :multipleTimes />\n\n\t\t\t<TopButton\n\t\t\t\t@click=\"toggleSelectAll()\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\ttabindex=\"0\"\n\t\t\t>\n\t\t\t\t{{ isAllDaysSelected ? $i18n.Common.Clear : $i18n.Common.Select_all }}\n\t\t\t</TopButton>\n\t\t</div>\n\n\t\t<div class=\"top-scheduleCalendar_calendar\">\n\t\t\t<label\n\t\t\t\tclass=\"top-scheduleCalendar_calendarDay\"\n\t\t\t\tv-for=\"day in days\"\n\t\t\t\t:key=\"day.value\"\n\t\t\t>\n\t\t\t\t<input\n\t\t\t\t\tclass=\"top-scheduleCalendar_calendarDayCheckbox\"\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t:value=\"day.value\"\n\t\t\t\t\t:checked=\"selectedDays.includes('ALL') || selectedDays.includes(day.value)\"\n\t\t\t\t\t@change=\"toggleDay(day.value)\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\n\t\t\t\t<span\n\t\t\t\t\tclass=\"top-scheduleCalendar_calendarDayTitle\"\n\t\t\t\t\t:data-top-icon=\"day.isIcon ? day.title : undefined\"\n\t\t\t\t>\n\t\t\t\t\t<template v-if=\"!day.isIcon\">\n\t\t\t\t\t\t{{ day.title }}\n\t\t\t\t\t</template>\n\t\t\t\t</span>\n\t\t\t</label>\n\t\t</div>\n\n\t\t<span\n\t\t\t:class=\"{\n\t\t\t\t'top-scheduleCalendar_selectionSummary': true,\n\t\t\t'top-error': !selectedDays.length\n\t\t\t}\"\n\t\t>\n\t\t\t<!-- Каждый день или Число проверок в неделю / месяц-->\n\t\t\t{{\n\t\t\t\tisAllDaysSelected ?\n\t\t\t\t\t$i18n.Common.Every_day :\n\t\t\t\t\tselectedDays.length\n\t\t\t}}\n\n\t\t\t<template v-if=\"times.length > 1 || !isAllDaysSelected\">\n\t\t\t\t<!-- Добавить число временных слотов, если их несколько -->\n\t\t\t\t{{ times.length > 1 ? ` × ${times.length}` : '' }}\n\n\t\t\t\t<!-- Суффикс \"раз\" -->\n\t\t\t\t{{\n\t\t\t\t\tnumberEnding(\n\t\t\t\t\t\ttimes.length === 1 ? selectedDays.length : times.length,\n\t\t\t\t\t\t$i18n.Common.time_a_0,\n\t\t\t\t\t\t$i18n.Common.time_a_0,\n\t\t\t\t\t\t$i18n.Common.time_a_2,\n\t\t\t\t\t)\n\t\t\t\t}}\n\n\t\t\t\t<!-- В неделю / месяц-->\n\t\t\t\t{{ mode === 'dayOfWeek' ? $i18n.Common.a_week : $i18n.Common.a_month }}\n\t\t\t</template>\n\t\t</span>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Props } from '@/components/schedule/schedule/compoents/calendar/types';\nimport { useDaysByCalendarMode } from './composables/useDaysByCalendarMode';\nimport { numberEnding } from '@/core/utils/string';\nimport { computed } from 'vue';\nimport TopScheduleTimeSelector from '@/components/schedule/schedule/compoents/timeSelector/timeSelector.vue';\n\nconst props = defineProps<Props>();\n\nconst selectedDays = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\nconst times = defineModel<Props['times']>('times', {\n\trequired: true,\n});\n\nif (!times.value.length) times.value = [{ hour: '0', minute: '0' }];\n\nconst days = useDaysByCalendarMode(() => props.mode);\n\nconst isAllDaysSelected = computed(() => selectedDays.value.includes('ALL') || selectedDays.value.length === days.value.length);\n\nconst toggleDay = (day: Props['modelValue'][number]) => {\n\tconst nextDays = selectedDays.value.includes('ALL') ? days.value.map(item => item.value) : [...selectedDays.value];\n\tconst dayIndex = nextDays.indexOf(day);\n\n\tif (dayIndex === -1) {\n\t\tnextDays.push(day);\n\t} else {\n\t\tnextDays.splice(dayIndex, 1);\n\t}\n\n\tselectedDays.value = nextDays.length === days.value.length ? ['ALL'] : nextDays;\n};\n\nconst toggleSelectAll = () => {\n\tselectedDays.value = isAllDaysSelected.value ? [] : ['ALL'];\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleCalendar\">\n\t\t<div class=\"top-scheduleCalendar_header\">\n\t\t\t<TopScheduleTimeSelector v-model=\"times\" :multipleTimes />\n\n\t\t\t<TopButton\n\t\t\t\t@click=\"toggleSelectAll()\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\ttabindex=\"0\"\n\t\t\t>\n\t\t\t\t{{ isAllDaysSelected ? $i18n.Common.Clear : $i18n.Common.Select_all }}\n\t\t\t</TopButton>\n\t\t</div>\n\n\t\t<div class=\"top-scheduleCalendar_calendar\">\n\t\t\t<label\n\t\t\t\tclass=\"top-scheduleCalendar_calendarDay\"\n\t\t\t\tv-for=\"day in days\"\n\t\t\t\t:key=\"day.value\"\n\t\t\t>\n\t\t\t\t<input\n\t\t\t\t\tclass=\"top-scheduleCalendar_calendarDayCheckbox\"\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t:value=\"day.value\"\n\t\t\t\t\t:checked=\"selectedDays.includes('ALL') || selectedDays.includes(day.value)\"\n\t\t\t\t\t@change=\"toggleDay(day.value)\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\n\t\t\t\t<span\n\t\t\t\t\tclass=\"top-scheduleCalendar_calendarDayTitle\"\n\t\t\t\t\t:data-top-icon=\"day.isIcon ? day.title : undefined\"\n\t\t\t\t>\n\t\t\t\t\t<template v-if=\"!day.isIcon\">\n\t\t\t\t\t\t{{ day.title }}\n\t\t\t\t\t</template>\n\t\t\t\t</span>\n\t\t\t</label>\n\t\t</div>\n\n\t\t<span\n\t\t\t:class=\"{\n\t\t\t\t'top-scheduleCalendar_selectionSummary': true,\n\t\t\t'top-error': !selectedDays.length\n\t\t\t}\"\n\t\t>\n\t\t\t<!-- Каждый день или Число проверок в неделю / месяц-->\n\t\t\t{{\n\t\t\t\tisAllDaysSelected ?\n\t\t\t\t\t$i18n.Common.Every_day :\n\t\t\t\t\tselectedDays.length\n\t\t\t}}\n\n\t\t\t<template v-if=\"times.length > 1 || !isAllDaysSelected\">\n\t\t\t\t<!-- Добавить число временных слотов, если их несколько -->\n\t\t\t\t{{ times.length > 1 ? ` × ${times.length}` : '' }}\n\n\t\t\t\t<!-- Суффикс \"раз\" -->\n\t\t\t\t{{\n\t\t\t\t\tnumberEnding(\n\t\t\t\t\t\ttimes.length === 1 ? selectedDays.length : times.length,\n\t\t\t\t\t\t$i18n.Common.time_a_0,\n\t\t\t\t\t\t$i18n.Common.time_a_0,\n\t\t\t\t\t\t$i18n.Common.time_a_2,\n\t\t\t\t\t)\n\t\t\t\t}}\n\n\t\t\t\t<!-- В неделю / месяц-->\n\t\t\t\t{{ mode === 'dayOfWeek' ? $i18n.Common.a_week : $i18n.Common.a_month }}\n\t\t\t</template>\n\t\t</span>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","import type { Props as CalendarProps } from './compoents/calendar/types';\nimport type { Mode, Props } from './types';\nimport type { Option as TopSelectOption } from '@/components/forms/select/types';\nimport { useI18n } from '@/core/plugins/i18n';\n\nexport const defaultMods: Mode[] = ['onDemand', 'dayOfWeek', 'dayOfMonth', 'afterYandexUpdated'];\n\n/**\n * Генерирует варианты задержки запуска после апдейта Яндекса.\n *\n * См. Апометр\n */\nexport const genAfterYandexUpdatedOptions = (): TopSelectOption[] => {\n\tconst i18n = useI18n();\n\n\treturn [\n\t\t{\n\t\t\tvalue: '0',\n\t\t\ttitle: i18n.Projects.immediately,\n\t\t},\n\t\t...Array.from({ length: 24 }, (_, index) => ({\n\t\t\tvalue: String(index + 1),\n\t\t\ttitle: i18n('Projects', 'in_hour', { hour: index + 1 }),\n\t\t})),\n\t];\n};\n\n/**\n * Проверяет, относится ли режим к календарным режимам.\n *\n * Календарный режим, это режим с выбором дней недели или месяца.\n */\nexport const isCalendarMode = (value: Mode): value is CalendarProps['mode'] => value === 'dayOfWeek' || value === 'dayOfMonth';\n\n/**\n * Определяет режим расписания по выбранным дням.\n */\nexport const getModeByDays = (days: Props['modelValue']['days'], currentMode: Mode = 'onDemand'): Mode => {\n\tif (days.includes('YANDEX_UPDATE')) return 'afterYandexUpdated';\n\tif (days.includes('CHECK_POSITIONS')) return 'afterCheck';\n\tif (days.includes('LAST_OF_MONTH') || days.some(day => /^\\d+$/.test(day))) return 'dayOfMonth';\n\n\tif (days.length) {\n\t\t// Сохраняем текущий календарный режм\n\t\tif (isCalendarMode(currentMode)) return currentMode;\n\n\t\t// Режим по умолчанию для `ALL`\n\t\treturn 'dayOfWeek';\n\t}\n\n\treturn currentMode;\n};\n\n/**\n * Подписи режимов принадлежат компоненту, а не каждому его потребителю.\n */\nexport const genModeOptions = (modes: Mode[]): TopSelectOption[] => {\n\tconst i18n = useI18n();\n\n\t// Словарь Dynamics нужен только потребителям режима afterCheck.\n\tconst titles: Record<Mode, string> = {\n\t\tonDemand: i18n.Projects.Settings_on_demand,\n\t\tdayOfWeek: i18n.Projects.Report_on_weekdays,\n\t\tdayOfMonth: i18n.Projects.Settings_particular_days,\n\t\tafterYandexUpdated: i18n.Projects.After_updates,\n\t\tafterCheck: modes.includes('afterCheck') ? i18n.Dynamics.Report_after_tracking_30min_1 : '',\n\t};\n\n\treturn modes.map(value => ({ value, title: titles[value] }));\n};\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue';\nimport TopSelect from '@/components/forms/select/select.vue';\nimport TopScheduleCalendar from './compoents/calendar/calendar.vue';\nimport type { Mode, Props, Slots } from './types';\nimport { defaultMods, genAfterYandexUpdatedOptions, genModeOptions, getModeByDays, isCalendarMode } from './utils';\n\ndefineOptions({\n\tname: 'TopSchedule',\n});\n\nconst props = withDefaults(defineProps<Props>(), {\n\t// Тип `go` соответствует запуску инструмента по расписанию.\n\ttype: 'go',\n});\n\ndefineSlots<Slots>();\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\n// Выбранный режим\nconst mode = ref<Mode>(getModeByDays(model.value.days));\n\n// Список режимов в селекторе зависит от типа расписания и переданных ограничений.\nconst modeOptions = computed(() => genModeOptions(\n\tprops.availableMods ?? (props.type === 'report' ? [...defaultMods, 'afterCheck'] : defaultMods),\n));\n\nconst afterYandexUpdatedOptions = genAfterYandexUpdatedOptions();\n\n// Кеш с выбранными днями и временными слотами для каждого режима.\nconst stateByMode: Partial<Record<Mode, Props['modelValue']>> = {};\n\n// Сохранять настройки выбранного режима\nwatch(model, () => {\n\tstateByMode[mode.value] = {\n\t\tdays: [...model.value.days],\n\t\ttimes: model.value.times.map(time => ({ ...time })),\n\t};\n}, { deep: true, immediate: true });\n\n/**\n * При смене `days` сразу првоеряем доступное значение режима и обновляем его, если надо.\n *\n * @note 1 в цепочке перед `watch(mode)`, цепочки не цикличны\n */\nwatch(\n\t() => model.value.days,\n\t() => mode.value = getModeByDays(model.value.days, mode.value),\n\t{ deep: true, immediate: true },\n);\n\n/**\n * При смене режима устанавливаем соответствующие `days` и `times`.\n *\n * Для календарных режимов восстанавливаем ранее сохранённый выбор дней.\n *\n * @note 2 в цепочке после `watch(() => model.value.days)`, цепочки не цикличны\n */\nwatch(mode, (nextMode) => {\n\t// Ранее сохраненные настройки режима.\n\tconst stateCached = stateByMode[nextMode];\n\n\tswitch (nextMode) {\n\t\tcase 'onDemand':\n\t\t\tmodel.value = {\n\t\t\t\tdays: [],\n\t\t\t\ttimes: [],\n\t\t\t};\n\n\t\t\tbreak;\n\n\t\tcase 'dayOfWeek':\n\t\tcase 'dayOfMonth': {\n\t\t\tmodel.value = {\n\t\t\t\t...model.value,\n\t\t\t\tdays: stateCached?.days ?? ['ALL'],\n\t\t\t\ttimes: stateCached?.times ?? [{ hour: '0', minute: '0' }],\n\t\t\t};\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'afterYandexUpdated':\n\t\t\tmodel.value = {\n\t\t\t\tdays: ['YANDEX_UPDATE'],\n\t\t\t\ttimes: stateCached?.times ?? [{ hour: '0', minute: '0' }],\n\t\t\t};\n\n\t\t\tbreak;\n\n\t\tcase 'afterCheck':\n\t\t\tmodel.value = {\n\t\t\t\tdays: ['CHECK_POSITIONS'],\n\t\t\t\ttimes: stateCached?.times ?? [{ hour: '0', minute: '30' }],\n\t\t\t};\n\n\t\t\tbreak;\n\t}\n});\n</script>\n\n<template>\n\t<div :class=\"['top-schedule', 'top-schedule-type_' + type]\">\n\t\t<div class=\"top-schedule_header\">\n\t\t\t<div class=\"top-schedule_headerTitle\">\n\t\t\t\t{{ title ?? (type === 'go' ? $i18n.Projects.Checks : $i18n.Projects.Reports) }}\n\t\t\t</div>\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-schedule_headerMods\"\n\t\t\t\tv-model=\"mode\"\n\t\t\t\t:options=\"modeOptions\"\n\t\t\t\tsize=\"s\"\n\t\t\t/>\n\t\t</div>\n\n\t\t<div v-if=\"mode !== 'onDemand' && (isCalendarMode(mode) || mode === 'afterYandexUpdated' || $slots.settings)\" class=\"top-schedule_body\">\n\t\t\t<TopSelect\n\t\t\t\tv-if=\"mode === 'afterYandexUpdated' && model.times[0]\"\n\t\t\t\tclass=\"top-schedule_afterYandexUpdatedDelay\"\n\t\t\t\tv-model=\"model.times[0].hour\"\n\t\t\t\t:options=\"afterYandexUpdatedOptions\"\n\t\t\t\tsize=\"s\"\n\t\t\t/>\n\n\t\t\t<TopScheduleCalendar\n\t\t\t\tv-if=\"isCalendarMode(mode)\"\n\t\t\t\tv-model=\"model.days\"\n\t\t\t\tv-model:times=\"model.times\"\n\t\t\t\t:mode\n\t\t\t\t:multipleTimes\n\t\t\t/>\n\n\t\t\t<hr v-if=\"isCalendarMode(mode) && $slots.settings\">\n\n\t\t\t<slot name=\"settings\" :mode></slot>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue';\nimport TopSelect from '@/components/forms/select/select.vue';\nimport TopScheduleCalendar from './compoents/calendar/calendar.vue';\nimport type { Mode, Props, Slots } from './types';\nimport { defaultMods, genAfterYandexUpdatedOptions, genModeOptions, getModeByDays, isCalendarMode } from './utils';\n\ndefineOptions({\n\tname: 'TopSchedule',\n});\n\nconst props = withDefaults(defineProps<Props>(), {\n\t// Тип `go` соответствует запуску инструмента по расписанию.\n\ttype: 'go',\n});\n\ndefineSlots<Slots>();\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\n// Выбранный режим\nconst mode = ref<Mode>(getModeByDays(model.value.days));\n\n// Список режимов в селекторе зависит от типа расписания и переданных ограничений.\nconst modeOptions = computed(() => genModeOptions(\n\tprops.availableMods ?? (props.type === 'report' ? [...defaultMods, 'afterCheck'] : defaultMods),\n));\n\nconst afterYandexUpdatedOptions = genAfterYandexUpdatedOptions();\n\n// Кеш с выбранными днями и временными слотами для каждого режима.\nconst stateByMode: Partial<Record<Mode, Props['modelValue']>> = {};\n\n// Сохранять настройки выбранного режима\nwatch(model, () => {\n\tstateByMode[mode.value] = {\n\t\tdays: [...model.value.days],\n\t\ttimes: model.value.times.map(time => ({ ...time })),\n\t};\n}, { deep: true, immediate: true });\n\n/**\n * При смене `days` сразу првоеряем доступное значение режима и обновляем его, если надо.\n *\n * @note 1 в цепочке перед `watch(mode)`, цепочки не цикличны\n */\nwatch(\n\t() => model.value.days,\n\t() => mode.value = getModeByDays(model.value.days, mode.value),\n\t{ deep: true, immediate: true },\n);\n\n/**\n * При смене режима устанавливаем соответствующие `days` и `times`.\n *\n * Для календарных режимов восстанавливаем ранее сохранённый выбор дней.\n *\n * @note 2 в цепочке после `watch(() => model.value.days)`, цепочки не цикличны\n */\nwatch(mode, (nextMode) => {\n\t// Ранее сохраненные настройки режима.\n\tconst stateCached = stateByMode[nextMode];\n\n\tswitch (nextMode) {\n\t\tcase 'onDemand':\n\t\t\tmodel.value = {\n\t\t\t\tdays: [],\n\t\t\t\ttimes: [],\n\t\t\t};\n\n\t\t\tbreak;\n\n\t\tcase 'dayOfWeek':\n\t\tcase 'dayOfMonth': {\n\t\t\tmodel.value = {\n\t\t\t\t...model.value,\n\t\t\t\tdays: stateCached?.days ?? ['ALL'],\n\t\t\t\ttimes: stateCached?.times ?? [{ hour: '0', minute: '0' }],\n\t\t\t};\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'afterYandexUpdated':\n\t\t\tmodel.value = {\n\t\t\t\tdays: ['YANDEX_UPDATE'],\n\t\t\t\ttimes: stateCached?.times ?? [{ hour: '0', minute: '0' }],\n\t\t\t};\n\n\t\t\tbreak;\n\n\t\tcase 'afterCheck':\n\t\t\tmodel.value = {\n\t\t\t\tdays: ['CHECK_POSITIONS'],\n\t\t\t\ttimes: stateCached?.times ?? [{ hour: '0', minute: '30' }],\n\t\t\t};\n\n\t\t\tbreak;\n\t}\n});\n</script>\n\n<template>\n\t<div :class=\"['top-schedule', 'top-schedule-type_' + type]\">\n\t\t<div class=\"top-schedule_header\">\n\t\t\t<div class=\"top-schedule_headerTitle\">\n\t\t\t\t{{ title ?? (type === 'go' ? $i18n.Projects.Checks : $i18n.Projects.Reports) }}\n\t\t\t</div>\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-schedule_headerMods\"\n\t\t\t\tv-model=\"mode\"\n\t\t\t\t:options=\"modeOptions\"\n\t\t\t\tsize=\"s\"\n\t\t\t/>\n\t\t</div>\n\n\t\t<div v-if=\"mode !== 'onDemand' && (isCalendarMode(mode) || mode === 'afterYandexUpdated' || $slots.settings)\" class=\"top-schedule_body\">\n\t\t\t<TopSelect\n\t\t\t\tv-if=\"mode === 'afterYandexUpdated' && model.times[0]\"\n\t\t\t\tclass=\"top-schedule_afterYandexUpdatedDelay\"\n\t\t\t\tv-model=\"model.times[0].hour\"\n\t\t\t\t:options=\"afterYandexUpdatedOptions\"\n\t\t\t\tsize=\"s\"\n\t\t\t/>\n\n\t\t\t<TopScheduleCalendar\n\t\t\t\tv-if=\"isCalendarMode(mode)\"\n\t\t\t\tv-model=\"model.days\"\n\t\t\t\tv-model:times=\"model.times\"\n\t\t\t\t:mode\n\t\t\t\t:multipleTimes\n\t\t\t/>\n\n\t\t\t<hr v-if=\"isCalendarMode(mode) && $slots.settings\">\n\n\t\t\t<slot name=\"settings\" :mode></slot>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { nextTick, onBeforeUnmount, onMounted, ref } from 'vue';\nimport TopInput from '@/components/forms/input/input.vue';\nimport TopButton from '@/components/forms/button/button.vue';\nimport Core from '@/core/core/core';\nimport { isEmail } from '@/core/utils/check';\nimport { useI18n } from '@/core/plugins/i18n';\nimport type { Props, Emits } from '@/components/schedule/schedule/compoents/emails/selector/types';\n\nconst props = withDefaults(defineProps<Props>(), {\n\temails: () => [],\n\tgetEmailSuggestions: () => [],\n});\n\nconst emit = defineEmits<Emits>();\nconst i18n = useI18n();\nconst $ = Core.$;\n\nconst elRootRef = ref<HTMLElement>();\nconst elInputRef = ref<InstanceType<typeof TopInput>>();\nlet elInput: HTMLInputElement | null = null;\nconst autocompleteCache: Record<string, string[]> = {};\n\nconst filterEmails = (emails: string[]) => emails.filter(email => !props.emails.includes(email));\n\nconst submit = (value: unknown = props.modelValue) => {\n\tconst email = String(value).trim();\n\tif (!email) return;\n\tif (!isEmail(email)) {\n\t\tvoid Core.notice(i18n.Common.Enter_valid_email_notice, 'error');\n\n\t\treturn;\n\t}\n\n\temit('submit', email);\n};\n\nconst initAutocomplete = async () => {\n\tawait nextTick();\n\n\telInput = elInputRef.value?.$el.querySelector('input') ?? null;\n\tif (!elInput) return;\n\n\tif (!$?.ui?.autocomplete) {\n\t\tconsole.info('Для работы autocomplete требуется глобальная загрузка jQuery UI Autocomplete');\n\n\t\treturn;\n\t}\n\n\t$(elInput).autocomplete({\n\t\tappendTo: elRootRef.value,\n\t\tminLength: 0,\n\t\tsource: async (request: { term: string }, response: (items: Array<{ label: string, value: string }>) => void) => {\n\t\t\tconst term = request.term;\n\t\t\tif (!(term in autocompleteCache)) {\n\t\t\t\tautocompleteCache[term] = await props.getEmailSuggestions(term);\n\t\t\t}\n\n\t\t\tresponse(filterEmails(autocompleteCache[term]).map(email => ({\n\t\t\t\tlabel: email,\n\t\t\t\tvalue: email,\n\t\t\t})));\n\t\t},\n\t\tselect: (event: Event, ui: { item?: { value: string } }) => {\n\t\t\tif (!ui.item || !elInput) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tsubmit(ui.item.value);\n\t\t\temit('update:modelValue', '');\n\n\t\t\t$(elInput).trigger('focus');\n\t\t},\n\t});\n\n\t$(elInput).attr('autocomplete', 'disabled');\n\t$(elInput).on('focus.scheduleEmailSelector', () => {\n\t\tif (!elInput) return;\n\n\t\t$(elInput).trigger('input');\n\t});\n};\n\nonMounted(() => {\n\tvoid initAutocomplete();\n});\n\nonBeforeUnmount(() => {\n\tif (!$?.ui?.autocomplete || !elInput) return;\n\n\t$(elInput).off('focus.scheduleEmailSelector');\n\t$(elInput).autocomplete('destroy');\n});\n</script>\n\n<template>\n\t<div\n\t\tclass=\"top-scheduleEmailSelector\"\n\t\tref=\"elRootRef\"\n\t>\n\t\t<TopInput\n\t\t\tref=\"elInputRef\"\n\t\t\t:modelValue\n\t\t\t@update:modelValue=\"$emit('update:modelValue', $event)\"\n\t\t\t@keydown.enter.prevent=\"submit()\"\n\t\t\t:title=\"$i18n.Common.Enter_email\"\n\t\t\ttype=\"email\"\n\t\t\tsize=\"l\"\n\t\t>\n\t\t\t<TopButton\n\t\t\t\tclass=\"top-scheduleEmailSelector_submit\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\ticon=\"\"\n\t\t\t\t@click.prevent=\"submit()\"\n\t\t\t/>\n\t\t</TopInput>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { nextTick, onBeforeUnmount, onMounted, ref } from 'vue';\nimport TopInput from '@/components/forms/input/input.vue';\nimport TopButton from '@/components/forms/button/button.vue';\nimport Core from '@/core/core/core';\nimport { isEmail } from '@/core/utils/check';\nimport { useI18n } from '@/core/plugins/i18n';\nimport type { Props, Emits } from '@/components/schedule/schedule/compoents/emails/selector/types';\n\nconst props = withDefaults(defineProps<Props>(), {\n\temails: () => [],\n\tgetEmailSuggestions: () => [],\n});\n\nconst emit = defineEmits<Emits>();\nconst i18n = useI18n();\nconst $ = Core.$;\n\nconst elRootRef = ref<HTMLElement>();\nconst elInputRef = ref<InstanceType<typeof TopInput>>();\nlet elInput: HTMLInputElement | null = null;\nconst autocompleteCache: Record<string, string[]> = {};\n\nconst filterEmails = (emails: string[]) => emails.filter(email => !props.emails.includes(email));\n\nconst submit = (value: unknown = props.modelValue) => {\n\tconst email = String(value).trim();\n\tif (!email) return;\n\tif (!isEmail(email)) {\n\t\tvoid Core.notice(i18n.Common.Enter_valid_email_notice, 'error');\n\n\t\treturn;\n\t}\n\n\temit('submit', email);\n};\n\nconst initAutocomplete = async () => {\n\tawait nextTick();\n\n\telInput = elInputRef.value?.$el.querySelector('input') ?? null;\n\tif (!elInput) return;\n\n\tif (!$?.ui?.autocomplete) {\n\t\tconsole.info('Для работы autocomplete требуется глобальная загрузка jQuery UI Autocomplete');\n\n\t\treturn;\n\t}\n\n\t$(elInput).autocomplete({\n\t\tappendTo: elRootRef.value,\n\t\tminLength: 0,\n\t\tsource: async (request: { term: string }, response: (items: Array<{ label: string, value: string }>) => void) => {\n\t\t\tconst term = request.term;\n\t\t\tif (!(term in autocompleteCache)) {\n\t\t\t\tautocompleteCache[term] = await props.getEmailSuggestions(term);\n\t\t\t}\n\n\t\t\tresponse(filterEmails(autocompleteCache[term]).map(email => ({\n\t\t\t\tlabel: email,\n\t\t\t\tvalue: email,\n\t\t\t})));\n\t\t},\n\t\tselect: (event: Event, ui: { item?: { value: string } }) => {\n\t\t\tif (!ui.item || !elInput) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tsubmit(ui.item.value);\n\t\t\temit('update:modelValue', '');\n\n\t\t\t$(elInput).trigger('focus');\n\t\t},\n\t});\n\n\t$(elInput).attr('autocomplete', 'disabled');\n\t$(elInput).on('focus.scheduleEmailSelector', () => {\n\t\tif (!elInput) return;\n\n\t\t$(elInput).trigger('input');\n\t});\n};\n\nonMounted(() => {\n\tvoid initAutocomplete();\n});\n\nonBeforeUnmount(() => {\n\tif (!$?.ui?.autocomplete || !elInput) return;\n\n\t$(elInput).off('focus.scheduleEmailSelector');\n\t$(elInput).autocomplete('destroy');\n});\n</script>\n\n<template>\n\t<div\n\t\tclass=\"top-scheduleEmailSelector\"\n\t\tref=\"elRootRef\"\n\t>\n\t\t<TopInput\n\t\t\tref=\"elInputRef\"\n\t\t\t:modelValue\n\t\t\t@update:modelValue=\"$emit('update:modelValue', $event)\"\n\t\t\t@keydown.enter.prevent=\"submit()\"\n\t\t\t:title=\"$i18n.Common.Enter_email\"\n\t\t\ttype=\"email\"\n\t\t\tsize=\"l\"\n\t\t>\n\t\t\t<TopButton\n\t\t\t\tclass=\"top-scheduleEmailSelector_submit\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\ticon=\"\"\n\t\t\t\t@click.prevent=\"submit()\"\n\t\t\t/>\n\t\t</TopInput>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { Props, Emits } from '@/components/schedule/schedule/compoents/emails/types';\nimport ScheduleEmailSelector from '@/components/schedule/schedule/compoents/emails/selector/selector.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\temails: () => [],\n\tgetEmailSuggestions: () => [],\n\tmaxEmailsCount: -1,\n});\n\nconst emit = defineEmits<Emits>();\n\nconst value = ref('');\n\nconst addEmail = (email: string) => {\n\tconst preparedEmail = email.trim();\n\tif (!preparedEmail || props.emails.includes(preparedEmail)) {\n\t\tvalue.value = '';\n\n\t\treturn;\n\t}\n\n\temit('add:email', preparedEmail);\n\n\tvalue.value = '';\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleEmail\">\n\t\t<div class=\"top-scheduleEmail_title\">\n\t\t\t{{ $i18n.Projects.Reports_send_to_address }} E-mail:\n\t\t</div>\n\n\t\t<ScheduleEmailSelector\n\t\t\tv-if=\"!(maxEmailsCount && emails.length === maxEmailsCount)\"\n\t\t\tv-model=\"value\"\n\t\t\t:getEmailSuggestions\n\t\t\t:emails\n\t\t\t@submit=\"addEmail\"\n\t\t/>\n\n\t\t<div\n\t\t\tv-if=\"emails.length\"\n\t\t\tclass=\"top-scheduleEmail_emails\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"top-scheduleEmail_emailsItem\"\n\t\t\t\tv-for=\"email in emails\"\n\t\t\t\t:key=\"email\"\n\t\t\t>\n\t\t\t\t<span class=\"top-ellipsis1\">{{ email }}</span>\n\n\t\t\t\t<TopButton\n\t\t\t\t\t@click=\"$emit('remove:email', email)\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { Props, Emits } from '@/components/schedule/schedule/compoents/emails/types';\nimport ScheduleEmailSelector from '@/components/schedule/schedule/compoents/emails/selector/selector.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\temails: () => [],\n\tgetEmailSuggestions: () => [],\n\tmaxEmailsCount: -1,\n});\n\nconst emit = defineEmits<Emits>();\n\nconst value = ref('');\n\nconst addEmail = (email: string) => {\n\tconst preparedEmail = email.trim();\n\tif (!preparedEmail || props.emails.includes(preparedEmail)) {\n\t\tvalue.value = '';\n\n\t\treturn;\n\t}\n\n\temit('add:email', preparedEmail);\n\n\tvalue.value = '';\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleEmail\">\n\t\t<div class=\"top-scheduleEmail_title\">\n\t\t\t{{ $i18n.Projects.Reports_send_to_address }} E-mail:\n\t\t</div>\n\n\t\t<ScheduleEmailSelector\n\t\t\tv-if=\"!(maxEmailsCount && emails.length === maxEmailsCount)\"\n\t\t\tv-model=\"value\"\n\t\t\t:getEmailSuggestions\n\t\t\t:emails\n\t\t\t@submit=\"addEmail\"\n\t\t/>\n\n\t\t<div\n\t\t\tv-if=\"emails.length\"\n\t\t\tclass=\"top-scheduleEmail_emails\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"top-scheduleEmail_emailsItem\"\n\t\t\t\tv-for=\"email in emails\"\n\t\t\t\t:key=\"email\"\n\t\t\t>\n\t\t\t\t<span class=\"top-ellipsis1\">{{ email }}</span>\n\n\t\t\t\t<TopButton\n\t\t\t\t\t@click=\"$emit('remove:email', email)\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Emits, Props } from '@/components/schedule/schedule/compoents/socials/types';\n\nconst props = defineProps<Props>();\ndefineEmits<Emits>();\n\ntype ReportChannelSource = Props['channels'][number]['source'];\n\nconst hasChannel = (source: ReportChannelSource) => props.channels.some(channel => channel.source === source);\n\nconst sourceIconBySource: Record<ReportChannelSource, string> = {\n\tinformer: '',\n\ttelegram: '',\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleSocials\">\n\t\t<div class=\"top-scheduleSocials_title\">\n\t\t\t{{ $i18n.Projects.Reports_send_to_address }}\n\t\t</div>\n\n\t\t<div class=\"top-scheduleSocials_channels\">\n\t\t\t<div\n\t\t\t\tclass=\"top-scheduleSocials_channel\"\n\t\t\t\tv-for=\"channel in channels\"\n\t\t\t\t:key=\"`${channel.source}-${channel.id}`\"\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tclass=\"top-scheduleSocials_channelIcon\"\n\t\t\t\t\t:data-top-icon=\"sourceIconBySource[channel.source]\"\n\t\t\t\t></span>\n\n\t\t\t\t<span class=\"top-scheduleSocials_channelLabel top-ellipsis1\">\n\t\t\t\t\t{{ channel.label }}\n\t\t\t\t</span>\n\n\t\t\t\t<TopButton\n\t\t\t\t\tv-if=\"channel.settingLink\"\n\t\t\t\t\tclass=\"top-scheduleSocials_channelSettings\"\n\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t:href=\"channel.settingLink\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t></TopButton>\n\n\t\t\t\t<TopSwitcher\n\t\t\t\t\tclass=\"top-scheduleSocials_channelSwitcher\"\n\t\t\t\t\t:modelValue=\"channel.selected\"\n\t\t\t\t\t@update:modelValue=\"$emit('update:channelSelected', {\n\t\t\t\t\t\tid: channel.id,\n\t\t\t\t\t\tsource: channel.source,\n\t\t\t\t\t\tselected: $event as boolean,\n\t\t\t\t\t})\"\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<template\n\t\t\t\tv-for=\"connector in connectors\"\n\t\t\t\t:key=\"connector.source\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tv-if=\"!hasChannel(connector.source)\"\n\t\t\t\tclass=\"top-scheduleSocials_channel\"\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"top-scheduleSocials_channelIcon\"\n\t\t\t\t\t\t:data-top-icon=\"sourceIconBySource[connector.source]\"\n\t\t\t\t\t></span>\n\n\t\t\t\t\t<a\n\t\t\t\t\t\tclass=\"top-scheduleSocials_channelLabel top-ellipsis1\"\n\t\t\t\t\t\t:href=\"connector.connectLink\"\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ connector.connectLabel }}\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Emits, Props } from '@/components/schedule/schedule/compoents/socials/types';\n\nconst props = defineProps<Props>();\ndefineEmits<Emits>();\n\ntype ReportChannelSource = Props['channels'][number]['source'];\n\nconst hasChannel = (source: ReportChannelSource) => props.channels.some(channel => channel.source === source);\n\nconst sourceIconBySource: Record<ReportChannelSource, string> = {\n\tinformer: '',\n\ttelegram: '',\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleSocials\">\n\t\t<div class=\"top-scheduleSocials_title\">\n\t\t\t{{ $i18n.Projects.Reports_send_to_address }}\n\t\t</div>\n\n\t\t<div class=\"top-scheduleSocials_channels\">\n\t\t\t<div\n\t\t\t\tclass=\"top-scheduleSocials_channel\"\n\t\t\t\tv-for=\"channel in channels\"\n\t\t\t\t:key=\"`${channel.source}-${channel.id}`\"\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tclass=\"top-scheduleSocials_channelIcon\"\n\t\t\t\t\t:data-top-icon=\"sourceIconBySource[channel.source]\"\n\t\t\t\t></span>\n\n\t\t\t\t<span class=\"top-scheduleSocials_channelLabel top-ellipsis1\">\n\t\t\t\t\t{{ channel.label }}\n\t\t\t\t</span>\n\n\t\t\t\t<TopButton\n\t\t\t\t\tv-if=\"channel.settingLink\"\n\t\t\t\t\tclass=\"top-scheduleSocials_channelSettings\"\n\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t:href=\"channel.settingLink\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t></TopButton>\n\n\t\t\t\t<TopSwitcher\n\t\t\t\t\tclass=\"top-scheduleSocials_channelSwitcher\"\n\t\t\t\t\t:modelValue=\"channel.selected\"\n\t\t\t\t\t@update:modelValue=\"$emit('update:channelSelected', {\n\t\t\t\t\t\tid: channel.id,\n\t\t\t\t\t\tsource: channel.source,\n\t\t\t\t\t\tselected: $event as boolean,\n\t\t\t\t\t})\"\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<template\n\t\t\t\tv-for=\"connector in connectors\"\n\t\t\t\t:key=\"connector.source\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tv-if=\"!hasChannel(connector.source)\"\n\t\t\t\tclass=\"top-scheduleSocials_channel\"\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"top-scheduleSocials_channelIcon\"\n\t\t\t\t\t\t:data-top-icon=\"sourceIconBySource[connector.source]\"\n\t\t\t\t\t></span>\n\n\t\t\t\t\t<a\n\t\t\t\t\t\tclass=\"top-scheduleSocials_channelLabel top-ellipsis1\"\n\t\t\t\t\t\t:href=\"connector.connectLink\"\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ connector.connectLabel }}\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"schedule.js","names":[],"sources":["../../src/components/schedule/schedule/components/calendar/composables/useDaysByCalendarMode.ts","../../src/components/schedule/schedule/components/timeSelector/timeSelector.vue","../../src/components/schedule/schedule/components/timeSelector/timeSelector.vue","../../src/components/schedule/schedule/components/calendar/calendar.vue","../../src/components/schedule/schedule/components/calendar/calendar.vue","../../src/components/schedule/schedule/utils.ts","../../src/components/schedule/schedule/composables/useModeOptions.ts","../../src/components/schedule/schedule/composables/useModelByModeCache.ts","../../src/components/schedule/schedule/schedule.vue","../../src/components/schedule/schedule/schedule.vue","../../src/components/schedule/schedule/components/emails/selector/selector.vue","../../src/components/schedule/schedule/components/emails/selector/selector.vue","../../src/components/schedule/schedule/components/emails/emails.vue","../../src/components/schedule/schedule/components/emails/emails.vue","../../src/components/schedule/schedule/components/socials/socials.vue","../../src/components/schedule/schedule/components/socials/socials.vue"],"sourcesContent":["import { computed, type MaybeRefOrGetter, toValue } from 'vue';\nimport type { Day, Props } from '../types';\nimport { useI18n } from '@/core/app';\n\n/**\n * Формирует список дней для выбранного режима календаря.\n */\nexport const useDaysByCalendarMode = (mode: MaybeRefOrGetter<Props['mode']>) => {\n\tconst i18n = useI18n();\n\n\treturn computed<Day[]>(() => {\n\t\tswitch (toValue(mode)) {\n\t\t\t// Дни месяца\n\t\t\tcase 'dayOfMonth': {\n\t\t\t\tconst days: Day[] = Array.from({ length: 27 }, (_, index) => ({\n\t\t\t\t\tvalue: String(index + 1) as Day['value'],\n\t\t\t\t\ttitle: String(index + 1),\n\t\t\t\t}));\n\n\t\t\t\tdays.push({\n\t\t\t\t\tvalue: 'LAST_OF_MONTH',\n\t\t\t\t\ttitle: '',\n\t\t\t\t\tisIcon: true,\n\t\t\t\t});\n\n\t\t\t\treturn days;\n\t\t\t}\n\n\t\t\t// Дни недели\n\t\t\tcase 'dayOfWeek':\n\t\t\t\treturn [\n\t\t\t\t\t{ value: 'MONDAY', title: i18n.Calendar.Dw_1 },\n\t\t\t\t\t{ value: 'TUESDAY', title: i18n.Calendar.Dw_2 },\n\t\t\t\t\t{ value: 'WEDNESDAY', title: i18n.Calendar.Dw_3 },\n\t\t\t\t\t{ value: 'THURSDAY', title: i18n.Calendar.Dw_4 },\n\t\t\t\t\t{ value: 'FRIDAY', title: i18n.Calendar.Dw_5 },\n\t\t\t\t\t{ value: 'SATURDAY', title: i18n.Calendar.Dw_6 },\n\t\t\t\t\t{ value: 'SUNDAY', title: i18n.Calendar.Dw_7 },\n\t\t\t\t];\n\n\t\t\tdefault:\n\t\t\t\treturn [];\n\t\t}\n\t});\n};\n","<script setup lang=\"ts\">\nimport type { Props } from '@/components/schedule/schedule/components/timeSelector/types';\n\nconst props = defineProps<Props>();\n\nconst times = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\n/**\n * Варианты выбора часа от `00` до `23`.\n *\n * Поддерижвает вставку произвольного значения через `modelValue` для констант периода.\n */\nconst hourOptions = Array.from({ length: 24 }, (_, index) => ({\n\tvalue: String(index),\n\ttitle: String(index).padStart(2, '0'),\n}));\n\n/**\n * Предустановленные варианты минут.\n *\n * Поддерижвает вставку произвольного значения через `modelValue`.\n */\nconst minuteOptions = Array.from({ length: 4 }, (_, index) => {\n\tconst minute = index * 15;\n\n\treturn {\n\t\tvalue: String(minute),\n\t\ttitle: String(minute).padStart(2, '0'),\n\t};\n});\n\nconst updateTimeByIndex = (index: number, patch: Partial<Props['modelValue'][number]>) => {\n\tconst nextTimes = [...times.value];\n\tnextTimes[index] = { ...nextTimes[index], ...patch };\n\n\ttimes.value = nextTimes;\n};\n\n/**\n * Добавить временной слот.\n *\n * UX: Временной слот должен добавляться в конец списка:\n * - текущий временной слот не должен заменться новым и спускаться ниже\n * - пржений список сохраняет привычный порядок\n * - должно быть видно новый слот\n * - новый слот должно быть можно удалить\n */\nconst addTime = () => {\n\ttimes.value = [\n\t\t...times.value,\n\t\t{\n\t\t\thour: '0',\n\t\t\tminute: '0',\n\t\t},\n\t];\n};\n\nconst delTime = (index: number) => {\n\ttimes.value = times.value.filter((_, timeIndex) => timeIndex !== index);\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleTimeSelector\">\n\t\t<div v-for=\"(time, index) in times\" :key=\"index\" class=\"top-scheduleTimeSelector_item\">\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-scheduleTimeSelector_hour\"\n\t\t\t\t:modelValue=\"time.hour\"\n\t\t\t\t:options=\"hourOptions\"\n\t\t\t\tavailableCustomValue\n\t\t\t\t@update:modelValue=\"updateTimeByIndex(index, { hour: $event as Props['modelValue'][number]['hour'] })\"\n\t\t\t/>\n\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-scheduleTimeSelector_minute\"\n\t\t\t\t:modelValue=\"time.minute\"\n\t\t\t\t:options=\"minuteOptions\"\n\t\t\t\tavailableCustomValue\n\t\t\t\t@update:modelValue=\"updateTimeByIndex(index, { minute: $event as Props['modelValue'][number]['minute'] })\"\n\t\t\t/>\n\n\t\t\t<TopButton\n\t\t\t\tv-if=\"props.multipleTimes || times.length > 1\"\n\t\t\t\t@click=\"index ? delTime(index) : addTime()\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\t:icon=\"index ? '' : ''\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Props } from '@/components/schedule/schedule/components/timeSelector/types';\n\nconst props = defineProps<Props>();\n\nconst times = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\n/**\n * Варианты выбора часа от `00` до `23`.\n *\n * Поддерижвает вставку произвольного значения через `modelValue` для констант периода.\n */\nconst hourOptions = Array.from({ length: 24 }, (_, index) => ({\n\tvalue: String(index),\n\ttitle: String(index).padStart(2, '0'),\n}));\n\n/**\n * Предустановленные варианты минут.\n *\n * Поддерижвает вставку произвольного значения через `modelValue`.\n */\nconst minuteOptions = Array.from({ length: 4 }, (_, index) => {\n\tconst minute = index * 15;\n\n\treturn {\n\t\tvalue: String(minute),\n\t\ttitle: String(minute).padStart(2, '0'),\n\t};\n});\n\nconst updateTimeByIndex = (index: number, patch: Partial<Props['modelValue'][number]>) => {\n\tconst nextTimes = [...times.value];\n\tnextTimes[index] = { ...nextTimes[index], ...patch };\n\n\ttimes.value = nextTimes;\n};\n\n/**\n * Добавить временной слот.\n *\n * UX: Временной слот должен добавляться в конец списка:\n * - текущий временной слот не должен заменться новым и спускаться ниже\n * - пржений список сохраняет привычный порядок\n * - должно быть видно новый слот\n * - новый слот должно быть можно удалить\n */\nconst addTime = () => {\n\ttimes.value = [\n\t\t...times.value,\n\t\t{\n\t\t\thour: '0',\n\t\t\tminute: '0',\n\t\t},\n\t];\n};\n\nconst delTime = (index: number) => {\n\ttimes.value = times.value.filter((_, timeIndex) => timeIndex !== index);\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleTimeSelector\">\n\t\t<div v-for=\"(time, index) in times\" :key=\"index\" class=\"top-scheduleTimeSelector_item\">\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-scheduleTimeSelector_hour\"\n\t\t\t\t:modelValue=\"time.hour\"\n\t\t\t\t:options=\"hourOptions\"\n\t\t\t\tavailableCustomValue\n\t\t\t\t@update:modelValue=\"updateTimeByIndex(index, { hour: $event as Props['modelValue'][number]['hour'] })\"\n\t\t\t/>\n\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-scheduleTimeSelector_minute\"\n\t\t\t\t:modelValue=\"time.minute\"\n\t\t\t\t:options=\"minuteOptions\"\n\t\t\t\tavailableCustomValue\n\t\t\t\t@update:modelValue=\"updateTimeByIndex(index, { minute: $event as Props['modelValue'][number]['minute'] })\"\n\t\t\t/>\n\n\t\t\t<TopButton\n\t\t\t\tv-if=\"props.multipleTimes || times.length > 1\"\n\t\t\t\t@click=\"index ? delTime(index) : addTime()\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\t:icon=\"index ? '' : ''\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Props } from '@/components/schedule/schedule/components/calendar/types';\nimport { useDaysByCalendarMode } from './composables/useDaysByCalendarMode';\nimport { numberEnding } from '@/core/utils/string';\nimport { computed } from 'vue';\nimport TopScheduleTimeSelector from '@/components/schedule/schedule/components/timeSelector/timeSelector.vue';\n\nconst props = defineProps<Props>();\n\nconst selectedDays = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\nconst times = defineModel<Props['times']>('times', {\n\trequired: true,\n});\n\nconst days = useDaysByCalendarMode(() => props.mode);\n\nconst isAllDaysSelected = computed(() => selectedDays.value.includes('ALL') || selectedDays.value.length === days.value.length);\n\nconst toggleDay = (day: Props['modelValue'][number]) => {\n\tconst nextDays = selectedDays.value.includes('ALL') ? days.value.map(item => item.value) : [...selectedDays.value];\n\tconst dayIndex = nextDays.indexOf(day);\n\n\tif (dayIndex === -1) {\n\t\tnextDays.push(day);\n\t} else {\n\t\tnextDays.splice(dayIndex, 1);\n\t}\n\n\tselectedDays.value = nextDays.length === days.value.length ? ['ALL'] : nextDays;\n};\n\nconst toggleSelectAll = () => {\n\tselectedDays.value = isAllDaysSelected.value ? [] : ['ALL'];\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleCalendar\">\n\t\t<div class=\"top-scheduleCalendar_header\">\n\t\t\t<TopScheduleTimeSelector v-model=\"times\" :multipleTimes />\n\n\t\t\t<TopButton\n\t\t\t\t@click=\"toggleSelectAll()\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\ttabindex=\"0\"\n\t\t\t>\n\t\t\t\t{{ isAllDaysSelected ? $i18n.Common.Clear : $i18n.Common.Select_all }}\n\t\t\t</TopButton>\n\t\t</div>\n\n\t\t<div class=\"top-scheduleCalendar_calendar\">\n\t\t\t<label\n\t\t\t\tclass=\"top-scheduleCalendar_calendarDay\"\n\t\t\t\tv-for=\"day in days\"\n\t\t\t\t:key=\"day.value\"\n\t\t\t>\n\t\t\t\t<input\n\t\t\t\t\tclass=\"top-scheduleCalendar_calendarDayCheckbox\"\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t:value=\"day.value\"\n\t\t\t\t\t:checked=\"selectedDays.includes('ALL') || selectedDays.includes(day.value)\"\n\t\t\t\t\t@change=\"toggleDay(day.value)\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\n\t\t\t\t<span :data-top-icon=\"day.isIcon ? day.title : undefined\">\n\t\t\t\t\t<template v-if=\"!day.isIcon\">\n\t\t\t\t\t\t{{ day.title }}\n\t\t\t\t\t</template>\n\t\t\t\t</span>\n\t\t\t</label>\n\t\t</div>\n\n\t\t<span\n\t\t\t:class=\"{\n\t\t\t\t'top-scheduleCalendar_selectionSummary': true,\n\t\t\t'top-error': !selectedDays.length\n\t\t\t}\"\n\t\t>\n\t\t\t<!-- Каждый день или Число проверок в неделю / месяц-->\n\t\t\t{{\n\t\t\t\tisAllDaysSelected ?\n\t\t\t\t\t$i18n.Common.Every_day :\n\t\t\t\t\tselectedDays.length\n\t\t\t}}\n\n\t\t\t<template v-if=\"times.length > 1 || !isAllDaysSelected\">\n\t\t\t\t<!-- Добавить число временных слотов, если их несколько -->\n\t\t\t\t{{ times.length > 1 ? ` × ${times.length}` : '' }}\n\n\t\t\t\t<!-- Суффикс \"раз\" -->\n\t\t\t\t{{\n\t\t\t\t\tnumberEnding(\n\t\t\t\t\t\ttimes.length === 1 ? selectedDays.length : times.length,\n\t\t\t\t\t\t$i18n.Common.time_a_0,\n\t\t\t\t\t\t$i18n.Common.time_a_0,\n\t\t\t\t\t\t$i18n.Common.time_a_2,\n\t\t\t\t\t)\n\t\t\t\t}}\n\n\t\t\t\t<!-- В неделю / месяц-->\n\t\t\t\t{{ mode === 'dayOfWeek' ? $i18n.Common.a_week : $i18n.Common.a_month }}\n\t\t\t</template>\n\t\t</span>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Props } from '@/components/schedule/schedule/components/calendar/types';\nimport { useDaysByCalendarMode } from './composables/useDaysByCalendarMode';\nimport { numberEnding } from '@/core/utils/string';\nimport { computed } from 'vue';\nimport TopScheduleTimeSelector from '@/components/schedule/schedule/components/timeSelector/timeSelector.vue';\n\nconst props = defineProps<Props>();\n\nconst selectedDays = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\nconst times = defineModel<Props['times']>('times', {\n\trequired: true,\n});\n\nconst days = useDaysByCalendarMode(() => props.mode);\n\nconst isAllDaysSelected = computed(() => selectedDays.value.includes('ALL') || selectedDays.value.length === days.value.length);\n\nconst toggleDay = (day: Props['modelValue'][number]) => {\n\tconst nextDays = selectedDays.value.includes('ALL') ? days.value.map(item => item.value) : [...selectedDays.value];\n\tconst dayIndex = nextDays.indexOf(day);\n\n\tif (dayIndex === -1) {\n\t\tnextDays.push(day);\n\t} else {\n\t\tnextDays.splice(dayIndex, 1);\n\t}\n\n\tselectedDays.value = nextDays.length === days.value.length ? ['ALL'] : nextDays;\n};\n\nconst toggleSelectAll = () => {\n\tselectedDays.value = isAllDaysSelected.value ? [] : ['ALL'];\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleCalendar\">\n\t\t<div class=\"top-scheduleCalendar_header\">\n\t\t\t<TopScheduleTimeSelector v-model=\"times\" :multipleTimes />\n\n\t\t\t<TopButton\n\t\t\t\t@click=\"toggleSelectAll()\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\ttabindex=\"0\"\n\t\t\t>\n\t\t\t\t{{ isAllDaysSelected ? $i18n.Common.Clear : $i18n.Common.Select_all }}\n\t\t\t</TopButton>\n\t\t</div>\n\n\t\t<div class=\"top-scheduleCalendar_calendar\">\n\t\t\t<label\n\t\t\t\tclass=\"top-scheduleCalendar_calendarDay\"\n\t\t\t\tv-for=\"day in days\"\n\t\t\t\t:key=\"day.value\"\n\t\t\t>\n\t\t\t\t<input\n\t\t\t\t\tclass=\"top-scheduleCalendar_calendarDayCheckbox\"\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t:value=\"day.value\"\n\t\t\t\t\t:checked=\"selectedDays.includes('ALL') || selectedDays.includes(day.value)\"\n\t\t\t\t\t@change=\"toggleDay(day.value)\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\n\t\t\t\t<span :data-top-icon=\"day.isIcon ? day.title : undefined\">\n\t\t\t\t\t<template v-if=\"!day.isIcon\">\n\t\t\t\t\t\t{{ day.title }}\n\t\t\t\t\t</template>\n\t\t\t\t</span>\n\t\t\t</label>\n\t\t</div>\n\n\t\t<span\n\t\t\t:class=\"{\n\t\t\t\t'top-scheduleCalendar_selectionSummary': true,\n\t\t\t'top-error': !selectedDays.length\n\t\t\t}\"\n\t\t>\n\t\t\t<!-- Каждый день или Число проверок в неделю / месяц-->\n\t\t\t{{\n\t\t\t\tisAllDaysSelected ?\n\t\t\t\t\t$i18n.Common.Every_day :\n\t\t\t\t\tselectedDays.length\n\t\t\t}}\n\n\t\t\t<template v-if=\"times.length > 1 || !isAllDaysSelected\">\n\t\t\t\t<!-- Добавить число временных слотов, если их несколько -->\n\t\t\t\t{{ times.length > 1 ? ` × ${times.length}` : '' }}\n\n\t\t\t\t<!-- Суффикс \"раз\" -->\n\t\t\t\t{{\n\t\t\t\t\tnumberEnding(\n\t\t\t\t\t\ttimes.length === 1 ? selectedDays.length : times.length,\n\t\t\t\t\t\t$i18n.Common.time_a_0,\n\t\t\t\t\t\t$i18n.Common.time_a_0,\n\t\t\t\t\t\t$i18n.Common.time_a_2,\n\t\t\t\t\t)\n\t\t\t\t}}\n\n\t\t\t\t<!-- В неделю / месяц-->\n\t\t\t\t{{ mode === 'dayOfWeek' ? $i18n.Common.a_week : $i18n.Common.a_month }}\n\t\t\t</template>\n\t\t</span>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","import type { Props as CalendarProps } from '@/components/schedule/schedule/components/calendar/types';\nimport type { Mode, Props } from './types';\nimport type { Option as TopSelectOption } from '@/components/forms/select/types';\nimport { useI18n } from '@/core/plugins/i18n';\n\n/**\n * Генерирует варианты задержки запуска после апдейта Яндекса.\n *\n * См. Апометр\n */\nexport const genAfterYandexUpdatedOptions = (): TopSelectOption[] => {\n\tconst i18n = useI18n();\n\n\treturn [\n\t\t{\n\t\t\tvalue: '0',\n\t\t\ttitle: i18n.Projects.immediately,\n\t\t},\n\t\t...Array.from({ length: 24 }, (_, index) => ({\n\t\t\tvalue: String(index + 1),\n\t\t\ttitle: i18n('Projects', 'in_hour', { hour: index + 1 }),\n\t\t})),\n\t];\n};\n\n/**\n * Проверяет, относится ли режим к календарным режимам.\n *\n * Календарный режим, это режим с выбором дней недели или месяца.\n */\nexport const isCalendarMode = (value: Mode): value is CalendarProps['mode'] => value === 'dayOfWeek' || value === 'dayOfMonth';\n\n/**\n * Определяет режим расписания по выбранным дням.\n */\nexport const getModeByDays = (days: Props['modelValue']['days'], currentMode: Mode = 'onDemand'): Mode => {\n\tif (days.includes('YANDEX_UPDATE')) return 'afterYandexUpdated';\n\tif (days.includes('CHECK_POSITIONS')) return 'afterCheck';\n\tif (days.includes('LAST_OF_MONTH') || days.some(day => /^\\d+$/.test(day))) return 'dayOfMonth';\n\n\tif (days.length) {\n\t\t// Сохраняем текущий календарный режим\n\t\tif (isCalendarMode(currentMode)) return currentMode;\n\n\t\t// Режим по умолчанию для `ALL`\n\t\treturn 'dayOfWeek';\n\t}\n\n\treturn currentMode;\n};\n","import { computed, type Ref } from 'vue';\nimport type { Option as TopSelectOption } from '@/components/forms/select/types';\nimport { useI18n } from '@/core/plugins/i18n';\nimport type { Mode, Props } from '../types';\n\nconst defaultModsGo: readonly Mode[] = ['onDemand', 'dayOfWeek', 'dayOfMonth'];\nconst defaultModsReport: readonly Mode[] = ['onDemand', 'afterCheck'];\n\n/**\n * Формирует реактивный список режимов расписания с учетом дополнительных режимов.\n */\nexport const useModeOptions = (props: Props, mode: Ref<Mode>) => {\n\tconst i18n = useI18n();\n\n\treturn computed<TopSelectOption[]>(() => {\n\t\tconst modes: Mode[] = props.type === 'go' ? [...defaultModsGo] : [...defaultModsReport];\n\n\t\tif (props.extraMods) {\n\t\t\tmodes.push(...props.extraMods);\n\t\t}\n\n\t\t// Всегда отображать выбранный режим.\n\t\tif (!modes.includes(mode.value)) modes.push(mode.value);\n\n\t\t// Словарь Dynamics нужен только потребителям режима afterCheck.\n\t\tconst titles: Record<Mode, string> = {\n\t\t\tonDemand: i18n.Projects.Settings_on_demand,\n\t\t\tdayOfWeek: i18n.Projects.Report_on_weekdays,\n\t\t\tdayOfMonth: i18n.Projects.Settings_particular_days,\n\t\t\tafterYandexUpdated: i18n.Projects.After_updates,\n\t\t\tafterCheck: modes.includes('afterCheck') ? i18n.Dynamics.Report_after_tracking_30min_1 : '',\n\t\t};\n\n\t\treturn modes.map(value => ({ value, title: titles[value] }));\n\t});\n};\n","import { watch, type Ref } from 'vue';\nimport type { Mode, Props } from '../types';\nimport { isCalendarMode } from '../utils';\n\n/**\n * Создаёт независимую копию модели расписания.\n */\nconst cloneModel = (model: Props['modelValue']): Props['modelValue'] => ({\n\tdays: [...model.days],\n\ttimes: model.times.map(time => ({ ...time })),\n});\n\n/**\n * Сохраняет дни и временные слоты модели по режимам расписания.\n */\nexport const useModelByModeCache = (model: Ref<Props['modelValue']>, mode: Ref<Mode>) => {\n\ttype TimeCacheMode = Mode | 'calendar';\n\n\tconst cache = {\n\t\t// Дни календарных режимов кэшируем отдельно.\n\t\tdaysByMode: {} as Partial<Record<Mode, Props['modelValue']['days']>>,\n\n\t\t// Временные слоты храним по режимам, используя общий ключ `calendar` для недели и месяца.\n\t\ttimesByMode: {} as Partial<Record<TimeCacheMode, Props['modelValue']['times']>>,\n\t};\n\n\t// Сохранять настройки выбранного режима\n\twatch(model, () => {\n\t\tconst modelCached = cloneModel(model.value);\n\n\t\tcache.daysByMode[mode.value] = modelCached.days;\n\t\tcache.timesByMode[isCalendarMode(mode.value) ? 'calendar' : mode.value] = modelCached.times;\n\t}, { deep: true, immediate: true });\n\n\treturn cache;\n};\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport TopSelect from '@/components/forms/select/select.vue';\nimport TopScheduleCalendar from '@/components/schedule/schedule/components/calendar/calendar.vue';\nimport type { Mode, Props, Slots } from './types';\nimport { genAfterYandexUpdatedOptions, getModeByDays, isCalendarMode } from './utils';\nimport { useModeOptions } from './composables/useModeOptions';\nimport { useModelByModeCache } from './composables/useModelByModeCache';\n\n/**\n * Используется для размытия нагрузка на разное время\n */\nconst randomHour = String(Math.floor(Math.random() * 7) + 1) as Props['modelValue']['times'][number]['hour'];\n\nconst props = withDefaults(defineProps<Props>(), {\n\t// Тип `go` соответствует запуску инструмента по расписанию.\n\ttype: 'go',\n});\n\ndefineSlots<Slots>();\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\n// Выбранный режим\nconst mode = ref<Mode>(getModeByDays(model.value.days));\n\n// Список режимов\nconst modeOptions = useModeOptions(props, mode);\n\nconst afterYandexUpdatedOptions = genAfterYandexUpdatedOptions();\n\n// Кэш дней по режимам и временных слотов по группам расписания.\nconst cache = useModelByModeCache(model, mode);\n\n/**\n * При смене `days` сразу проверяем доступное значение режима и обновляем его, если надо.\n *\n * @note 1 в цепочке перед `watch(mode)`, цепочки не цикличны\n */\nwatch(\n\t() => model.value.days,\n\t() => mode.value = getModeByDays(model.value.days, mode.value),\n\t{ deep: true, immediate: true },\n);\n\n/**\n * При смене режима устанавливаем соответствующие `days` и `times`.\n *\n * Для календарных режимов восстанавливаем ранее сохранённый выбор дней.\n *\n * @note 2 в цепочке после `watch(() => model.value.days)`, цепочки не цикличны\n */\nwatch(mode, (newMode, oldMode) => {\n\t// Для недели и месяца временные слоты берём из общего кэша `calendar`.\n\tconst daysCached = cache.daysByMode[newMode];\n\tconst timesCached = cache.timesByMode[isCalendarMode(newMode) ? 'calendar' : newMode];\n\n\tconst modelPath: Partial<Props['modelValue']> = {};\n\tconst modeChaged = oldMode;\n\n\tswitch (newMode) {\n\t\tcase 'onDemand':\n\t\t\tif (modeChaged || model.value.days.length) modelPath.days = [];\n\t\t\tif (modeChaged || model.value.times.length) modelPath.times = [];\n\n\t\t\tbreak;\n\t\tcase 'dayOfWeek':\n\t\tcase 'dayOfMonth': {\n\t\t\tif (modeChaged || !model.value.days.length) modelPath.days = daysCached ?? ['ALL'];\n\t\t\tif (modeChaged || !model.value.times.length) modelPath.times = timesCached?.length ? timesCached : [{ hour: randomHour, minute: '0' }];\n\n\t\t\tbreak;\n\t\t}\n\t\tcase 'afterYandexUpdated':\n\t\t\tif (modeChaged || model.value.days[0] !== 'YANDEX_UPDATE') modelPath.days = ['YANDEX_UPDATE'];\n\t\t\tif (modeChaged || !model.value.times.length) modelPath.times = timesCached?.length ? timesCached : [{ hour: '1', minute: '0' }];\n\n\t\t\tbreak;\n\t\tcase 'afterCheck':\n\t\t\tif (modeChaged || model.value.days[0] !== 'CHECK_POSITIONS') modelPath.days = ['CHECK_POSITIONS'];\n\t\t\tif (modeChaged || !model.value.times.length) modelPath.times = timesCached?.length ? timesCached : [{ hour: '0', minute: '0' }];\n\n\t\t\tbreak;\n\t}\n\n\t// Отправляем новое значение только тогда, когда хотя бы одно поле требует изменения.\n\tif (Object.keys(modelPath).length) model.value = { ...model.value, ...modelPath };\n}, { immediate: true });\n</script>\n\n<template>\n\t<div :class=\"['top-schedule', 'top-schedule-type_' + type]\">\n\t\t<div class=\"top-schedule_header\">\n\t\t\t<div class=\"top-schedule_headerTitle\">\n\t\t\t\t{{ title ?? (type === 'go' ? $i18n.Projects.Checks : $i18n.Projects.Reports) }}\n\t\t\t</div>\n\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-schedule_headerMods\"\n\t\t\t\tv-model=\"mode\"\n\t\t\t\t:options=\"modeOptions\"\n\t\t\t\tsize=\"s\"\n\t\t\t/>\n\t\t</div>\n\n\t\t<div v-if=\"mode !== 'onDemand' && (isCalendarMode(mode) || mode === 'afterYandexUpdated' || $slots.default)\" class=\"top-schedule_body\">\n\t\t\t<TopScheduleCalendar\n\t\t\t\tv-if=\"isCalendarMode(mode)\"\n\t\t\t\tv-model=\"model.days\"\n\t\t\t\tv-model:times=\"model.times\"\n\t\t\t\t:mode\n\t\t\t\t:multipleTimes\n\t\t\t/>\n\n\t\t\t<TopSelect\n\t\t\t\tv-if=\"mode === 'afterYandexUpdated' && model.times[0]\"\n\t\t\t\tclass=\"top-schedule_afterYandexUpdatedDelay\"\n\t\t\t\tv-model=\"model.times[0].hour\"\n\t\t\t\t:options=\"afterYandexUpdatedOptions\"\n\t\t\t\tsize=\"s\"\n\t\t\t/>\n\n\t\t\t<hr v-if=\"(isCalendarMode(mode) || mode === 'afterYandexUpdated') && $slots.default\">\n\n\t\t\t<slot :mode></slot>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport TopSelect from '@/components/forms/select/select.vue';\nimport TopScheduleCalendar from '@/components/schedule/schedule/components/calendar/calendar.vue';\nimport type { Mode, Props, Slots } from './types';\nimport { genAfterYandexUpdatedOptions, getModeByDays, isCalendarMode } from './utils';\nimport { useModeOptions } from './composables/useModeOptions';\nimport { useModelByModeCache } from './composables/useModelByModeCache';\n\n/**\n * Используется для размытия нагрузка на разное время\n */\nconst randomHour = String(Math.floor(Math.random() * 7) + 1) as Props['modelValue']['times'][number]['hour'];\n\nconst props = withDefaults(defineProps<Props>(), {\n\t// Тип `go` соответствует запуску инструмента по расписанию.\n\ttype: 'go',\n});\n\ndefineSlots<Slots>();\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\n// Выбранный режим\nconst mode = ref<Mode>(getModeByDays(model.value.days));\n\n// Список режимов\nconst modeOptions = useModeOptions(props, mode);\n\nconst afterYandexUpdatedOptions = genAfterYandexUpdatedOptions();\n\n// Кэш дней по режимам и временных слотов по группам расписания.\nconst cache = useModelByModeCache(model, mode);\n\n/**\n * При смене `days` сразу проверяем доступное значение режима и обновляем его, если надо.\n *\n * @note 1 в цепочке перед `watch(mode)`, цепочки не цикличны\n */\nwatch(\n\t() => model.value.days,\n\t() => mode.value = getModeByDays(model.value.days, mode.value),\n\t{ deep: true, immediate: true },\n);\n\n/**\n * При смене режима устанавливаем соответствующие `days` и `times`.\n *\n * Для календарных режимов восстанавливаем ранее сохранённый выбор дней.\n *\n * @note 2 в цепочке после `watch(() => model.value.days)`, цепочки не цикличны\n */\nwatch(mode, (newMode, oldMode) => {\n\t// Для недели и месяца временные слоты берём из общего кэша `calendar`.\n\tconst daysCached = cache.daysByMode[newMode];\n\tconst timesCached = cache.timesByMode[isCalendarMode(newMode) ? 'calendar' : newMode];\n\n\tconst modelPath: Partial<Props['modelValue']> = {};\n\tconst modeChaged = oldMode;\n\n\tswitch (newMode) {\n\t\tcase 'onDemand':\n\t\t\tif (modeChaged || model.value.days.length) modelPath.days = [];\n\t\t\tif (modeChaged || model.value.times.length) modelPath.times = [];\n\n\t\t\tbreak;\n\t\tcase 'dayOfWeek':\n\t\tcase 'dayOfMonth': {\n\t\t\tif (modeChaged || !model.value.days.length) modelPath.days = daysCached ?? ['ALL'];\n\t\t\tif (modeChaged || !model.value.times.length) modelPath.times = timesCached?.length ? timesCached : [{ hour: randomHour, minute: '0' }];\n\n\t\t\tbreak;\n\t\t}\n\t\tcase 'afterYandexUpdated':\n\t\t\tif (modeChaged || model.value.days[0] !== 'YANDEX_UPDATE') modelPath.days = ['YANDEX_UPDATE'];\n\t\t\tif (modeChaged || !model.value.times.length) modelPath.times = timesCached?.length ? timesCached : [{ hour: '1', minute: '0' }];\n\n\t\t\tbreak;\n\t\tcase 'afterCheck':\n\t\t\tif (modeChaged || model.value.days[0] !== 'CHECK_POSITIONS') modelPath.days = ['CHECK_POSITIONS'];\n\t\t\tif (modeChaged || !model.value.times.length) modelPath.times = timesCached?.length ? timesCached : [{ hour: '0', minute: '0' }];\n\n\t\t\tbreak;\n\t}\n\n\t// Отправляем новое значение только тогда, когда хотя бы одно поле требует изменения.\n\tif (Object.keys(modelPath).length) model.value = { ...model.value, ...modelPath };\n}, { immediate: true });\n</script>\n\n<template>\n\t<div :class=\"['top-schedule', 'top-schedule-type_' + type]\">\n\t\t<div class=\"top-schedule_header\">\n\t\t\t<div class=\"top-schedule_headerTitle\">\n\t\t\t\t{{ title ?? (type === 'go' ? $i18n.Projects.Checks : $i18n.Projects.Reports) }}\n\t\t\t</div>\n\n\t\t\t<TopSelect\n\t\t\t\tclass=\"top-schedule_headerMods\"\n\t\t\t\tv-model=\"mode\"\n\t\t\t\t:options=\"modeOptions\"\n\t\t\t\tsize=\"s\"\n\t\t\t/>\n\t\t</div>\n\n\t\t<div v-if=\"mode !== 'onDemand' && (isCalendarMode(mode) || mode === 'afterYandexUpdated' || $slots.default)\" class=\"top-schedule_body\">\n\t\t\t<TopScheduleCalendar\n\t\t\t\tv-if=\"isCalendarMode(mode)\"\n\t\t\t\tv-model=\"model.days\"\n\t\t\t\tv-model:times=\"model.times\"\n\t\t\t\t:mode\n\t\t\t\t:multipleTimes\n\t\t\t/>\n\n\t\t\t<TopSelect\n\t\t\t\tv-if=\"mode === 'afterYandexUpdated' && model.times[0]\"\n\t\t\t\tclass=\"top-schedule_afterYandexUpdatedDelay\"\n\t\t\t\tv-model=\"model.times[0].hour\"\n\t\t\t\t:options=\"afterYandexUpdatedOptions\"\n\t\t\t\tsize=\"s\"\n\t\t\t/>\n\n\t\t\t<hr v-if=\"(isCalendarMode(mode) || mode === 'afterYandexUpdated') && $slots.default\">\n\n\t\t\t<slot :mode></slot>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';\nimport TopInput from '@/components/forms/input/input.vue';\nimport TopButton from '@/components/forms/button/button.vue';\nimport Core from '@/core/core/core';\nimport { isEmail } from '@/core/utils/check';\nimport { useI18n } from '@/core/plugins/i18n';\nimport type { Props, Emits } from '@/components/schedule/schedule/components/emails/selector/types';\n\nconst props = withDefaults(defineProps<Props>(), {\n\temails: () => [],\n\tgetEmailSuggestions: () => [],\n});\n\nconst model = defineModel<Props['modelValue']>({ required: true });\n\nconst emit = defineEmits<Emits>();\n\nconst i18n = useI18n();\nconst $ = Core.$;\n\nconst elRootRef = ref<HTMLElement>();\nconst elInputRef = ref<InstanceType<typeof TopInput>>();\nlet elInput: HTMLInputElement | null = null;\nconst autocompleteCache: Record<string, string[]> = {};\n\n// При достижении лимита отключаем поле ввода и скрываем кнопку добавления.\nconst isLimitReached = computed(() => !!props.maxEmailsCount && props.emails.length >= props.maxEmailsCount);\n\nconst filterEmails = (emails: string[]) => emails.filter(email => !props.emails.includes(email));\n\nconst submit = (value: unknown = model.value) => {\n\tconst email = String(value).trim();\n\tif (!email) return;\n\n\tif (!isEmail(email)) {\n\t\tvoid Core.notice(i18n.Common.Enter_valid_email_notice, 'error');\n\n\t\treturn;\n\t}\n\n\temit('submit', email);\n};\n\nconst initAutocomplete = async () => {\n\tawait nextTick();\n\n\telInput = elInputRef.value?.$el.querySelector('input') ?? null;\n\tif (!elInput) return;\n\n\tif (!$?.ui?.autocomplete) {\n\t\tconsole.info('Для работы autocomplete требуется глобальная загрузка jQuery UI Autocomplete');\n\n\t\treturn;\n\t}\n\n\t$(elInput).autocomplete({\n\t\tappendTo: elRootRef.value,\n\t\tminLength: 0,\n\t\tsource: async (request: { term: string }, response: (items: Array<{ label: string, value: string }>) => void) => {\n\t\t\tconst term = request.term;\n\n\t\t\tif (!(term in autocompleteCache)) {\n\t\t\t\tautocompleteCache[term] = await props.getEmailSuggestions(term);\n\t\t\t}\n\n\t\t\tresponse(filterEmails(autocompleteCache[term]).map(email => ({\n\t\t\t\tlabel: email,\n\t\t\t\tvalue: email,\n\t\t\t})));\n\t\t},\n\t\tselect: (event: Event, ui: { item?: { value: string } }) => {\n\t\t\tif (!ui.item || !elInput) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tsubmit(ui.item.value);\n\t\t\tmodel.value = '';\n\n\t\t\t$(elInput).trigger('focus');\n\t\t},\n\t});\n\n\t$(elInput).attr('autocomplete', 'disabled');\n\t$(elInput).on('focus.scheduleEmailSelector', () => {\n\t\tif (!elInput) return;\n\n\t\t$(elInput).trigger('input');\n\t});\n};\n\nonMounted(() => {\n\tvoid initAutocomplete();\n});\n\nonBeforeUnmount(() => {\n\tif (!$?.ui?.autocomplete || !elInput) return;\n\n\t$(elInput).off('focus.scheduleEmailSelector');\n\t$(elInput).autocomplete('destroy');\n});\n</script>\n\n<template>\n\t<div\n\t\tclass=\"top-scheduleEmailSelector\"\n\t\tref=\"elRootRef\"\n\t>\n\t\t<!-- UX: Компонент не должен скраываться, это приведет к CLS -->\n\t\t<TopInput\n\t\t\tref=\"elInputRef\"\n\t\t\tv-model=\"model\"\n\t\t\t@keydown.enter.prevent=\"submit()\"\n\t\t\t:title=\"$i18n.Common.Enter_email\"\n\t\t\ttype=\"email\"\n\t\t\tsize=\"m\"\n\t\t\t:disabled=\"isLimitReached\"\n\t\t>\n\t\t\t<TopButton\n\t\t\t\tv-if=\"!isLimitReached\"\n\t\t\t\tclass=\"top-scheduleEmailSelector_submit\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\ticon=\"\"\n\t\t\t\t@click.prevent=\"submit()\"\n\t\t\t/>\n\t\t</TopInput>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';\nimport TopInput from '@/components/forms/input/input.vue';\nimport TopButton from '@/components/forms/button/button.vue';\nimport Core from '@/core/core/core';\nimport { isEmail } from '@/core/utils/check';\nimport { useI18n } from '@/core/plugins/i18n';\nimport type { Props, Emits } from '@/components/schedule/schedule/components/emails/selector/types';\n\nconst props = withDefaults(defineProps<Props>(), {\n\temails: () => [],\n\tgetEmailSuggestions: () => [],\n});\n\nconst model = defineModel<Props['modelValue']>({ required: true });\n\nconst emit = defineEmits<Emits>();\n\nconst i18n = useI18n();\nconst $ = Core.$;\n\nconst elRootRef = ref<HTMLElement>();\nconst elInputRef = ref<InstanceType<typeof TopInput>>();\nlet elInput: HTMLInputElement | null = null;\nconst autocompleteCache: Record<string, string[]> = {};\n\n// При достижении лимита отключаем поле ввода и скрываем кнопку добавления.\nconst isLimitReached = computed(() => !!props.maxEmailsCount && props.emails.length >= props.maxEmailsCount);\n\nconst filterEmails = (emails: string[]) => emails.filter(email => !props.emails.includes(email));\n\nconst submit = (value: unknown = model.value) => {\n\tconst email = String(value).trim();\n\tif (!email) return;\n\n\tif (!isEmail(email)) {\n\t\tvoid Core.notice(i18n.Common.Enter_valid_email_notice, 'error');\n\n\t\treturn;\n\t}\n\n\temit('submit', email);\n};\n\nconst initAutocomplete = async () => {\n\tawait nextTick();\n\n\telInput = elInputRef.value?.$el.querySelector('input') ?? null;\n\tif (!elInput) return;\n\n\tif (!$?.ui?.autocomplete) {\n\t\tconsole.info('Для работы autocomplete требуется глобальная загрузка jQuery UI Autocomplete');\n\n\t\treturn;\n\t}\n\n\t$(elInput).autocomplete({\n\t\tappendTo: elRootRef.value,\n\t\tminLength: 0,\n\t\tsource: async (request: { term: string }, response: (items: Array<{ label: string, value: string }>) => void) => {\n\t\t\tconst term = request.term;\n\n\t\t\tif (!(term in autocompleteCache)) {\n\t\t\t\tautocompleteCache[term] = await props.getEmailSuggestions(term);\n\t\t\t}\n\n\t\t\tresponse(filterEmails(autocompleteCache[term]).map(email => ({\n\t\t\t\tlabel: email,\n\t\t\t\tvalue: email,\n\t\t\t})));\n\t\t},\n\t\tselect: (event: Event, ui: { item?: { value: string } }) => {\n\t\t\tif (!ui.item || !elInput) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tsubmit(ui.item.value);\n\t\t\tmodel.value = '';\n\n\t\t\t$(elInput).trigger('focus');\n\t\t},\n\t});\n\n\t$(elInput).attr('autocomplete', 'disabled');\n\t$(elInput).on('focus.scheduleEmailSelector', () => {\n\t\tif (!elInput) return;\n\n\t\t$(elInput).trigger('input');\n\t});\n};\n\nonMounted(() => {\n\tvoid initAutocomplete();\n});\n\nonBeforeUnmount(() => {\n\tif (!$?.ui?.autocomplete || !elInput) return;\n\n\t$(elInput).off('focus.scheduleEmailSelector');\n\t$(elInput).autocomplete('destroy');\n});\n</script>\n\n<template>\n\t<div\n\t\tclass=\"top-scheduleEmailSelector\"\n\t\tref=\"elRootRef\"\n\t>\n\t\t<!-- UX: Компонент не должен скраываться, это приведет к CLS -->\n\t\t<TopInput\n\t\t\tref=\"elInputRef\"\n\t\t\tv-model=\"model\"\n\t\t\t@keydown.enter.prevent=\"submit()\"\n\t\t\t:title=\"$i18n.Common.Enter_email\"\n\t\t\ttype=\"email\"\n\t\t\tsize=\"m\"\n\t\t\t:disabled=\"isLimitReached\"\n\t\t>\n\t\t\t<TopButton\n\t\t\t\tv-if=\"!isLimitReached\"\n\t\t\t\tclass=\"top-scheduleEmailSelector_submit\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\ticon=\"\"\n\t\t\t\t@click.prevent=\"submit()\"\n\t\t\t/>\n\t\t</TopInput>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { Emits, Props } from '@/components/schedule/schedule/components/emails/types';\nimport ScheduleEmailSelector from '@/components/schedule/schedule/components/emails/selector/selector.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\temails: () => [],\n\tgetEmailSuggestions: () => [],\n});\n\nconst emit = defineEmits<Emits>();\n\nconst value = ref('');\n\nconst addEmail = (email: string) => {\n\tconst preparedEmail = email.trim();\n\n\tif (!preparedEmail || props.emails.includes(preparedEmail)) {\n\t\tvalue.value = '';\n\n\t\treturn;\n\t}\n\n\temit('add:email', preparedEmail);\n\n\tvalue.value = '';\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleEmail\">\n\t\t<div class=\"top-scheduleEmail_title\">\n\t\t\t{{ $i18n.Projects.Reports_send_to_address }} E-mail:\n\t\t</div>\n\n\t\t<ScheduleEmailSelector\n\t\t\tv-model=\"value\"\n\t\t\t:emails\n\t\t\t:maxEmailsCount\n\t\t\t:getEmailSuggestions\n\t\t\t@submit=\"addEmail\"\n\t\t/>\n\n\t\t<div\n\t\t\tv-if=\"emails.length\"\n\t\t\tclass=\"top-scheduleEmail_emails\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"top-scheduleEmail_emailsItem\"\n\t\t\t\tv-for=\"email in emails\"\n\t\t\t\t:key=\"email\"\n\t\t\t>\n\t\t\t\t<span class=\"top-ellipsis1\">{{ email }}</span>\n\n\t\t\t\t<TopButton\n\t\t\t\t\t@click=\"emit('remove:email', email)\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { Emits, Props } from '@/components/schedule/schedule/components/emails/types';\nimport ScheduleEmailSelector from '@/components/schedule/schedule/components/emails/selector/selector.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\temails: () => [],\n\tgetEmailSuggestions: () => [],\n});\n\nconst emit = defineEmits<Emits>();\n\nconst value = ref('');\n\nconst addEmail = (email: string) => {\n\tconst preparedEmail = email.trim();\n\n\tif (!preparedEmail || props.emails.includes(preparedEmail)) {\n\t\tvalue.value = '';\n\n\t\treturn;\n\t}\n\n\temit('add:email', preparedEmail);\n\n\tvalue.value = '';\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleEmail\">\n\t\t<div class=\"top-scheduleEmail_title\">\n\t\t\t{{ $i18n.Projects.Reports_send_to_address }} E-mail:\n\t\t</div>\n\n\t\t<ScheduleEmailSelector\n\t\t\tv-model=\"value\"\n\t\t\t:emails\n\t\t\t:maxEmailsCount\n\t\t\t:getEmailSuggestions\n\t\t\t@submit=\"addEmail\"\n\t\t/>\n\n\t\t<div\n\t\t\tv-if=\"emails.length\"\n\t\t\tclass=\"top-scheduleEmail_emails\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"top-scheduleEmail_emailsItem\"\n\t\t\t\tv-for=\"email in emails\"\n\t\t\t\t:key=\"email\"\n\t\t\t>\n\t\t\t\t<span class=\"top-ellipsis1\">{{ email }}</span>\n\n\t\t\t\t<TopButton\n\t\t\t\t\t@click=\"emit('remove:email', email)\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Emits, Props } from '@/components/schedule/schedule/components/socials/types';\n\nconst props = defineProps<Props>();\ndefineEmits<Emits>();\n\ntype ReportChannelSource = Props['channels'][number]['source'];\n\nconst hasChannel = (source: ReportChannelSource) => props.channels.some(channel => channel.source === source);\n\nconst sourceIconBySource: Record<ReportChannelSource, string> = {\n\tinformer: '',\n\ttelegram: '',\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleSocials\">\n\t\t<div class=\"top-scheduleSocials_title\">\n\t\t\t{{ $i18n.Projects.Reports_send_to_address }}\n\t\t</div>\n\n\t\t<div class=\"top-scheduleSocials_channels\">\n\t\t\t<div\n\t\t\t\tclass=\"top-scheduleSocials_channel\"\n\t\t\t\tv-for=\"channel in channels\"\n\t\t\t\t:key=\"`${channel.source}-${channel.id}`\"\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tclass=\"top-scheduleSocials_channelIcon\"\n\t\t\t\t\t:data-top-icon=\"sourceIconBySource[channel.source]\"\n\t\t\t\t></span>\n\n\t\t\t\t<span class=\"top-scheduleSocials_channelLabel top-ellipsis1\">\n\t\t\t\t\t{{ channel.label }}\n\t\t\t\t</span>\n\n\t\t\t\t<TopButton\n\t\t\t\t\tv-if=\"channel.settingLink\"\n\t\t\t\t\tclass=\"top-scheduleSocials_channelSettings\"\n\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t:href=\"channel.settingLink\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t></TopButton>\n\n\t\t\t\t<TopSwitcher\n\t\t\t\t\tclass=\"top-scheduleSocials_channelSwitcher\"\n\t\t\t\t\t:modelValue=\"channel.selected\"\n\t\t\t\t\t@update:modelValue=\"$emit('update:channelSelected', {\n\t\t\t\t\t\tid: channel.id,\n\t\t\t\t\t\tsource: channel.source,\n\t\t\t\t\t\tselected: $event as boolean,\n\t\t\t\t\t})\"\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<template\n\t\t\t\tv-for=\"connector in connectors\"\n\t\t\t\t:key=\"connector.source\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tv-if=\"!hasChannel(connector.source)\"\n\t\t\t\tclass=\"top-scheduleSocials_channel\"\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"top-scheduleSocials_channelIcon\"\n\t\t\t\t\t\t:data-top-icon=\"sourceIconBySource[connector.source]\"\n\t\t\t\t\t></span>\n\n\t\t\t\t\t<a\n\t\t\t\t\t\tclass=\"top-scheduleSocials_channelLabel top-ellipsis1\"\n\t\t\t\t\t\t:href=\"connector.connectLink\"\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ connector.connectLabel }}\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n","<script setup lang=\"ts\">\nimport type { Emits, Props } from '@/components/schedule/schedule/components/socials/types';\n\nconst props = defineProps<Props>();\ndefineEmits<Emits>();\n\ntype ReportChannelSource = Props['channels'][number]['source'];\n\nconst hasChannel = (source: ReportChannelSource) => props.channels.some(channel => channel.source === source);\n\nconst sourceIconBySource: Record<ReportChannelSource, string> = {\n\tinformer: '',\n\ttelegram: '',\n};\n</script>\n\n<template>\n\t<div class=\"top-scheduleSocials\">\n\t\t<div class=\"top-scheduleSocials_title\">\n\t\t\t{{ $i18n.Projects.Reports_send_to_address }}\n\t\t</div>\n\n\t\t<div class=\"top-scheduleSocials_channels\">\n\t\t\t<div\n\t\t\t\tclass=\"top-scheduleSocials_channel\"\n\t\t\t\tv-for=\"channel in channels\"\n\t\t\t\t:key=\"`${channel.source}-${channel.id}`\"\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tclass=\"top-scheduleSocials_channelIcon\"\n\t\t\t\t\t:data-top-icon=\"sourceIconBySource[channel.source]\"\n\t\t\t\t></span>\n\n\t\t\t\t<span class=\"top-scheduleSocials_channelLabel top-ellipsis1\">\n\t\t\t\t\t{{ channel.label }}\n\t\t\t\t</span>\n\n\t\t\t\t<TopButton\n\t\t\t\t\tv-if=\"channel.settingLink\"\n\t\t\t\t\tclass=\"top-scheduleSocials_channelSettings\"\n\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t:href=\"channel.settingLink\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t></TopButton>\n\n\t\t\t\t<TopSwitcher\n\t\t\t\t\tclass=\"top-scheduleSocials_channelSwitcher\"\n\t\t\t\t\t:modelValue=\"channel.selected\"\n\t\t\t\t\t@update:modelValue=\"$emit('update:channelSelected', {\n\t\t\t\t\t\tid: channel.id,\n\t\t\t\t\t\tsource: channel.source,\n\t\t\t\t\t\tselected: $event as boolean,\n\t\t\t\t\t})\"\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<template\n\t\t\t\tv-for=\"connector in connectors\"\n\t\t\t\t:key=\"connector.source\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tv-if=\"!hasChannel(connector.source)\"\n\t\t\t\tclass=\"top-scheduleSocials_channel\"\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclass=\"top-scheduleSocials_channelIcon\"\n\t\t\t\t\t\t:data-top-icon=\"sourceIconBySource[connector.source]\"\n\t\t\t\t\t></span>\n\n\t\t\t\t\t<a\n\t\t\t\t\t\tclass=\"top-scheduleSocials_channelLabel top-ellipsis1\"\n\t\t\t\t\t\t:href=\"connector.connectLink\"\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ connector.connectLabel }}\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n@import \"./style.css\";\n</style>\n"],"mappings":"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"}
@@ -85,7 +85,6 @@ export declare const genApiAddGroups: (client: Api.Client<Api.TV.Paths, true>, s
85
85
  names?: unknown[] | null;
86
86
  name?: unknown[] | null;
87
87
  on?: boolean;
88
- status?: boolean;
89
88
  project_id: number;
90
89
  }>, never>;
91
90
  /**
@@ -127,8 +127,11 @@ export declare const genApiGetProjects: (client: Api.Client<Api.TV.Paths, true>)
127
127
  audit_auto_collect_pages_limit?: number | null;
128
128
  indexing_searchers_keys?: unknown[] | null;
129
129
  watcher_types?: unknown[] | null;
130
+ brand_name?: any;
131
+ brand_aliases?: unknown[] | null;
132
+ brand_description?: any;
130
133
  ai_tracker_brand_name?: any;
131
- ai_tracker_brand_description?: unknown[] | null;
134
+ ai_tracker_brand_description?: any;
132
135
  ai_tracker_models_keys?: unknown[] | null;
133
136
  ai_tracker_context_lang?: any;
134
137
  ai_tracker_context_location?: any;
@@ -241,8 +244,11 @@ export declare const genApiGetProjects: (client: Api.Client<Api.TV.Paths, true>)
241
244
  audit_auto_collect_pages_limit?: number | null;
242
245
  indexing_searchers_keys?: unknown[] | null;
243
246
  watcher_types?: unknown[] | null;
247
+ brand_name?: any;
248
+ brand_aliases?: unknown[] | null;
249
+ brand_description?: any;
244
250
  ai_tracker_brand_name?: any;
245
- ai_tracker_brand_description?: unknown[] | null;
251
+ ai_tracker_brand_description?: any;
246
252
  ai_tracker_models_keys?: unknown[] | null;
247
253
  ai_tracker_context_lang?: any;
248
254
  ai_tracker_context_location?: any;
@@ -3,10 +3,12 @@ export interface Props {
3
3
  searchers: Searcher[];
4
4
  /**
5
5
  * Список выбранных значений
6
- * *
6
+ *
7
7
  * - при `onlySearcher = false`:
8
+ * - при `forMode === 'volume'`: массив `regionKey`
9
+ * - при `forMode === 'cost_forecast'`: массив `regionKey`
10
+ * - при `forMode === 'project_relevant_url'`: массив `regionIndex`
8
11
  * - при `forMode === ''`: массив `regionIndex`
9
- * - при `forMode !== ''`: массив `regionKey`
10
12
  * - при `onlySearcher = true` массив `searcherKey`
11
13
  *
12
14
  * Обратите внимание, всегда является массивом, даже если не предпогается получить несколько значений
@@ -23,21 +25,26 @@ export interface Props {
23
25
  */
24
26
  modelValueSingle?: number;
25
27
  /**
26
- * Добавить режим сравнения
27
- *
28
- * В режиме сравнения выбранные значения длиной массива > 1 сохраняются с привязкой к projectId
28
+ * Добавить режим сравнения.
29
29
  *
30
- * Чтобы изменить сохраненное значение в режиме сравнения необходимо указать modelValue с длиной массива > 1
30
+ * - В режиме сравнения выбранные значения длиной массива > 1 сохраняются с привязкой к `projectId`
31
+ * - Чтобы изменить сохраненное значение в режиме сравнения необходимо указать `modelValue` с длиной массива > 1
31
32
  *
32
- * Выбор регионов для сравнения требуется настраивать отдельно, см. emit `compareRegions`
33
+ * Режим сравнения работает только с `regionIndex`, поэтому не поддерживает `forMode` со значениями `volume` или `cost_forecast`.
33
34
  */
34
35
  addCompare?: boolean;
35
36
  /**
36
37
  * Режим выбора регионов
37
38
  *
38
- * - `volume` для Частоты
39
- * - `cost_forecast` для ставок
40
- * - `project_relevant_url` для Релевантной (подбор)
39
+ * - Не указано, значение по умолчанию
40
+ * - Выводит все включенные настроенные ПС и регионы
41
+ * - `volume` / `cost_forecast`: Частоты / Стоимость клика
42
+ * - Всегда выводит такие ПС и только такие ПС, где есть сбор частоты
43
+ * - Выводит и включенные и выключенные регионы этих ПС
44
+ * - Добавляет регион `Глобальный`, если включена настройка: `Core.state.showGlobalRegionForKeywordsStats`
45
+ * - `project_relevant_url`: Проверка релевантной
46
+ * - Не выводит ПС, в которых нет понятия релевантной, например `YouTube`
47
+ * - Выводит и включенные и выключенные регионы этих ПС
41
48
  */
42
49
  forMode?: ForMode;
43
50
  /**
@@ -1,20 +1,6 @@
1
1
  import { ForMode, Region, Searcher, SearcherByKey } from '../types';
2
2
  import { AsyncTopDialogHandle } from '../../../dialog/dialog/composables/asyncDialogHandle';
3
3
  import { DefineComponent } from 'vue';
4
- /**
5
- * Генерация Map ПС с Map регионов из массива searchers
6
- * - ключ для ПС - searcherKey
7
- * - ключ для региона - regionIndex
8
- *
9
- * Если поисковиков в списке нет, в список будет добавлен searcherUndefined
10
- *
11
- * Если регионов в списке нет, в список будет добавлен regionUndefined
12
- *
13
- * @param forMode - Режим выбора регионов
14
- * @param autoRegion - добавить элемент с ключем -2, который в API заменяется на нужный ключ в зависимости от контекста
15
- * @param searchers - поисковики с регионами проекта, см.: get/projects_2/projects, show_searchers_and_regions = 1
16
- */
17
- export declare const genSearcherByKey: (forMode?: ForMode, autoRegion?: boolean, searchers?: Searcher[]) => SearcherByKey;
18
4
  /**
19
5
  * Поиск региона по заданному критерию из списка поисковиков проекта
20
6
  *
@@ -29,3 +15,17 @@ export declare const findRegion: (forMode: ForMode, searchRegion: Partial<Region
29
15
  * @see import('../dialog_regionSelectorRegions/types').Props
30
16
  */
31
17
  export declare const dialogRegionSelector: AsyncTopDialogHandle<DefineComponent<Record<string, never>, Record<string, never>, any>>;
18
+ /**
19
+ * Генерация Map ПС с Map регионов из массива searchers
20
+ * - ключ для ПС - searcherKey
21
+ * - ключ для региона - regionIndex
22
+ *
23
+ * Если поисковиков в списке нет, в список будет добавлен `searcherUndefined`
24
+ *
25
+ * Если регионов в списке нет, в список будет добавлен `regionUndefined`
26
+ *
27
+ * @param forMode - Режим выбора регионов
28
+ * @param autoRegion - добавить элемент с ключем -2, который в API заменяется на нужный ключ в зависимости от контекста
29
+ * @param searchers - поисковики с регионами проекта, см.: get/projects_2/projects, show_searchers_and_regions = 1
30
+ */
31
+ export declare const genSearcherByKey: (forMode?: ForMode, autoRegion?: boolean, searchers?: Searcher[]) => SearcherByKey;
@@ -1,7 +1,6 @@
1
1
  import { Mode } from '../../types';
2
2
  import { Props as TimeSelectorProps } from '../timeSelector/types';
3
3
  import { components as DayComponents } from 'topvisor-openapi/src/ts/Schedule_2/Types/Day';
4
- type ScheduleDay = DayComponents['schemas']['Schedule_2.Types.Day'];
5
4
  export type Day = {
6
5
  value: Props['modelValue'][number];
7
6
  title: string;
@@ -13,7 +12,7 @@ export interface Props {
13
12
  *
14
13
  * Если выбраны все дни в режиме будет содержать `ALL`
15
14
  */
16
- modelValue: ScheduleDay[];
15
+ modelValue: DayComponents['schemas']['Schedule_2.Types.Day'][];
17
16
  /**
18
17
  * Режим отображения календаря.
19
18
  *
@@ -33,4 +32,3 @@ export interface Props {
33
32
  */
34
33
  multipleTimes?: boolean;
35
34
  }
36
- export {};
@@ -1,9 +1,13 @@
1
1
  import { Props as EmailsProps } from '../types';
2
2
  export interface Props {
3
3
  modelValue: string;
4
- emails?: string[];
5
4
  /**
6
- * Получение поисковых подсказок при вводе Email
5
+ * Уже добавленные email.
6
+ */
7
+ emails: string[];
8
+ maxEmailsCount?: number;
9
+ /**
10
+ * Получение поисковых подсказок при вводе Email.
7
11
  */
8
12
  getEmailSuggestions?: EmailsProps['getEmailSuggestions'];
9
13
  }
@@ -0,0 +1,7 @@
1
+ import { Ref, ComputedRef } from 'vue';
2
+ import { Option as TopSelectOption } from '../../../forms/select/types';
3
+ import { Mode, Props } from '../types';
4
+ /**
5
+ * Формирует реактивный список режимов расписания с учетом дополнительных режимов.
6
+ */
7
+ export declare const useModeOptions: (props: Props, mode: Ref<Mode>) => ComputedRef<TopSelectOption[]>;
@@ -0,0 +1,9 @@
1
+ import { Ref } from 'vue';
2
+ import { Mode, Props } from '../types';
3
+ /**
4
+ * Сохраняет дни и временные слоты модели по режимам расписания.
5
+ */
6
+ export declare const useModelByModeCache: (model: Ref<Props["modelValue"]>, mode: Ref<Mode>) => {
7
+ daysByMode: Partial<Record<Mode, Props["modelValue"]["days"]>>;
8
+ timesByMode: Partial<Record<Mode | "calendar", Props["modelValue"]["times"]>>;
9
+ };
@@ -0,0 +1,5 @@
1
+ import { Story } from '../../schedule.stories';
2
+ /**
3
+ * Проверяет выбор расписания и восстановление настроек после ручного режима.
4
+ */
5
+ export declare const playSchedule: NonNullable<Story['play']>;
@@ -1,10 +1,14 @@
1
- import { Props as CalendarProps } from './compoents/calendar/types';
2
- import { Props as TimeSelectorProps } from './compoents/timeSelector/types';
1
+ import { Props as CalendarProps } from './components/calendar/types';
2
+ import { Props as TimeSelectorProps } from './components/timeSelector/types';
3
3
  import { components as TypeMethodComponents } from 'topvisor-openapi/src/ts/Schedule_2/Types/TypeMethod';
4
4
  /**
5
5
  * Режим вывода календаря
6
6
  */
7
7
  export type Mode = 'onDemand' | 'dayOfWeek' | 'dayOfMonth' | 'afterYandexUpdated' | 'afterCheck';
8
+ /**
9
+ * Режимы, которые можно добавить к базовому набору расписания.
10
+ */
11
+ export type ExtraMode = Extract<Mode, 'afterYandexUpdated'>;
8
12
  export interface Props {
9
13
  /**
10
14
  * Настройки расписания: дни и временные слоты.
@@ -23,13 +27,9 @@ export interface Props {
23
27
  */
24
28
  type?: TypeMethodComponents['schemas']['Schedule_2.Types.TypeMethod'];
25
29
  /**
26
- * Доступные режимы календаря в порядке отображения.
27
- *
28
- * Если не указано будут выведены все доступные режимы
29
- *
30
- * Режим `afterCheck` по здравому смыслу никогда не дожен выводиться в `go`
30
+ * Дополнительные режимы календаря.
31
31
  */
32
- availableMods?: Mode[];
32
+ extraMods?: ExtraMode[];
33
33
  /**
34
34
  * Возможность выбирать один или несколько временных слотов.
35
35
  */
@@ -47,7 +47,7 @@ export interface Slots {
47
47
  *
48
48
  * Для разделения секция используйте `<hr>`
49
49
  */
50
- settings?(props: {
50
+ default?(props: {
51
51
  mode: Mode;
52
52
  }): any;
53
53
  }
@@ -1,7 +1,6 @@
1
- import { Props as CalendarProps } from './compoents/calendar/types';
1
+ import { Props as CalendarProps } from './components/calendar/types';
2
2
  import { Mode, Props } from './types';
3
3
  import { Option as TopSelectOption } from '../../forms/select/types';
4
- export declare const defaultMods: Mode[];
5
4
  /**
6
5
  * Генерирует варианты задержки запуска после апдейта Яндекса.
7
6
  *
@@ -18,7 +17,3 @@ export declare const isCalendarMode: (value: Mode) => value is CalendarProps["mo
18
17
  * Определяет режим расписания по выбранным дням.
19
18
  */
20
19
  export declare const getModeByDays: (days: Props["modelValue"]["days"], currentMode?: Mode) => Mode;
21
- /**
22
- * Подписи режимов принадлежат компоненту, а не каждому его потребителю.
23
- */
24
- export declare const genModeOptions: (modes: Mode[]) => TopSelectOption[];
@@ -1,3 +1,3 @@
1
1
  export { default as TopSchedule } from './schedule/schedule.vue';
2
- export { default as TopScheduleEmails } from './schedule/compoents/emails/emails.vue';
3
- export { default as TopScheduleSocials } from './schedule/compoents/socials/socials.vue';
2
+ export { default as TopScheduleEmails } from './schedule/components/emails/emails.vue';
3
+ export { default as TopScheduleSocials } from './schedule/components/socials/socials.vue';