Skip to content

Commit

Permalink
Plugins update manager: Schedule form validation (#87897)
Browse files Browse the repository at this point in the history
* Add name field validation

* Update hour and period control; keep changes between frequency

* Update types, SelectControl takes string as a value

* Fix typing error

* Update day option values

* Rename file from helper to const

* Create prepareTimestamp helper function

* Create name and timestamp validation functions

* Create name and timestamp validation effects

* Show timestamp validation error

* Add selected plugins validation

* Extend plugins validation

* Optimize module styles import

* Change default period

* Add unit tests for plugin and timeslot validation functions

* Update client/blocks/plugins-update-manager/schedule-form.helper.ts

Co-authored-by: Konstantin Obenland <obenland@gmx.de>

---------

Co-authored-by: Konstantin Obenland <obenland@gmx.de>
  • Loading branch information
2 people authored and pull[bot] committed Apr 17, 2024
1 parent dccadf2 commit 6511093
Show file tree
Hide file tree
Showing 7 changed files with 386 additions and 143 deletions.
2 changes: 2 additions & 0 deletions client/blocks/plugins-update-manager/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import NavigationHeader from 'calypso/components/navigation-header';
import { ScheduleCreate } from './schedule-create';
import { ScheduleList } from './schedule-list';

import './styles.scss';

interface Props {
siteSlug: string;
context: 'list' | 'create';
Expand Down
6 changes: 3 additions & 3 deletions client/blocks/plugins-update-manager/schedule-create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import { arrowLeft } from '@wordpress/icons';
import { SiteSlug } from 'calypso/types';
import { ScheduleForm } from './schedule-form';

import './styles.scss';

interface Props {
siteSlug: SiteSlug;
onNavBack?: () => void;
Expand All @@ -36,7 +34,9 @@ export const ScheduleCreate = ( props: Props ) => {
<ScheduleForm siteSlug={ siteSlug } />
</CardBody>
<CardFooter>
<Button variant="primary">Create</Button>
<Button form="schedule" type="submit" variant="primary">
Create
</Button>
</CardFooter>
</Card>
);
Expand Down
104 changes: 104 additions & 0 deletions client/blocks/plugins-update-manager/schedule-form.const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
export const MAX_SELECTABLE_PLUGINS = 10;

export const DAILY_OPTION = {
label: 'Daily',
value: 'daily',
};

export const WEEKLY_OPTION = {
label: 'Weekly',
value: 'weekly',
};

export const DAY_OPTIONS = [
{
label: 'Monday',
value: '1',
},
{
label: 'Tuesday',
value: '2',
},
{
label: 'Wednesday',
value: '3',
},
{
label: 'Thursday',
value: '4',
},
{
label: 'Friday',
value: '5',
},
{
label: 'Saturday',
value: '6',
},
{
label: 'Sunday',
value: '0',
},
];

export const HOUR_OPTIONS = [
{
label: '01',
value: '1',
},
{
label: '02',
value: '2',
},
{
label: '03',
value: '3',
},
{
label: '04',
value: '4',
},
{
label: '05',
value: '5',
},
{
label: '06',
value: '6',
},
{
label: '07',
value: '7',
},
{
label: '08',
value: '8',
},
{
label: '09',
value: '9',
},
{
label: '10',
value: '10',
},
{
label: '11',
value: '11',
},
{
label: '12',
value: '12',
},
];

export const PERIOD_OPTIONS = [
{
label: 'AM',
value: 'am',
},
{
label: 'PM',
value: 'pm',
},
];
193 changes: 96 additions & 97 deletions client/blocks/plugins-update-manager/schedule-form.helper.ts
Original file line number Diff line number Diff line change
@@ -1,104 +1,103 @@
export const MAX_SELECTABLE_PLUGINS = 10;
/**
* Prepare unix timestamp in seconds
* based on selected frequency, day, hour and period
*/
export const prepareTimestamp = (
frequency: string,
day: string,
hour: string,
period: string
) => {
const event = new Date();

export const DAILY_OPTION = {
label: 'Daily',
value: 'daily',
const hours = parseInt( hour ) + ( period === 'pm' ? 12 : 0 );
event.setHours( hours, 0, 0, 0 );

if ( frequency === 'daily' ) {
// Set next day
event.setDate( event.getDate() + 1 );
}

if ( frequency === 'weekly' ) {
// Set first next selected day
event.setDate( event.getDate() + ( ( parseInt( day ) + 7 - event.getDay() ) % 7 || 7 ) );
}

// return timestamp in seconds
return event.getTime() / 1000;
};

export const WEEKLY_OPTION = {
label: 'Weekly',
value: 'weekly',
/**
* Validate name
* - required
* - max length 120
*/
export const validateName = ( name: string ) => {
let error = '';
if ( ! name ) {
error = 'Please provide a name to this plugin update schedule.';
} else if ( name.length > 120 ) {
error = 'Please provide a shorter name.';
}

return error;
};

export const DAY_OPTIONS = [
{
label: 'Monday',
value: 'a',
},
{
label: 'Tuesday',
value: 'b',
},
{
label: 'Wednesday',
value: 'c',
},
{
label: 'Thursday',
value: 'd',
},
{
label: 'Friday',
value: 'e',
},
{
label: 'Saturday',
value: 'f',
},
{
label: 'Sunday',
value: 'g',
},
];
type TimeSlot = {
frequency: string;
timestamp: number;
};
/**
* Validate time slot
* based on existing schedules in context of frequency
*/
export const validateTimeSlot = ( newSchedule: TimeSlot, existingSchedules: TimeSlot[] = [] ) => {
let error = '';
const newDate = new Date( newSchedule.timestamp * 1000 );

existingSchedules.forEach( ( schedule ) => {
if ( error ) {
return;
}

const existingDate = new Date( schedule.timestamp * 1000 );

export const HOUR_OPTIONS = [
{
label: '00',
value: '0',
},
{
label: '01',
value: '1',
},
{
label: '02',
value: '3',
},
{
label: '03',
value: '3',
},
{
label: '04',
value: '4',
},
{
label: '05',
value: '5',
},
{
label: '06',
value: '6',
},
{
label: '07',
value: '7',
},
{
label: '08',
value: '8',
},
{
label: '09',
value: '9',
},
{
label: '10',
value: '10',
},
{
label: '11',
value: '11',
},
];
if (
( newSchedule.frequency === 'daily' || schedule.frequency === 'daily' ) &&
existingDate.getHours() === newDate.getHours()
) {
error = 'Please choose another time, as this slot is already scheduled.';
} else if (
newSchedule.frequency === 'weekly' &&
schedule.frequency === 'weekly' &&
newDate.getDay() === existingDate.getDay() &&
newDate.getHours() === existingDate.getHours()
) {
error = 'Please pick another time for optimal performance, as this slot is already taken.';
}
} );

export const PERIOD_OPTIONS = [
{
label: 'AM',
value: 'am',
},
{
label: 'PM',
value: 'pm',
},
];
return error;
};

/**
* Validate plugins
* compared with existing scheduled plugins
*/
export const validatePlugins = ( plugins: string[], existingPlugins: Array< string[] > = [] ) => {
let error = '';

if ( plugins.length === 0 ) {
error = 'Please select at least one plugin to update.';
} else if ( existingPlugins.length ) {
const _plugins = [ ...plugins ].sort();

existingPlugins.forEach( ( existing ) => {
if ( JSON.stringify( _plugins ) === JSON.stringify( [ ...existing ].sort() ) ) {
error = 'Please select a different set of plugins, as this one has already been chosen.';
}
} );
}

return error;
};
Loading

0 comments on commit 6511093

Please sign in to comment.