fix: allow users to disable any active cloud integration even if they are not entitled to cloud backups (#870)

* fix: allow users to disable any active cloud integration even if they are not entitled to cloud backups

* chore: better variable naming

* refactor: move css constant away from the global constants file

* refactor: avoid importing a constant css class from non-shared file
This commit is contained in:
Vardan Hakobyan
2022-02-15 19:48:35 +04:00
committed by GitHub
parent dab8080da6
commit 80cc37fbd4
3 changed files with 41 additions and 32 deletions

View File

@@ -34,7 +34,7 @@ export const EmailBackups = observer(({ application }: Props) => {
>([]); >([]);
const [isFailedBackupEmailMuted, setIsFailedBackupEmailMuted] = const [isFailedBackupEmailMuted, setIsFailedBackupEmailMuted] =
useState(true); useState(true);
const [isEntitledForEmailBackups, setIsEntitledForEmailBackups] = const [isEntitledToEmailBackups, setIsEntitledToEmailBackups] =
useState(false); useState(false);
const loadEmailFrequencySetting = useCallback(async () => { const loadEmailFrequencySetting = useCallback(async () => {
@@ -65,7 +65,7 @@ export const EmailBackups = observer(({ application }: Props) => {
const emailBackupsFeatureStatus = application.getFeatureStatus( const emailBackupsFeatureStatus = application.getFeatureStatus(
FeatureIdentifier.DailyEmailBackup FeatureIdentifier.DailyEmailBackup
); );
setIsEntitledForEmailBackups( setIsEntitledToEmailBackups(
emailBackupsFeatureStatus === FeatureStatus.Entitled emailBackupsFeatureStatus === FeatureStatus.Entitled
); );
@@ -126,7 +126,7 @@ export const EmailBackups = observer(({ application }: Props) => {
<PreferencesGroup> <PreferencesGroup>
<PreferencesSegment> <PreferencesSegment>
<Title>Email Backups</Title> <Title>Email Backups</Title>
{!isEntitledForEmailBackups && ( {!isEntitledToEmailBackups && (
<> <>
<Text> <Text>
A <span className={'font-bold'}>Plus</span> or{' '} A <span className={'font-bold'}>Plus</span> or{' '}
@@ -142,7 +142,7 @@ export const EmailBackups = observer(({ application }: Props) => {
)} )}
<div <div
className={ className={
isEntitledForEmailBackups isEntitledToEmailBackups
? '' ? ''
: 'faded cursor-default pointer-events-none' : 'faded cursor-default pointer-events-none'
} }

View File

@@ -17,11 +17,13 @@ import { FunctionComponent } from 'preact';
type Props = { type Props = {
application: WebApplication; application: WebApplication;
providerName: CloudProvider; providerName: CloudProvider;
isEntitledToCloudBackups: boolean;
}; };
export const CloudBackupProvider: FunctionComponent<Props> = ({ export const CloudBackupProvider: FunctionComponent<Props> = ({
application, application,
providerName, providerName,
isEntitledToCloudBackups,
}) => { }) => {
const [authBegan, setAuthBegan] = useState(false); const [authBegan, setAuthBegan] = useState(false);
const [successfullyInstalled, setSuccessfullyInstalled] = useState(false); const [successfullyInstalled, setSuccessfullyInstalled] = useState(false);
@@ -174,6 +176,9 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
const isExpanded = authBegan || successfullyInstalled; const isExpanded = authBegan || successfullyInstalled;
const shouldShowEnableButton = !backupFrequency && !authBegan; const shouldShowEnableButton = !backupFrequency && !authBegan;
const additionalClass = isEntitledToCloudBackups
? ''
: 'faded cursor-default pointer-events-none';
return ( return (
<div <div
@@ -184,7 +189,7 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
}`} }`}
> >
<div> <div>
<Subtitle>{providerName}</Subtitle> <Subtitle className={additionalClass}>{providerName}</Subtitle>
{successfullyInstalled && ( {successfullyInstalled && (
<p>{providerName} has been successfully enabled.</p> <p>{providerName} has been successfully enabled.</p>
@@ -213,7 +218,7 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
<Button <Button
type="normal" type="normal"
label="Enable" label="Enable"
className={'px-1 text-xs min-w-40'} className={`px-1 text-xs min-w-40 ${additionalClass}`}
onClick={installIntegration} onClick={installIntegration}
/> />
</div> </div>
@@ -222,7 +227,7 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
{backupFrequency && ( {backupFrequency && (
<div className={'flex flex-col items-end'}> <div className={'flex flex-col items-end'}>
<Button <Button
className="min-w-40 mb-2" className={`min-w-40 mb-2 ${additionalClass}`}
type="normal" type="normal"
label="Perform Backup" label="Perform Backup"
onClick={performBackupNow} onClick={performBackupNow}

View File

@@ -35,11 +35,14 @@ type Props = {
}; };
export const CloudLink: FunctionComponent<Props> = ({ application }) => { export const CloudLink: FunctionComponent<Props> = ({ application }) => {
const [isEntitledForCloudBackups, setIsEntitledForCloudBackups] = const [isEntitledToCloudBackups, setIsEntitledToCloudBackups] =
useState(false); useState(false);
const [isFailedCloudBackupEmailMuted, setIsFailedCloudBackupEmailMuted] = const [isFailedCloudBackupEmailMuted, setIsFailedCloudBackupEmailMuted] =
useState(true); useState(true);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const additionalClass = isEntitledToCloudBackups
? ''
: 'faded cursor-default pointer-events-none';
const loadIsFailedCloudBackupEmailMutedSetting = useCallback(async () => { const loadIsFailedCloudBackupEmailMutedSetting = useCallback(async () => {
if (!application.getUser()) { if (!application.getUser()) {
@@ -77,7 +80,7 @@ export const CloudLink: FunctionComponent<Props> = ({ application }) => {
dailyOneDriveBackupStatus, dailyOneDriveBackupStatus,
].every((status) => status === FeatureStatus.Entitled); ].every((status) => status === FeatureStatus.Entitled);
setIsEntitledForCloudBackups(isCloudBackupsAllowed); setIsEntitledToCloudBackups(isCloudBackupsAllowed);
loadIsFailedCloudBackupEmailMutedSetting(); loadIsFailedCloudBackupEmailMutedSetting();
}, [application, loadIsFailedCloudBackupEmailMutedSetting]); }, [application, loadIsFailedCloudBackupEmailMutedSetting]);
@@ -111,7 +114,7 @@ export const CloudLink: FunctionComponent<Props> = ({ application }) => {
<PreferencesGroup> <PreferencesGroup>
<PreferencesSegment> <PreferencesSegment>
<Title>Cloud Backups</Title> <Title>Cloud Backups</Title>
{!isEntitledForCloudBackups && ( {!isEntitledToCloudBackups && (
<> <>
<Text> <Text>
A <span className={'font-bold'}>Plus</span> or{' '} A <span className={'font-bold'}>Plus</span> or{' '}
@@ -125,45 +128,46 @@ export const CloudLink: FunctionComponent<Props> = ({ application }) => {
<HorizontalSeparator classes="mt-3 mb-3" /> <HorizontalSeparator classes="mt-3 mb-3" />
</> </>
)} )}
<div <div>
className={ <Text className={additionalClass}>
isEntitledForCloudBackups
? ''
: 'faded cursor-default pointer-events-none'
}
>
<Text>
Configure the integrations below to enable automatic daily backups Configure the integrations below to enable automatic daily backups
of your encrypted data set to your third-party cloud provider. of your encrypted data set to your third-party cloud provider.
</Text> </Text>
<div> <div>
<HorizontalSeparator classes={'mt-3 mb-3'} /> <HorizontalSeparator classes={`mt-3 mb-3 ${additionalClass}`} />
<div> <div>
{providerData.map(({ name }) => ( {providerData.map(({ name }) => (
<> <>
<CloudBackupProvider <CloudBackupProvider
application={application} application={application}
providerName={name} providerName={name}
isEntitledToCloudBackups={isEntitledToCloudBackups}
/>
<HorizontalSeparator
classes={`mt-3 mb-3 ${additionalClass}`}
/> />
<HorizontalSeparator classes={'mt-3 mb-3'} />
</> </>
))} ))}
</div> </div>
</div> </div>
<Subtitle>Email preferences</Subtitle> <div className={additionalClass}>
<div className="flex items-center justify-between mt-1"> <Subtitle>Email preferences</Subtitle>
<div className="flex flex-col"> <div className="flex items-center justify-between mt-1">
<Text>Receive a notification email if a cloud backup fails.</Text> <div className="flex flex-col">
<Text>
Receive a notification email if a cloud backup fails.
</Text>
</div>
{isLoading ? (
<div className={'sk-spinner info small'} />
) : (
<Switch
onChange={toggleMuteFailedCloudBackupEmails}
checked={!isFailedCloudBackupEmailMuted}
/>
)}
</div> </div>
{isLoading ? (
<div className={'sk-spinner info small'} />
) : (
<Switch
onChange={toggleMuteFailedCloudBackupEmails}
checked={!isFailedCloudBackupEmailMuted}
/>
)}
</div> </div>
</div> </div>
</PreferencesSegment> </PreferencesSegment>