* refactor: menuRow directive to MenuRow component * refactor: migrate footer to react * refactor: migrate actions menu to react * refactor: migrate history menu to react * fix: click outside handler use capture to trigger event before re-render occurs which would otherwise cause node.contains to return incorrect result (specifically for the account menu) * refactor: migrate revision preview modal to react * refactor: migrate permissions modal to react * refactor: migrate password wizard to react * refactor: remove unused input modal directive * refactor: remove unused delay hide component * refactor: remove unused filechange directive * refactor: remove unused elemReady directive * refactor: remove unused sn-enter directive * refactor: remove unused lowercase directive * refactor: remove unused autofocus directive * refactor(wip): note view to react * refactor: use mutation observer to deinit textarea listeners * refactor: migrate challenge modal to react * refactor: migrate note group view to react * refactor(wip): migrate remaining classes * fix: navigation parent ref * refactor: fully remove angular assets * fix: account switcher * fix: application view state * refactor: remove unused password wizard type * fix: revision preview and permissions modal * fix: remove angular comment * refactor: react panel resizers for editor * feat: simple panel resizer * fix: use simple panel resizer everywhere * fix: simplify panel resizer state * chore: rename simple panel resizer to panel resizer * refactor: simplify column layout * fix: editor mount safety check * fix: use inline onLoad callback for iframe, as setting onload after it loads will never call it * chore: fix note view test * chore(deps): upgrade snjs
188 lines
6.8 KiB
TypeScript
188 lines
6.8 KiB
TypeScript
import { WebApplication } from '@/ui_models/application';
|
|
import { PureComponent } from './Abstract/PureComponent';
|
|
import { Fragment } from 'preact';
|
|
|
|
type Props = {
|
|
application: WebApplication;
|
|
close: () => void;
|
|
};
|
|
|
|
export class SyncResolutionMenu extends PureComponent<Props> {
|
|
private status: Partial<{
|
|
backupFinished: boolean;
|
|
resolving: boolean;
|
|
attemptedResolution: boolean;
|
|
success: boolean;
|
|
fail: boolean;
|
|
}> = {};
|
|
|
|
constructor(props: Props) {
|
|
super(props, props.application);
|
|
}
|
|
|
|
downloadBackup(encrypted: boolean) {
|
|
this.props.application.getArchiveService().downloadBackup(encrypted);
|
|
this.status.backupFinished = true;
|
|
}
|
|
|
|
skipBackup() {
|
|
this.status.backupFinished = true;
|
|
}
|
|
|
|
async performSyncResolution() {
|
|
this.status.resolving = true;
|
|
await this.props.application.resolveOutOfSync();
|
|
|
|
this.status.resolving = false;
|
|
this.status.attemptedResolution = true;
|
|
if (this.props.application.isOutOfSync()) {
|
|
this.status.fail = true;
|
|
} else {
|
|
this.status.success = true;
|
|
}
|
|
}
|
|
|
|
close() {
|
|
this.props.close();
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<div className="sn-component">
|
|
<div id="sync-resolution-menu" className="sk-panel sk-panel-right">
|
|
<div className="sk-panel-header">
|
|
<div className="sk-panel-header-title">Out of Sync</div>
|
|
<a onClick={this.close} className="sk-a info close-button">
|
|
Close
|
|
</a>
|
|
</div>
|
|
<div className="sk-panel-content">
|
|
<div className="sk-panel-section">
|
|
<div className="sk-panel-row sk-p">
|
|
We've detected that the data on the server may not match the
|
|
data in the current application session.
|
|
</div>
|
|
<div className="sk-p sk-panel-row">
|
|
<div className="sk-panel-column">
|
|
<strong className="sk-panel-row">
|
|
Option 1 — Restart App:
|
|
</strong>
|
|
<div className="sk-p">
|
|
Quit the application and re-open it. Sometimes, this may
|
|
resolve the issue.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="sk-p sk-panel-row">
|
|
<div className="sk-panel-column">
|
|
<strong className="sk-panel-row">
|
|
Option 2 (recommended) — Sign Out:
|
|
</strong>
|
|
<div className="sk-p">
|
|
Sign out of your account, then sign back in. This will
|
|
ensure your data is consistent with the server.
|
|
</div>
|
|
Be sure to download a backup of your data before doing so.
|
|
</div>
|
|
</div>
|
|
<div className="sk-p sk-panel-row">
|
|
<div className="sk-panel-column">
|
|
<strong className="sk-panel-row">
|
|
Option 3 — Sync Resolution:
|
|
</strong>
|
|
<div className="sk-p">
|
|
We can attempt to reconcile changes by downloading all data
|
|
from the server. No existing data will be overwritten. If
|
|
the local contents of an item differ from what the server
|
|
has, a conflicted copy will be created.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{!this.status.backupFinished && (
|
|
<Fragment>
|
|
<div className="sk-p sk-panel-row">
|
|
Please download a backup before we attempt to perform a full
|
|
account sync resolution.
|
|
</div>
|
|
<div className="sk-panel-row">
|
|
<div className="flex gap-2">
|
|
<button
|
|
onClick={() => this.downloadBackup(true)}
|
|
className="sn-button small info"
|
|
>
|
|
Encrypted
|
|
</button>
|
|
<button
|
|
onClick={() => this.downloadBackup(false)}
|
|
className="sn-button small info"
|
|
>
|
|
Decrypted
|
|
</button>
|
|
<button
|
|
onClick={this.skipBackup}
|
|
className="sn-button small danger"
|
|
>
|
|
Skip
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</Fragment>
|
|
)}
|
|
|
|
{this.status.backupFinished && (
|
|
<div>
|
|
{!this.status.resolving && !this.status.attemptedResolution && (
|
|
<div className="sk-panel-row">
|
|
<button
|
|
onClick={this.performSyncResolution}
|
|
className="sn-button small info"
|
|
>
|
|
Perform Sync Resolution
|
|
</button>
|
|
</div>
|
|
)}
|
|
{this.status.resolving && (
|
|
<div className="sk-panel-row justify-left">
|
|
<div className="sk-horizontal-group">
|
|
<div className="sk-spinner small info" />
|
|
<div className="sk-label">
|
|
Attempting sync resolution...
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{this.status.fail && (
|
|
<div className="sk-panel-column">
|
|
<div className="sk-panel-row sk-label danger">
|
|
Sync Resolution Failed
|
|
</div>
|
|
<div className="sk-p sk-panel-row">
|
|
We attempted to reconcile local content and server
|
|
content, but were unable to do so. At this point, we
|
|
recommend signing out of your account and signing back
|
|
in. You may wish to download a data backup before doing
|
|
so.
|
|
</div>
|
|
</div>
|
|
)}
|
|
{this.status.success && (
|
|
<div className="sk-panel-column">
|
|
<div className="sk-panel-row sk-label success">
|
|
Sync Resolution Success
|
|
</div>
|
|
<div className="sk-p sk-panel-row">
|
|
Your local data is now in sync with the server. You may
|
|
close this window.
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|