autmation final reaftocrs and setitgns dafautls
This commit is contained in:
@@ -36,6 +36,11 @@ import {
|
||||
StageConfig,
|
||||
DAYS_OF_WEEK,
|
||||
FREQUENCY_OPTIONS,
|
||||
HOUR_OPTIONS,
|
||||
AMPM_OPTIONS,
|
||||
toTime24,
|
||||
fromTime24,
|
||||
formatTime,
|
||||
calculateTotalBudget,
|
||||
} from '../../services/unifiedSettings.api';
|
||||
|
||||
@@ -185,11 +190,64 @@ export default function AIAutomationSettings({ siteId }: AIAutomationSettingsPro
|
||||
}
|
||||
};
|
||||
|
||||
// Reset to defaults
|
||||
const handleReset = () => {
|
||||
loadSettings();
|
||||
loadImageSettings();
|
||||
toastRef.current.info('Settings reset to last saved values');
|
||||
// Reset to defaults - fetches from backend DefaultAutomationConfig
|
||||
const handleReset = async () => {
|
||||
if (!settings) return;
|
||||
|
||||
try {
|
||||
// Fetch defaults from backend
|
||||
// fetchAPI automatically extracts .data from the unified response format
|
||||
const defaults = await fetchAPI('/v1/integration/settings/defaults/');
|
||||
|
||||
if (!defaults || !defaults.automation) {
|
||||
throw new Error('Invalid defaults response format');
|
||||
}
|
||||
|
||||
// Reset automation settings
|
||||
const defaultSettings: UnifiedSiteSettings = {
|
||||
...settings,
|
||||
automation: {
|
||||
enabled: defaults.automation.enabled,
|
||||
frequency: defaults.automation.frequency,
|
||||
time: defaults.automation.time,
|
||||
last_run_at: null,
|
||||
next_run_at: null,
|
||||
},
|
||||
stages: settings.stages.map(s => {
|
||||
const stageDefault = defaults.stages?.find((d: { number: number }) => d.number === s.number);
|
||||
return {
|
||||
...s,
|
||||
enabled: stageDefault?.enabled ?? true,
|
||||
batch_size: stageDefault?.batch_size ?? (s.number === 1 ? 50 : s.number === 3 ? 20 : 1),
|
||||
per_run_limit: stageDefault?.per_run_limit ?? 0,
|
||||
use_testing: stageDefault?.use_testing ?? false,
|
||||
budget_pct: s.has_ai ? (stageDefault?.budget_pct ?? 0) : undefined,
|
||||
};
|
||||
}),
|
||||
delays: {
|
||||
within_stage: defaults.delays?.within_stage ?? 3,
|
||||
between_stage: defaults.delays?.between_stage ?? 5,
|
||||
},
|
||||
publishing: {
|
||||
...settings.publishing,
|
||||
auto_approval_enabled: defaults.publishing?.auto_approval_enabled ?? false,
|
||||
auto_publish_enabled: defaults.publishing?.auto_publish_enabled ?? false,
|
||||
publish_days: defaults.publishing?.publish_days ?? ['mon', 'tue', 'wed', 'thu', 'fri'],
|
||||
time_slots: defaults.publishing?.time_slots ?? ['09:00', '14:00', '18:00'],
|
||||
},
|
||||
};
|
||||
|
||||
setSettings(defaultSettings);
|
||||
|
||||
// NOTE: Image settings (style, max_images) are NOT reset here.
|
||||
// They are loaded from /v1/account/settings/ai/ (SystemAISettings/AccountSettings)
|
||||
// which is a separate global setting managed in the backend admin.
|
||||
|
||||
toastRef.current.info('Settings reset to defaults. Click Save to apply. (Image settings unchanged)');
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch defaults:', error);
|
||||
toastRef.current.error('Failed to fetch default settings from server.');
|
||||
}
|
||||
};
|
||||
|
||||
// Update automation settings
|
||||
@@ -330,19 +388,39 @@ export default function AIAutomationSettings({ siteId }: AIAutomationSettingsPro
|
||||
<SelectDropdown
|
||||
options={FREQUENCY_OPTIONS.map(f => ({ value: f.value, label: f.label }))}
|
||||
value={settings.automation.frequency}
|
||||
onChange={(value) => updateAutomation({ frequency: value as 'hourly' | 'daily' | 'weekly' })}
|
||||
onChange={(value) => updateAutomation({ frequency: value as 'daily' | 'weekly' | 'monthly' })}
|
||||
disabled={!settings.automation.enabled}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="mb-2">Run Time</Label>
|
||||
<InputField
|
||||
type="time"
|
||||
value={settings.automation.time}
|
||||
onChange={(e) => updateAutomation({ time: e.target.value })}
|
||||
disabled={!settings.automation.enabled}
|
||||
/>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<SelectDropdown
|
||||
options={HOUR_OPTIONS}
|
||||
value={fromTime24(settings.automation.time).hour}
|
||||
onChange={(value) => {
|
||||
const { ampm } = fromTime24(settings.automation.time);
|
||||
updateAutomation({ time: toTime24(value, ampm) });
|
||||
}}
|
||||
disabled={!settings.automation.enabled}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<SelectDropdown
|
||||
options={AMPM_OPTIONS}
|
||||
value={fromTime24(settings.automation.time).ampm}
|
||||
onChange={(value) => {
|
||||
const { hour } = fromTime24(settings.automation.time);
|
||||
updateAutomation({ time: toTime24(hour, value) });
|
||||
}}
|
||||
disabled={!settings.automation.enabled}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -352,7 +430,7 @@ export default function AIAutomationSettings({ siteId }: AIAutomationSettingsPro
|
||||
{settings.automation.enabled && settings.automation.next_run_at ? (
|
||||
<span>Next run: {new Date(settings.automation.next_run_at).toLocaleString()}</span>
|
||||
) : (
|
||||
<span>Runs {settings.automation.frequency} at {settings.automation.time}</span>
|
||||
<span>Runs {settings.automation.frequency} at {formatTime(settings.automation.time)}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -828,11 +906,11 @@ export default function AIAutomationSettings({ siteId }: AIAutomationSettingsPro
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Check Frequency</span>
|
||||
<p className="text-sm font-semibold text-gray-900 dark:text-white">Every 15 minutes</p>
|
||||
<p className="text-sm font-semibold text-gray-900 dark:text-white">Hourly</p>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Check Times</span>
|
||||
<p className="text-sm font-semibold text-gray-900 dark:text-white">:00, :15, :30, :45</p>
|
||||
<span className="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Check Time</span>
|
||||
<p className="text-sm font-semibold text-gray-900 dark:text-white">5 minutes past each hour</p>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Timezone</span>
|
||||
@@ -840,7 +918,7 @@ export default function AIAutomationSettings({ siteId }: AIAutomationSettingsPro
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-gray-600 dark:text-gray-400">
|
||||
The scheduler checks for due automations every 15 minutes. Your scheduled time will trigger within its 15-minute window (e.g., 14:35 triggers at the 14:30 check). Automations only run once per day — if already run, the next run is tomorrow. All times are UTC.
|
||||
The scheduler runs at 5 minutes past each hour. Select the hour you want your automation to run — for example, selecting 2 PM means it will run at 2:05 PM UTC. Automations only run once per day. If it has already run today, the next run will be tomorrow (or the next scheduled day for weekly/monthly).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,8 +32,8 @@ export interface UnifiedSiteSettings {
|
||||
site_name: string;
|
||||
automation: {
|
||||
enabled: boolean;
|
||||
frequency: 'hourly' | 'daily' | 'weekly';
|
||||
time: string; // HH:MM format
|
||||
frequency: 'daily' | 'weekly' | 'monthly';
|
||||
time: string; // HH:00 format (hour only)
|
||||
last_run_at: string | null;
|
||||
next_run_at: string | null;
|
||||
};
|
||||
@@ -66,8 +66,8 @@ export interface UnifiedSiteSettings {
|
||||
export interface UpdateUnifiedSettingsRequest {
|
||||
automation?: {
|
||||
enabled?: boolean;
|
||||
frequency?: 'hourly' | 'daily' | 'weekly';
|
||||
time?: string;
|
||||
frequency?: 'daily' | 'weekly' | 'monthly';
|
||||
time?: string; // HH:00 format (hour only)
|
||||
};
|
||||
stages?: Array<{
|
||||
number: number;
|
||||
@@ -136,20 +136,65 @@ export const DAYS_OF_WEEK = [
|
||||
* Frequency options for automation
|
||||
*/
|
||||
export const FREQUENCY_OPTIONS = [
|
||||
{ value: 'hourly', label: 'Hourly' },
|
||||
{ value: 'daily', label: 'Daily' },
|
||||
{ value: 'weekly', label: 'Weekly' },
|
||||
{ value: 'monthly', label: 'Monthly' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Hour options (1-12) for time selection
|
||||
*/
|
||||
export const HOUR_OPTIONS = [
|
||||
{ value: '12', label: '12' },
|
||||
{ value: '1', label: '1' },
|
||||
{ value: '2', label: '2' },
|
||||
{ value: '3', label: '3' },
|
||||
{ value: '4', label: '4' },
|
||||
{ value: '5', label: '5' },
|
||||
{ value: '6', label: '6' },
|
||||
{ value: '7', label: '7' },
|
||||
{ value: '8', label: '8' },
|
||||
{ value: '9', label: '9' },
|
||||
{ value: '10', label: '10' },
|
||||
{ value: '11', label: '11' },
|
||||
];
|
||||
|
||||
/**
|
||||
* AM/PM options
|
||||
*/
|
||||
export const AMPM_OPTIONS = [
|
||||
{ value: 'AM', label: 'AM' },
|
||||
{ value: 'PM', label: 'PM' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Convert hour (1-12) and AM/PM to 24-hour time string (HH:00)
|
||||
*/
|
||||
export function toTime24(hour: string, ampm: string): string {
|
||||
let h = parseInt(hour);
|
||||
if (ampm === 'PM' && h !== 12) h += 12;
|
||||
if (ampm === 'AM' && h === 12) h = 0;
|
||||
return `${h.toString().padStart(2, '0')}:00`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert 24-hour time string to hour (1-12) and AM/PM
|
||||
*/
|
||||
export function fromTime24(time: string): { hour: string; ampm: string } {
|
||||
const [hours] = time.split(':');
|
||||
let h = parseInt(hours);
|
||||
const ampm = h >= 12 ? 'PM' : 'AM';
|
||||
if (h > 12) h -= 12;
|
||||
if (h === 0) h = 12;
|
||||
return { hour: h.toString(), ampm };
|
||||
}
|
||||
|
||||
/**
|
||||
* Format time for display
|
||||
*/
|
||||
export function formatTime(time: string): string {
|
||||
const [hours, minutes] = time.split(':');
|
||||
const h = parseInt(hours);
|
||||
const ampm = h >= 12 ? 'PM' : 'AM';
|
||||
const displayHour = h > 12 ? h - 12 : h === 0 ? 12 : h;
|
||||
return `${displayHour}:${minutes} ${ampm}`;
|
||||
const { hour, ampm } = fromTime24(time);
|
||||
return `${hour}:00 ${ampm}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user