mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
add: week selection to policy creation.
This commit is contained in:
@@ -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 =
|
||||
|
||||
+38
-6
@@ -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>
|
||||
|
||||
+47
-2
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user