add: week selection to policy creation.

This commit is contained in:
ItzNotABug
2024-09-30 13:18:13 +05:30
parent cc04f5ecbe
commit ceefa7e2d8
3 changed files with 107 additions and 13 deletions
+22 -5
View File
@@ -10,6 +10,7 @@ export type UserBackupPolicy = {
checked?: boolean;
selectedTime?: string;
plainTextFrequency?: string;
weeklySelectedDays?: string[];
monthlyBackupFrequency?: string;
};
@@ -47,7 +48,16 @@ export const cronExpression = (policy: UserBackupPolicy) => {
if (policy.plainTextFrequency === 'daily') {
cronExpression = `${utcMinute} ${utcHour} * * *`;
} else if (policy.plainTextFrequency === 'weekly') {
cronExpression = `${utcMinute} ${utcHour} * * 1`;
const selectedDays = policy.weeklySelectedDays
?.map(
(dayLabel) =>
backupFrequencies.weekly.find((option) => option.label === dayLabel)?.index
)
.filter((index) => index !== undefined)
.join(',');
// Default to Monday (1)
cronExpression = `${utcMinute} ${utcHour} * * ${selectedDays || '1'}`;
} else if (policy.plainTextFrequency === 'monthly') {
cronExpression = `${utcMinute} ${utcHour} 28 * *`;
}
@@ -94,7 +104,8 @@ export const backupPolicyDescription = (
frequency: string,
time: string | null = null,
retained: number | null = null,
monthlyBackupFrequency: string
monthlyBackupFrequency: string,
weeklySelectedDays: string[] | null = null
) => {
const timeFormatted = time ? formatTime24to12(time) : '';
let retainedText = '';
@@ -127,10 +138,16 @@ export const backupPolicyDescription = (
? `Runs every day and is retained for ${retainedText}.`
: `A backup will run daily at ${timeFormatted}.`;
case 'weekly':
case 'weekly': {
const daysArray = weeklySelectedDays || ['Monday'];
const dayString =
daysArray.length > 1
? daysArray.slice(0, -1).join(', ') + ' and ' + daysArray.slice(-1)
: daysArray[0];
return retained !== null
? `Runs every Monday and is retained for ${retainedText}.`
: `A backup will run weekly on Monday at ${timeFormatted}.`;
? `Runs every ${dayString} and is retained for ${retainedText}.`
: `A backup will run weekly on ${dayString} at ${timeFormatted}.`;
}
case 'monthly': {
const monthDay =
@@ -5,8 +5,10 @@
Helper,
InputCheckbox,
InputSelect,
InputSelectCheckbox,
InputText,
InputTime
InputTime,
Label
} from '$lib/elements/forms';
import { ID } from '@appwrite.io/console';
import { capitalize } from '$lib/helpers/string';
@@ -42,6 +44,8 @@
let policyNameError: boolean;
let policyFrequency = 'monthly';
let monthlyBackupFrequency = 'end';
$: daysSelectionArray = [];
$: backupPolicyName = `${capitalize(policyFrequency)} backup`;
$: customRetentionEnabled = policyRetention === -1;
@@ -51,9 +55,9 @@
policyInEdit = null;
policyRetention = 30;
selectedTime = '00:00';
daysSelectionArray = [];
policyFrequency = 'monthly';
monthlyBackupFrequency = 'end';
customRetentionEnabled = false;
};
@@ -73,9 +77,13 @@
retained: policyRetention,
id: policyInEdit ?? ID.unique(),
plainTextFrequency: policyFrequency,
weeklySelectedDays: daysSelectionArray,
// placeholder description.
description: `Runs every ${policyFrequency} and is retained for ${policyRetention}`
};
userBackupPolicy.description = customPolicyDescription(userBackupPolicy);
listOfCustomPolicies = [...listOfCustomPolicies, userBackupPolicy];
resetFormVariables();
@@ -100,12 +108,19 @@
policy.plainTextFrequency,
null,
policy.retained,
policy.monthlyBackupFrequency
policy.monthlyBackupFrequency,
policy.weeklySelectedDays
);
};
$: formPolicyDescription = () => {
return backupPolicyDescription(policyFrequency, selectedTime, null, monthlyBackupFrequency);
return backupPolicyDescription(
policyFrequency,
selectedTime,
null,
monthlyBackupFrequency,
daysSelectionArray
);
};
$: if (showCustomPolicy) {
@@ -187,6 +202,7 @@
policyFrequency = policy.plainTextFrequency;
monthlyBackupFrequency =
policy.monthlyBackupFrequency;
daysSelectionArray = policy.weeklySelectedDays;
// do not show in the list can cause confusion.
listOfCustomPolicies = [
@@ -252,15 +268,31 @@
placeholder="End of month (28th)"
fullWidth
options={backupFrequencies[policyFrequency]} />
{:else if policyFrequency === 'weekly'}
<div class="u-flex-vertical u-width-full-line">
<Label>Timing</Label>
<InputSelectCheckbox
name="Timing"
bind:tags={daysSelectionArray}
placeholder="Select the weekdays for backup"
options={backupFrequencies[policyFrequency].map(
(option) => ({
...option,
checked: daysSelectionArray.includes(
option.value
)
})
)} />
</div>
{/if}
<div
class:u-margin-block-start-4={policyFrequency ===
'monthly'}>
'monthly' || policyFrequency === 'weekly'}>
<InputTime
id="time"
bind:value={selectedTime}
label={['daily', 'weekly'].includes(policyFrequency)
label={['daily'].includes(policyFrequency)
? 'Timing'
: ''} />
</div>
@@ -11,9 +11,12 @@
import { parseExpression } from 'cron-parser';
import { toLocaleDateTime } from '$lib/helpers/date';
import { tooltip } from '$lib/actions/tooltip';
import EmptyDark from '$lib/images/backups/backups-dark.png';
import EmptyLight from '$lib/images/backups/backups-light.png';
import type { BackupPolicy, BackupPolicyList } from '$lib/sdk/backups';
import { backupFrequencies } from '$lib/helpers/backups';
let showDropdown = [];
let showDelete = false;
@@ -70,7 +73,14 @@
}
if (dayOfMonth === '*' && month === '*' && dayOfWeek !== '*') {
return `Runs weekly on Monday`;
const days = dayOfWeek
.split(',')
.map((day) => backupFrequencies.weekly[parseInt(day, 10)].label);
const dayString =
days.length > 1 ? days.slice(0, -1).join(', ') + ' and ' + days.slice(-1) : days[0];
return `Runs weekly on ${dayString}`;
}
if (
@@ -93,6 +103,29 @@
return 'Runs daily';
}
};
const getTruncatedPolicyDescription = (policyDescription: string): string => {
let firstDayIndex = -1;
let secondDayIndex = -1;
for (const day of backupFrequencies.weekly.map((item) => item.label)) {
const dayIndex = policyDescription.indexOf(day);
if (dayIndex !== -1) {
if (firstDayIndex === -1) {
firstDayIndex = dayIndex;
} else {
secondDayIndex = dayIndex;
break;
}
}
}
if (firstDayIndex === -1 || secondDayIndex === -1) {
return policyDescription;
}
return `${policyDescription.substring(0, secondDayIndex).trim().replace(',', '')}...`;
};
</script>
<div class="u-flex u-flex-vertical u-gap-16">
@@ -101,6 +134,10 @@
style="padding: 0; min-width: 21.5rem;">
<div class="inner-card u-flex-vertical-mobile">
{#each policies.policies as policy, index (policy.$id)}
{@const policyDescription = getPolicyDescription(policy.schedule)}
{@const policyDescriptionShort = getTruncatedPolicyDescription(policyDescription)}
{@const shouldUseTooltip = policyDescription.length > policyDescriptionShort.length}
<div
class="policy-card-item-padding u-flex-vertical u-gap-10"
data-show-every={showEveryPolicy}
@@ -140,8 +177,16 @@
<div
class="policy-item-subtitles u-flex u-gap-6"
style="width: fit-content;">
{getPolicyDescription(policy.schedule)}
{#if shouldUseTooltip}
<span use:tooltip={{ content: policyDescription }}>
{policyDescriptionShort}
</span>
{:else}
{policyDescription}
{/if}
<span class="small-ellipse"></span>
{formatRetentionMessage(policy.retention)}
</div>
</div>