diff --git a/studio/src/app/services/data/deck/deck.offline.service.tsx b/studio/src/app/services/data/deck/deck.offline.service.tsx index 36f3cc403..687e3590b 100644 --- a/studio/src/app/services/data/deck/deck.offline.service.tsx +++ b/studio/src/app/services/data/deck/deck.offline.service.tsx @@ -3,6 +3,7 @@ import {get, set} from 'idb-keyval'; import {Deck} from '../../../models/data/deck'; import {OfflineUtils} from '../../../utils/editor/offline.utils'; +import {FirestoreUtils} from '../../../utils/editor/firestore.utils'; export class DeckOfflineService { private static instance: DeckOfflineService; @@ -41,7 +42,7 @@ export class DeckOfflineService { // @ts-ignore deck.data.updated_at = new Date(); - if (deck.data.background && OfflineUtils.shouldAttributeBeCleaned(deck.data.background)) { + if (deck.data.background && FirestoreUtils.shouldAttributeBeCleaned(deck.data.background)) { deck.data.background = null; } diff --git a/studio/src/app/services/data/deck/deck.online.service.tsx b/studio/src/app/services/data/deck/deck.online.service.tsx index 1575ca11f..9514f9003 100644 --- a/studio/src/app/services/data/deck/deck.online.service.tsx +++ b/studio/src/app/services/data/deck/deck.online.service.tsx @@ -2,6 +2,7 @@ import * as firebase from 'firebase/app'; import 'firebase/firestore'; import {Deck, DeckData} from '../../../models/data/deck'; +import {FirestoreUtils} from '../../../utils/editor/firestore.utils'; export class DeckOnlineService { private static instance: DeckOnlineService; @@ -51,10 +52,7 @@ export class DeckOnlineService { try { await firestore.collection('decks').doc(deck.id).set(deck.data, {merge: true}); - // Fetch newly persisted deck (clean firebase.firestore.FieldValue.delete()) - const updatedDeck: Deck = await this.get(deck.id); - - resolve(updatedDeck); + resolve(FirestoreUtils.filterDelete(deck)); } catch (err) { reject(err); } diff --git a/studio/src/app/services/data/slide/slide.offline.service.tsx b/studio/src/app/services/data/slide/slide.offline.service.tsx index 6e33d4c5d..9fad05119 100644 --- a/studio/src/app/services/data/slide/slide.offline.service.tsx +++ b/studio/src/app/services/data/slide/slide.offline.service.tsx @@ -5,6 +5,7 @@ import {del, get, set} from 'idb-keyval'; import {Slide, SlideData} from '../../../models/data/slide'; import {OfflineUtils} from '../../../utils/editor/offline.utils'; +import {FirestoreUtils} from '../../../utils/editor/firestore.utils'; export class SlideOfflineService { private static instance: SlideOfflineService; @@ -27,7 +28,7 @@ export class SlideOfflineService { const slide: Slide = { id: slideId, - data: slideData + data: slideData, }; const now: Date = new Date(); @@ -68,7 +69,7 @@ export class SlideOfflineService { slide.data.attributes = await OfflineUtils.cleanAttributes(slide.data.attributes); - if (slide.data.content && OfflineUtils.shouldAttributeBeCleaned(slide.data.content)) { + if (slide.data.content && FirestoreUtils.shouldAttributeBeCleaned(slide.data.content)) { slide.data.content = null; } diff --git a/studio/src/app/services/editor/offline/offline.service.tsx b/studio/src/app/services/editor/offline/offline.service.tsx index aae748cce..c4723a491 100644 --- a/studio/src/app/services/editor/offline/offline.service.tsx +++ b/studio/src/app/services/editor/offline/offline.service.tsx @@ -11,6 +11,7 @@ import {Slide} from '../../../models/data/slide'; import {SlotType} from '../../../utils/editor/slot-type'; import {OfflineUtils} from '../../../utils/editor/offline.utils'; +import {FirestoreUtils} from '../../../utils/editor/firestore.utils'; import {ServiceWorkerUtils} from '../../../utils/core/service-worker-utils'; import {SlideOnlineService} from '../../data/slide/slide.online.service'; @@ -352,7 +353,7 @@ export class OfflineService { await this.saveSlides(deckStore.state.deck); - if (deckStore.state.deck.data.background && OfflineUtils.shouldAttributeBeCleaned(deckStore.state.deck.data.background)) { + if (deckStore.state.deck.data.background && FirestoreUtils.shouldAttributeBeCleaned(deckStore.state.deck.data.background)) { deckStore.state.deck.data.background = null; } diff --git a/studio/src/app/utils/editor/firestore.utils.tsx b/studio/src/app/utils/editor/firestore.utils.tsx new file mode 100644 index 000000000..f6463296a --- /dev/null +++ b/studio/src/app/utils/editor/firestore.utils.tsx @@ -0,0 +1,24 @@ +export class FirestoreUtils { + static filterDelete(obj: T): T { + if (typeof obj !== 'object' || Array.isArray(obj)) { + return obj; + } + + return Object.keys(obj) + .filter((key) => !this.shouldAttributeBeCleaned(obj[key])) + .reduce((res, key) => ((res[key] = this.filterDelete(obj[key])), res), {} as T); + } + + static shouldAttributeBeCleaned(attr: T): boolean { + // If attr is a not an object (string, number or boolean) for sure it isn't a Firestore FieldValue.delete + if (typeof attr !== 'object' || Array.isArray(attr)) { + return false; + } + + const firestoreDelete = Object.keys(attr).find((key: string) => { + return attr[key] === 'FieldValue.delete'; + }); + + return firestoreDelete !== null && firestoreDelete !== undefined; + } +} diff --git a/studio/src/app/utils/editor/offline.utils.tsx b/studio/src/app/utils/editor/offline.utils.tsx index a830923c1..884909ae9 100644 --- a/studio/src/app/utils/editor/offline.utils.tsx +++ b/studio/src/app/utils/editor/offline.utils.tsx @@ -3,6 +3,8 @@ import * as firebase from 'firebase/app'; import {SlideAttributes} from '../../models/data/slide'; import {DeckAttributes} from '../../models/data/deck'; +import {FirestoreUtils} from './firestore.utils'; + export class OfflineUtils { static cleanAttributes(attributes: SlideAttributes | DeckAttributes): Promise { return new Promise((resolve) => { @@ -22,7 +24,7 @@ export class OfflineUtils { const attr = attributes[key]; // Replace Firestore "to delete fields" with null values - if (this.shouldAttributeBeCleaned(attr)) { + if (FirestoreUtils.shouldAttributeBeCleaned(attr)) { attributes[key] = null; } }); @@ -31,19 +33,6 @@ export class OfflineUtils { }); } - static shouldAttributeBeCleaned(attr): boolean { - // If attr is a not an object (string, number or boolean) for sure it isn't a Firestore FieldValue.delete - if (typeof attr !== 'object') { - return false; - } - - const firestoreDelete = Object.keys(attr).find((key: string) => { - return attr[key] === 'FieldValue.delete'; - }); - - return firestoreDelete !== null; - } - static prepareAttributes(attributes: SlideAttributes | DeckAttributes): Promise { return new Promise((resolve) => { if (!attributes) {