feat: edit smart view predicate as json (#2012)
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { MutationType } from '../../Abstract/Item'
|
||||
import { createSmartViewWithContent, createSmartViewWithTitle } from '../../Utilities/Test/SpecUtils'
|
||||
import { SmartViewMutator } from './SmartViewMutator'
|
||||
|
||||
describe('smart view mutator', () => {
|
||||
it('should set predicate', () => {
|
||||
const smartView = createSmartViewWithContent({
|
||||
title: 'foo',
|
||||
predicate: {
|
||||
keypath: 'title',
|
||||
operator: '=',
|
||||
value: 'foo',
|
||||
},
|
||||
})
|
||||
|
||||
const mutator = new SmartViewMutator(smartView, MutationType.UpdateUserTimestamps)
|
||||
mutator.predicate = {
|
||||
keypath: 'title',
|
||||
operator: '=',
|
||||
value: 'bar',
|
||||
}
|
||||
const result = mutator.getResult()
|
||||
|
||||
expect(result.content.predicate.value).toBe('bar')
|
||||
})
|
||||
|
||||
it('preferences should be undefined if previously undefined', () => {
|
||||
const smartView = createSmartViewWithTitle()
|
||||
const mutator = new SmartViewMutator(smartView, MutationType.UpdateUserTimestamps)
|
||||
const result = mutator.getResult()
|
||||
|
||||
expect(result.content.preferences).toBeFalsy()
|
||||
})
|
||||
|
||||
it('preferences should be lazy-created if attempting to set a property', () => {
|
||||
const smartView = createSmartViewWithTitle()
|
||||
const mutator = new SmartViewMutator(smartView, MutationType.UpdateUserTimestamps)
|
||||
mutator.preferences.sortBy = 'content_type'
|
||||
const result = mutator.getResult()
|
||||
|
||||
expect(result.content.preferences?.sortBy).toEqual('content_type')
|
||||
})
|
||||
|
||||
it('preferences should be nulled if client is reseting', () => {
|
||||
const smartView = createSmartViewWithContent({
|
||||
title: 'foo',
|
||||
preferences: {
|
||||
sortBy: 'content_type',
|
||||
},
|
||||
})
|
||||
|
||||
const mutator = new SmartViewMutator(smartView, MutationType.UpdateUserTimestamps)
|
||||
mutator.preferences = undefined
|
||||
const result = mutator.getResult()
|
||||
|
||||
expect(result.content.preferences).toBeFalsy()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,13 @@
|
||||
import { DecryptedItemInterface, MutationType } from '../../Abstract/Item'
|
||||
import { TagMutator } from '../Tag'
|
||||
import { SmartViewContent } from './SmartViewContent'
|
||||
|
||||
export class SmartViewMutator extends TagMutator<SmartViewContent> {
|
||||
constructor(item: DecryptedItemInterface<SmartViewContent>, type: MutationType) {
|
||||
super(item, type)
|
||||
}
|
||||
|
||||
set predicate(predicate: SmartViewContent['predicate']) {
|
||||
this.mutableContent.predicate = predicate
|
||||
}
|
||||
}
|
||||
@@ -2,3 +2,5 @@ export * from './SmartView'
|
||||
export * from './SmartViewBuilder'
|
||||
export * from './SystemViewId'
|
||||
export * from './SmartViewContent'
|
||||
export * from './SmartViewMutator'
|
||||
export * from './SmartViewIcons'
|
||||
|
||||
@@ -11,10 +11,10 @@ import { TagToFileReference } from '../../Abstract/Reference/TagToFileReference'
|
||||
import { TagPreferences } from './TagPreferences'
|
||||
import { DecryptedItemInterface, MutationType } from '../../Abstract/Item'
|
||||
|
||||
export class TagMutator extends DecryptedItemMutator<TagContent> {
|
||||
export class TagMutator<Content extends TagContent = TagContent> extends DecryptedItemMutator<Content> {
|
||||
private mutablePreferences?: TagPreferences
|
||||
|
||||
constructor(item: DecryptedItemInterface<TagContent>, type: MutationType) {
|
||||
constructor(item: DecryptedItemInterface<Content>, type: MutationType) {
|
||||
super(item, type)
|
||||
|
||||
this.mutablePreferences = this.mutableContent.preferences
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
import { DeletedItem } from '../../Abstract/Item/Implementations/DeletedItem'
|
||||
import { EncryptedItemInterface } from '../../Abstract/Item/Interfaces/EncryptedItem'
|
||||
import { DeletedItemInterface } from '../../Abstract/Item/Interfaces/DeletedItem'
|
||||
import { SmartViewMutator } from '../../Syncable/SmartView'
|
||||
|
||||
type ItemClass<C extends ItemContent = ItemContent> = new (payload: DecryptedPayloadInterface<C>) => DecryptedItem<C>
|
||||
|
||||
@@ -56,7 +57,7 @@ const ContentTypeClassMapping: Partial<Record<ContentType, MappingEntry>> = {
|
||||
[ContentType.ExtensionRepo]: { itemClass: SNFeatureRepo },
|
||||
[ContentType.File]: { itemClass: FileItem, mutatorClass: FileMutator },
|
||||
[ContentType.Note]: { itemClass: SNNote, mutatorClass: NoteMutator },
|
||||
[ContentType.SmartView]: { itemClass: SmartView, mutatorClass: TagMutator },
|
||||
[ContentType.SmartView]: { itemClass: SmartView, mutatorClass: SmartViewMutator },
|
||||
[ContentType.Tag]: { itemClass: SNTag, mutatorClass: TagMutator },
|
||||
[ContentType.Theme]: { itemClass: SNTheme, mutatorClass: ThemeMutator },
|
||||
[ContentType.UserPrefs]: { itemClass: SNUserPrefs, mutatorClass: UserPrefsMutator },
|
||||
|
||||
@@ -5,6 +5,7 @@ import { DecryptedPayload, PayloadSource, PayloadTimestampDefaults } from '../..
|
||||
import { FileContent, FileItem } from '../../Syncable/File'
|
||||
import { NoteContent, SNNote } from '../../Syncable/Note'
|
||||
import { SNTag } from '../../Syncable/Tag'
|
||||
import { SmartView, SmartViewContent } from '../../Syncable/SmartView'
|
||||
|
||||
let currentId = 0
|
||||
|
||||
@@ -55,6 +56,20 @@ export const createTagWithContent = (content: Partial<TagContent>): SNTag => {
|
||||
)
|
||||
}
|
||||
|
||||
export const createSmartViewWithContent = (content: Partial<SmartViewContent>): SmartView => {
|
||||
return new SmartView(
|
||||
new DecryptedPayload(
|
||||
{
|
||||
uuid: mockUuid(),
|
||||
content_type: ContentType.SmartView,
|
||||
content: FillItemContent<SmartViewContent>(content),
|
||||
...PayloadTimestampDefaults(),
|
||||
},
|
||||
PayloadSource.Constructor,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
export const createTagWithTitle = (title = 'photos') => {
|
||||
return new SNTag(
|
||||
new DecryptedPayload(
|
||||
@@ -69,6 +84,20 @@ export const createTagWithTitle = (title = 'photos') => {
|
||||
)
|
||||
}
|
||||
|
||||
export const createSmartViewWithTitle = (title = 'photos') => {
|
||||
return new SmartView(
|
||||
new DecryptedPayload(
|
||||
{
|
||||
uuid: mockUuid(),
|
||||
content_type: ContentType.SmartView,
|
||||
content: FillItemContent<SmartViewContent>({ title }),
|
||||
...PayloadTimestampDefaults(),
|
||||
},
|
||||
PayloadSource.Constructor,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
export const createFile = (name = 'screenshot.png') => {
|
||||
return new FileItem(
|
||||
new DecryptedPayload(
|
||||
|
||||
Reference in New Issue
Block a user