Merge pull request #12340 from john-westcott-iv/shedule_timezone_12255

Add documentation around schedule timezone change
This commit is contained in:
Jessica Steurer
2022-06-15 15:34:49 -03:00
committed by GitHub
5 changed files with 51 additions and 16 deletions

View File

@@ -4684,8 +4684,14 @@ class SchedulePreviewSerializer(BaseSerializer):
class ScheduleSerializer(LaunchConfigurationBaseSerializer, SchedulePreviewSerializer): class ScheduleSerializer(LaunchConfigurationBaseSerializer, SchedulePreviewSerializer):
show_capabilities = ['edit', 'delete'] show_capabilities = ['edit', 'delete']
timezone = serializers.SerializerMethodField() timezone = serializers.SerializerMethodField(
until = serializers.SerializerMethodField() help_text=_(
'The timezone this schedule runs in. This field is extracted from the RRULE. If the timezone in the RRULE is a link to another timezone, the link will be reflected in this field.'
),
)
until = serializers.SerializerMethodField(
help_text=_('The date this schedule will end. This field is computed from the RRULE. If the schedule does not end an emptry string will be returned'),
)
class Meta: class Meta:
model = Schedule model = Schedule

View File

@@ -578,8 +578,7 @@ class ScheduleZoneInfo(APIView):
swagger_topic = 'System Configuration' swagger_topic = 'System Configuration'
def get(self, request): def get(self, request):
zones = [{'name': zone} for zone in models.Schedule.get_zoneinfo()] return Response({'zones': models.Schedule.get_zoneinfo(), 'links': models.Schedule.get_zoneinfo_links()})
return Response(zones)
class LaunchConfigCredentialsBase(SubListAttachDetachAPIView): class LaunchConfigCredentialsBase(SubListAttachDetachAPIView):

View File

@@ -85,9 +85,18 @@ class Schedule(PrimordialModel, LaunchTimeConfig):
next_run = models.DateTimeField(null=True, default=None, editable=False, help_text=_("The next time that the scheduled action will run.")) next_run = models.DateTimeField(null=True, default=None, editable=False, help_text=_("The next time that the scheduled action will run."))
@classmethod @classmethod
def get_zoneinfo(self): def get_zoneinfo(cls):
return sorted(get_zonefile_instance().zones) return sorted(get_zonefile_instance().zones)
@classmethod
def get_zoneinfo_links(cls):
return_val = {}
zone_instance = get_zonefile_instance()
for zone_name in zone_instance.zones:
if str(zone_name) != str(zone_instance.zones[zone_name]._filename):
return_val[zone_name] = zone_instance.zones[zone_name]._filename
return return_val
@property @property
def timezone(self): def timezone(self):
utc = tzutc() utc = tzutc()

View File

@@ -500,7 +500,7 @@ def test_complex_schedule(post, admin_user, rrule, expected_result):
def test_zoneinfo(get, admin_user): def test_zoneinfo(get, admin_user):
url = reverse('api:schedule_zoneinfo') url = reverse('api:schedule_zoneinfo')
r = get(url, admin_user, expect=200) r = get(url, admin_user, expect=200)
assert {'name': 'America/New_York'} in r.data assert 'America/New_York' in r.data['zones']
@pytest.mark.django_db @pytest.mark.django_db

View File

@@ -89,7 +89,7 @@ const generateRunOnTheDay = (days = []) => {
return null; return null;
}; };
function ScheduleFormFields({ hasDaysToKeepField, zoneOptions }) { function ScheduleFormFields({ hasDaysToKeepField, zoneOptions, zoneLinks }) {
const [timezone, timezoneMeta] = useField({ const [timezone, timezoneMeta] = useField({
name: 'timezone', name: 'timezone',
validate: required(t`Select a value for this field`), validate: required(t`Select a value for this field`),
@@ -100,6 +100,24 @@ function ScheduleFormFields({ hasDaysToKeepField, zoneOptions }) {
}); });
const [{ name: dateFieldName }] = useField('startDate'); const [{ name: dateFieldName }] = useField('startDate');
const [{ name: timeFieldName }] = useField('startTime'); const [{ name: timeFieldName }] = useField('startTime');
const [timezoneMessage, setTimezoneMessage] = useState('');
const warnLinkedTZ = (event, selectedValue) => {
if (zoneLinks[selectedValue]) {
setTimezoneMessage(
`Warning: ${selectedValue} is a link to ${zoneLinks[selectedValue]} and will be saved as that.`
);
} else {
setTimezoneMessage('');
}
timezone.onChange(event, selectedValue);
};
let timezoneValidatedStatus = 'default';
if (timezoneMeta.touched && timezoneMeta.error) {
timezoneValidatedStatus = 'error';
} else if (timezoneMessage) {
timezoneValidatedStatus = 'warning';
}
return ( return (
<> <>
<FormField <FormField
@@ -124,17 +142,17 @@ function ScheduleFormFields({ hasDaysToKeepField, zoneOptions }) {
<FormGroup <FormGroup
name="timezone" name="timezone"
fieldId="schedule-timezone" fieldId="schedule-timezone"
helperTextInvalid={timezoneMeta.error} helperTextInvalid={timezoneMeta.error || timezoneMessage}
isRequired isRequired
validated={ validated={timezoneValidatedStatus}
!timezoneMeta.touched || !timezoneMeta.error ? 'default' : 'error'
}
label={t`Local time zone`} label={t`Local time zone`}
helperText={timezoneMessage}
> >
<AnsibleSelect <AnsibleSelect
id="schedule-timezone" id="schedule-timezone"
data={zoneOptions} data={zoneOptions}
{...timezone} {...timezone}
onChange={warnLinkedTZ}
/> />
</FormGroup> </FormGroup>
<FormGroup <FormGroup
@@ -212,7 +230,7 @@ function ScheduleForm({
request: loadScheduleData, request: loadScheduleData,
error: contentError, error: contentError,
isLoading: contentLoading, isLoading: contentLoading,
result: { zoneOptions, credentials }, result: { zoneOptions, zoneLinks, credentials },
} = useRequest( } = useRequest(
useCallback(async () => { useCallback(async () => {
const { data } = await SchedulesAPI.readZoneInfo(); const { data } = await SchedulesAPI.readZoneInfo();
@@ -225,19 +243,21 @@ function ScheduleForm({
creds = results; creds = results;
} }
const zones = data.map((zone) => ({ const zones = (data.zones || []).map((zone) => ({
value: zone.name, value: zone,
key: zone.name, key: zone,
label: zone.name, label: zone,
})); }));
return { return {
zoneOptions: zones, zoneOptions: zones,
zoneLinks: data.links,
credentials: creds || [], credentials: creds || [],
}; };
}, [schedule]), }, [schedule]),
{ {
zonesOptions: [], zonesOptions: [],
zoneLinks: {},
credentials: [], credentials: [],
isLoading: true, isLoading: true,
} }
@@ -630,6 +650,7 @@ function ScheduleForm({
<ScheduleFormFields <ScheduleFormFields
hasDaysToKeepField={hasDaysToKeepField} hasDaysToKeepField={hasDaysToKeepField}
zoneOptions={zoneOptions} zoneOptions={zoneOptions}
zoneLinks={zoneLinks}
/> />
{isWizardOpen && ( {isWizardOpen && (
<SchedulePromptableFields <SchedulePromptableFields