feat(automations): use Ant TimePicker with minute precision and Jalali dates

Replace hour-only select with HH:mm picker, show last run and send logs in Jalali, and display scheduled times as HH:mm in the table.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-24 22:13:06 +03:30
co-authored by Cursor
parent eb435fe3ab
commit 7a2254bc2d
4 changed files with 84 additions and 42 deletions
@@ -299,16 +299,16 @@
</template>
<div class="auto-editor__channel">
<a-switch :checked="hasSms" @change="(v) => toggleChannel('sms', !!v)" />
<BasicSelect
<a-time-picker
v-if="hasSms && showChannelHours"
class="auto-editor__hour-select"
:value="form.sms_send_hour"
:items="catalog?.hours || []"
key-name="key"
value-name="name"
class="auto-editor__hour-picker"
:value="smsHourValue"
format="HH:mm"
:minute-step="1"
:show-second="false"
placeholder="ساعت"
:has-tooltip="false"
@update:value="(v) => (form.sms_send_hour = v)"
allow-clear
@update:value="setSmsTime"
/>
</div>
</a-form-item>
@@ -318,16 +318,16 @@
</template>
<div class="auto-editor__channel">
<a-switch :checked="hasInApp" @change="(v) => toggleChannel('in_app', !!v)" />
<BasicSelect
<a-time-picker
v-if="hasInApp && showChannelHours"
class="auto-editor__hour-select"
:value="form.in_app_send_hour"
:items="catalog?.hours || []"
key-name="key"
value-name="name"
class="auto-editor__hour-picker"
:value="inAppHourValue"
format="HH:mm"
:minute-step="1"
:show-second="false"
placeholder="ساعت"
:has-tooltip="false"
@update:value="(v) => (form.in_app_send_hour = v)"
allow-clear
@update:value="setInAppTime"
/>
</div>
</a-form-item>
@@ -375,7 +375,11 @@
<script setup lang="ts">
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import type { FormInstance } from 'ant-design-vue'
import dayjs, { type Dayjs } from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
import { cloneDeep, debounce, isEmpty } from 'lodash'
dayjs.extend(customParseFormat)
import { inputRules } from '@/utils/inputRules'
import { getAutomationCatalog, previewAutomationAudience } from '@/api/automations'
import BaseDatePicker from '@core/components/BaseDatePicker'
@@ -499,6 +503,37 @@ const previewText = computed(() => {
const hasSms = computed(() => (props.form.channels || []).includes('sms'))
const hasInApp = computed(() => (props.form.channels || []).includes('in_app'))
function timeToPicker(hour?: number | null, minute?: number | null): Dayjs | undefined {
if (hour == null || Number.isNaN(Number(hour))) return undefined
return dayjs()
.hour(Number(hour))
.minute(Number(minute ?? 0))
.second(0)
.millisecond(0)
}
function pickerToTime(val: Dayjs | string | null | undefined): { hour: number | null; minute: number | null } {
if (val == null || val === '') return { hour: null, minute: null }
const parsed = dayjs.isDayjs(val) ? val : dayjs(String(val), 'HH:mm', true)
if (!parsed.isValid()) return { hour: null, minute: null }
return { hour: parsed.hour(), minute: parsed.minute() }
}
const smsHourValue = computed(() => timeToPicker(props.form.sms_send_hour, props.form.sms_send_minute))
const inAppHourValue = computed(() => timeToPicker(props.form.in_app_send_hour, props.form.in_app_send_minute))
function setSmsTime(val: Dayjs | string | null) {
const time = pickerToTime(val)
props.form.sms_send_hour = time.hour
props.form.sms_send_minute = time.hour == null ? null : time.minute
}
function setInAppTime(val: Dayjs | string | null) {
const time = pickerToTime(val)
props.form.in_app_send_hour = time.hour
props.form.in_app_send_minute = time.hour == null ? null : time.minute
}
function ensureTriggerConfig() {
if (!props.form.trigger_config) {
props.form.trigger_config = {
@@ -702,31 +737,14 @@ defineExpose({
@apply flex items-center gap-3;
}
.auto-editor__hour-select {
.auto-editor__hour-picker {
min-width: 7rem;
flex: 1;
}
.auto-editor__hour-select :deep(.ant-select-selector) {
display: flex !important;
align-items: center !important;
height: 32px !important;
}
.auto-editor__hour-select :deep(.ant-select-selection-search),
.auto-editor__hour-select :deep(.ant-select-selection-item),
.auto-editor__hour-select :deep(.ant-select-selection-placeholder) {
display: flex !important;
align-items: center !important;
line-height: 30px !important;
margin-top: 0 !important;
margin-bottom: 0 !important;
}
.auto-editor__hour-select :deep(.ant-select-selection-item > div) {
line-height: 30px;
white-space: nowrap;
padding: 0;
.auto-editor__hour-picker :deep(.ant-picker) {
width: 100%;
border-radius: 10px;
}
.auto-editor__hint {