Move isDirty to view concern. Document model is not updated until save
This commit is contained in:
@ -11,7 +11,6 @@ import type { NavigationNode } from 'types';
|
||||
|
||||
class Collection extends BaseModel {
|
||||
isSaving: boolean = false;
|
||||
hasPendingChanges: boolean = false;
|
||||
ui: UiStore;
|
||||
data: Object;
|
||||
|
||||
@ -109,7 +108,6 @@ class Collection extends BaseModel {
|
||||
runInAction('Collection#save', () => {
|
||||
invariant(res && res.data, 'Data should be available');
|
||||
this.updateData(res.data);
|
||||
this.hasPendingChanges = false;
|
||||
});
|
||||
} catch (e) {
|
||||
this.ui.showToast('Collection failed saving');
|
||||
|
@ -15,7 +15,6 @@ type SaveOptions = { publish?: boolean, done?: boolean, autosave?: boolean };
|
||||
|
||||
class Document extends BaseModel {
|
||||
isSaving: boolean = false;
|
||||
hasPendingChanges: boolean = false;
|
||||
ui: *;
|
||||
store: *;
|
||||
|
||||
@ -209,7 +208,6 @@ class Document extends BaseModel {
|
||||
runInAction('Document#save', () => {
|
||||
invariant(res && res.data, 'Data should be available');
|
||||
this.updateData(res.data);
|
||||
this.hasPendingChanges = false;
|
||||
|
||||
if (isCreating) {
|
||||
this.emit('documents.create', this);
|
||||
@ -288,13 +286,12 @@ class Document extends BaseModel {
|
||||
a.click();
|
||||
};
|
||||
|
||||
updateData(data: Object = {}, dirty: boolean = false) {
|
||||
updateData(data: Object = {}) {
|
||||
if (data.text) {
|
||||
const { title, emoji } = parseTitle(data.text);
|
||||
data.title = title;
|
||||
data.emoji = emoji;
|
||||
}
|
||||
if (dirty) this.hasPendingChanges = true;
|
||||
extendObservable(this, data);
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,7 @@ class DocumentScene extends React.Component<Props> {
|
||||
@observable isUploading = false;
|
||||
@observable isSaving = false;
|
||||
@observable isPublishing = false;
|
||||
@observable isDirty = false;
|
||||
@observable notFound = false;
|
||||
@observable moveModalOpen: boolean = false;
|
||||
|
||||
@ -117,6 +118,7 @@ class DocumentScene extends React.Component<Props> {
|
||||
props.match.params.documentSlug,
|
||||
{ shareId }
|
||||
);
|
||||
this.isDirty = false;
|
||||
|
||||
const document = this.document;
|
||||
|
||||
@ -167,7 +169,7 @@ class DocumentScene extends React.Component<Props> {
|
||||
if (!document) return;
|
||||
|
||||
// get the latest version of the editor text value
|
||||
const text = this.getEditorText();
|
||||
const text = this.getEditorText ? this.getEditorText() : document.text;
|
||||
|
||||
// prevent autosave if nothing has changed
|
||||
if (options.autosave && document.text.trim() === text.trim()) return;
|
||||
@ -183,6 +185,7 @@ class DocumentScene extends React.Component<Props> {
|
||||
this.isSaving = true;
|
||||
this.isPublishing = !!options.publish;
|
||||
document = await document.save(options);
|
||||
this.isDirty = false;
|
||||
this.isSaving = false;
|
||||
this.isPublishing = false;
|
||||
|
||||
@ -199,6 +202,10 @@ class DocumentScene extends React.Component<Props> {
|
||||
this.onSave({ done: false, autosave: true });
|
||||
}, AUTOSAVE_INTERVAL);
|
||||
|
||||
updateIsDirty = debounce(() => {
|
||||
this.isDirty = this.getEditorText().trim() !== this.document.text.trim();
|
||||
}, 500);
|
||||
|
||||
onImageUploadStart = () => {
|
||||
this.isUploading = true;
|
||||
};
|
||||
@ -209,6 +216,7 @@ class DocumentScene extends React.Component<Props> {
|
||||
|
||||
onChange = getEditorText => {
|
||||
this.getEditorText = getEditorText;
|
||||
this.updateIsDirty();
|
||||
this.autosave();
|
||||
};
|
||||
|
||||
@ -312,7 +320,7 @@ class DocumentScene extends React.Component<Props> {
|
||||
{this.isEditing && (
|
||||
<React.Fragment>
|
||||
<Prompt
|
||||
when={document.hasPendingChanges}
|
||||
when={this.isDirty}
|
||||
message={DISCARD_CHANGES}
|
||||
/>
|
||||
<Prompt when={this.isUploading} message={UPLOADING_WARNING} />
|
||||
@ -322,6 +330,7 @@ class DocumentScene extends React.Component<Props> {
|
||||
<Header
|
||||
document={document}
|
||||
isDraft={document.isDraft}
|
||||
isDirty={this.isDirty}
|
||||
isEditing={this.isEditing}
|
||||
isSaving={this.isSaving}
|
||||
isPublishing={this.isPublishing}
|
||||
|
@ -20,6 +20,7 @@ import { Action, Separator } from 'components/Actions';
|
||||
|
||||
type Props = {
|
||||
document: Document,
|
||||
isDirty: boolean,
|
||||
isDraft: boolean,
|
||||
isEditing: boolean,
|
||||
isSaving: boolean,
|
||||
@ -87,6 +88,7 @@ class Header extends React.Component<Props> {
|
||||
document,
|
||||
isEditing,
|
||||
isDraft,
|
||||
isDirty,
|
||||
isPublishing,
|
||||
isSaving,
|
||||
savingIsDisabled,
|
||||
@ -161,13 +163,6 @@ class Header extends React.Component<Props> {
|
||||
<Link onClick={this.handleEdit}>Edit</Link>
|
||||
</Action>
|
||||
)}
|
||||
{isEditing &&
|
||||
!isSaving &&
|
||||
document.hasPendingChanges && (
|
||||
<Action>
|
||||
<Link onClick={this.props.onDiscard}>Discard</Link>
|
||||
</Action>
|
||||
)}
|
||||
{!isEditing && (
|
||||
<Action>
|
||||
<DocumentMenu document={document} showPrint />
|
||||
|
Reference in New Issue
Block a user