import { useEffect } from 'react'
import {
  pug,
  styl,
  $root,
  useDoc,
  useModel,
  useSession,
  useValue
} from 'startupjs'
import { Div, Span, Button, TextInput } from '@startupjs/ui'

# Редактирование

```jsx example
const docId = 'a2205406-7de4-43a4-8b73-48ea23a8aaab'
const [doc, $doc] = useDoc('temp', docId)

useEffect(()=> {
  if (doc) return
  $root.at('temp').add({ id: docId, title: 'Title', message: 'Message' })
}, [])

return pug`
  Span Создание тестового документа, для демонстрации примеров, если его не существует
`
```

В нашем фреймворке по-умолчанию все данные обновляются реалтайм.
В основном нет зваимодействия, когда какие-то данные получают с сервера статично, т.е. отправил запрос, получил что-то один раз из бд и работаешь с этим.
Зачастую, если что-то меняется в бд, изменения сразу же отображаются на клиенте у юзера.

Простой пример:

Возьмем созданный документ для примеров и input который меняет значение title в документе
Если попробывать что-то ввести, то title в Span будет обновлятся сразу же

```jsx example
const docId = 'a2205406-7de4-43a4-8b73-48ea23a8aaab'
const [doc = {}, $doc] = useDoc('temp', docId)

return pug`
  Span= doc.title
  TextInput.input(
    placeholder='Title'
    value=doc.title
    onChangeText=t=> $doc.set('title', t)
  )
`

styl`
  .input
    margin-top 1u
`
```

Иногда встречаются такие кейсы, где такое поведение не нужно, и обновление данных в документе должно происходит целеком, к примеру после нажания на кнопку "Сохранить"

## Локальная копия документа

Пример показывает что данные изменяются уже не сразу, и их ввод сбрасывается после обновления страницы
Если вводить данные, то Span`ы меняться уже не будут
Изменения произойдут после сохранения скопированного объекта в doc

Реализуется это с помощью дополнительного стейта (черновика), который полностью клонирует содержимое документа (нужно именно клонировать документ, к примеру через spread, а не задавать в состояние ссылку на объект)

```jsx example
const docId = 'a2205406-7de4-43a4-8b73-48ea23a8aaab'
const [doc = {}, $doc] = useDoc('temp', docId)
const [draft, $draft] = useValue({ ...doc })

function onSubmit () {
  $doc.setDiffDeep(draft)
}

return pug`
  Div
    Span= doc.title
    Span.line= doc.message

  Div
    TextInput.line(
      placeholder='Title'
      value=draft.title
      onChangeText=t=> $draft.set('title', t)
    )

    TextInput.line(
      placeholder='Message'
      value=draft.message
      onChangeText=t=> $draft.set('message', t)
    )

    Button(
      variant='flat'
      onPress=onSubmit
    ) Сохранить
`

styl`
  .line
    margin-bottom 1u
`
```

## Документ-черновик

Если же все введенные данные юзером при перезагрузке страницы не должны потеряться, для этого можно создать в бд документ-черновик
Как правило такие черновики нужно создать отдельно в коде и задавать им id напрямую, с перечеслением скоупов, например:

`draft__27d222d5-db49-4788-ab2e-79f9371aedb9__a2205406-7de4-43a4-8b73-48ea23a8aaab`

id любого draft`а должен начинаться с приставки 'draft', далее как правильно id юзера (чтобы разные юзеры не ссылались на один и тот же черновик в итоге), и после id самого документа

```jsx example
const userId = useSession('userId')
const docId = 'a2205406-7de4-43a4-8b73-48ea23a8aaab'
const draftId = `draft__${userId}__${docId}`

const [doc, $doc] = useDoc('temp', docId)
const [draft, $draft] = useDoc('temp', draftId)
const $temp = useModel('temp')

useEffect(()=> {
  if (draft) return
  $temp.add({ ...doc, id: draftId })
}, [])

function onSubmit () {
  $doc.setDiffDeep(draft)
}

if (!draft) return null
return pug`
  Div
    Span= doc.title
    Span.line= doc.message

  Div
    TextInput.line(
      placeholder='Title'
      value=draft.title
      onChangeText=t=> $draft.set('title', t)
    )

    TextInput.line(
      placeholder='Message'
      value=draft.message
      onChangeText=t=> $draft.set('message', t)
    )

    Button(
      variant='flat'
      onPress=onSubmit
    ) Сохранить
`

styl`
  .line
    margin-bottom 1u
`
```

## Так же
При сохранении документа важно использовать - `.setDiffDeep(draft)`, вместо `.set({ ...draft })`, чтобы в sharedb вместо генерации операции на замену всего документа, создавались операции на точечное изменение только того, что реально изменилось

Это еще важно для того, чтобы `observer` триггерил изменения для минимального количества компонентов, использующих какие-то данные из этого документа

Например, 2 юзера подписались на разные поля в одном и том же документе
При - `.set({ ...draft })`, независимо какое поле изменилось, ререндер на клиенте произойдет у всех юзеров
Если же делать - `.setDiffDeep(draft)`, ререндер будет происходит точетно только там где было задействованы поля которые изменились
