feat(snjs): add revisions api v2 (#2154)

* feat(snjs): add revisions api v2

* fix(snjs): reference listing and getting revisions in specs

* fix(snjs): revisions specs

* fix(web): usage of revision metadata

* fix(snjs): add specs for decryption revision

* fix(snjs): issue with building mocked specs

* fix(snjs): adjust revision creation delay
This commit is contained in:
Karol Sójko
2023-01-18 09:20:06 +01:00
committed by GitHub
parent 7d7815917b
commit 880a537774
52 changed files with 882 additions and 226 deletions

View File

@@ -1,5 +1,5 @@
import { NoteHistoryController } from '@/Controllers/NoteHistory/NoteHistoryController'
import { RevisionListEntry } from '@standardnotes/snjs'
import { RevisionMetadata } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite'
import { useCallback, useState } from 'react'
import Button from '@/Components/Button/Button'
@@ -36,7 +36,7 @@ const HistoryModalFooter = ({ dismissModal, noteHistoryController }: Props) => {
}
setIsDeletingRevision(true)
await deleteRemoteRevision(selectedEntry as RevisionListEntry)
await deleteRemoteRevision(selectedEntry as RevisionMetadata)
setIsDeletingRevision(false)
}, [deleteRemoteRevision, selectedEntry])
@@ -45,13 +45,13 @@ const HistoryModalFooter = ({ dismissModal, noteHistoryController }: Props) => {
<Button className="py-1.35" label="Close" onClick={dismissModal} />
{selectedRevision && (
<>
{(selectedEntry as RevisionListEntry).uuid && (
{(selectedEntry as RevisionMetadata).uuid && (
<Button className="md:ml-auto" onClick={deleteSelectedRevision}>
{isDeletingRevision ? <Spinner className="my-1 h-3 w-3" /> : 'Delete this revision'}
</Button>
)}
<Button
className={!(selectedEntry as RevisionListEntry).uuid ? 'md:ml-auto' : ''}
className={!(selectedEntry as RevisionMetadata).uuid ? 'md:ml-auto' : ''}
label="Restore as a copy"
onClick={restoreAsCopy}
/>

View File

@@ -4,7 +4,7 @@ import Icon from '@/Components/Icon/Icon'
import { useListKeyboardNavigation } from '@/Hooks/useListKeyboardNavigation'
import HistoryListItem from './HistoryListItem'
import { previewHistoryEntryTitle } from './utils'
import { FeaturesClientInterface, RevisionListEntry } from '@standardnotes/snjs'
import { FeaturesClientInterface, RevisionMetadata, RoleName } from '@standardnotes/snjs'
import { NoteHistoryController } from '@/Controllers/NoteHistory/NoteHistoryController'
import Spinner from '@/Components/Spinner/Spinner'
import { PremiumFeatureIconClass, PremiumFeatureIconName } from '../Icon/PremiumFeatureIcon'
@@ -46,7 +46,7 @@ const RemoteHistoryList: FunctionComponent<RemoteHistoryListProps> = ({
{group.entries.map((entry) => (
<HistoryListItem
key={entry.uuid}
isSelected={(selectedEntry as RevisionListEntry)?.uuid === entry.uuid}
isSelected={(selectedEntry as RevisionMetadata)?.uuid === entry.uuid}
onClick={() => {
void selectRemoteRevision(entry)
onSelectRevision()
@@ -54,7 +54,7 @@ const RemoteHistoryList: FunctionComponent<RemoteHistoryListProps> = ({
>
<div className="flex flex-grow items-center justify-between">
<div>{previewHistoryEntryTitle(entry)}</div>
{!features.hasMinimumRole(entry.required_role) && (
{!features.hasMinimumRole(entry.required_role as RoleName) && (
<Icon type={PremiumFeatureIconName} className={PremiumFeatureIconClass} />
)}
</div>

View File

@@ -1,5 +1,5 @@
import { DAYS_IN_A_WEEK, DAYS_IN_A_YEAR } from '@/Constants/Constants'
import { HistoryEntry, NoteHistoryEntry, RevisionListEntry } from '@standardnotes/snjs'
import { HistoryEntry, NoteHistoryEntry, RevisionMetadata } from '@standardnotes/snjs'
import { calculateDifferenceBetweenDatesInDays } from '../../Utils/CalculateDifferenceBetweenDatesInDays'
export type HistoryModalMobileTab = 'Content' | 'List'
@@ -9,14 +9,14 @@ export type LegacyHistoryEntry = {
created_at: string
}
type RevisionEntry = RevisionListEntry | NoteHistoryEntry | LegacyHistoryEntry
type RevisionEntry = RevisionMetadata | NoteHistoryEntry | LegacyHistoryEntry
export type ListGroup<EntryType extends RevisionEntry> = {
title: string
entries: EntryType[] | undefined
}
export type RemoteRevisionListGroup = ListGroup<RevisionListEntry>
export type RemoteRevisionListGroup = ListGroup<RevisionMetadata>
export type SessionRevisionListGroup = ListGroup<NoteHistoryEntry>
export const formatDateAsMonthYearString = (date: Date) => {
@@ -28,7 +28,7 @@ export const formatDateAsMonthYearString = (date: Date) => {
export const getGroupIndexForEntry = (entry: RevisionEntry, groups: ListGroup<RevisionEntry>[]) => {
const todayAsDate = new Date()
const entryDate = new Date((entry as RevisionListEntry).created_at ?? (entry as NoteHistoryEntry).payload.updated_at)
const entryDate = new Date((entry as RevisionMetadata).created_at ?? (entry as NoteHistoryEntry).payload.updated_at)
const differenceBetweenDatesInDays = calculateDifferenceBetweenDatesInDays(todayAsDate, entryDate)
@@ -81,7 +81,7 @@ export const sortRevisionListIntoGroups = <EntryType extends RevisionEntry>(revi
} else {
addBeforeLastGroup({
title: formatDateAsMonthYearString(
new Date((entry as RevisionListEntry).created_at ?? (entry as NoteHistoryEntry).payload.updated_at),
new Date((entry as RevisionMetadata).created_at ?? (entry as NoteHistoryEntry).payload.updated_at),
),
entries: [entry],
})
@@ -91,6 +91,6 @@ export const sortRevisionListIntoGroups = <EntryType extends RevisionEntry>(revi
return sortedGroups
}
export const previewHistoryEntryTitle = (revision: RevisionListEntry | LegacyHistoryEntry) => {
export const previewHistoryEntryTitle = (revision: RevisionMetadata | LegacyHistoryEntry) => {
return new Date(revision.created_at).toLocaleString()
}