Guide

Commenti ancorati

Come WikiEditor ancora un commento al testo selezionato, ne evidenzia gli aperti e li segna nel margine destro, in modifica e in sola lettura.

Il modello

Il commento è del modulo: testo, autore, risposte, stato e salvataggio stanno nel suo database. L'editor si occupa solo dell'ancora, cioè del punto del testo a cui il commento si riferisce:

  • l'ancora è un mark nel contenuto, <span data-commento="ancora">testo</span>, e viaggia con il contenuto salvato;
  • lo stato del commento (aperto o risolto) non è nel contenuto: arriva dalla prop commenti.

Così un commento risolto non richiede di modificare la pagina, e il testo ancorato resta al suo posto anche se attorno si scrive.

Abilitare i commenti

I commenti si abilitano passando la prop commenti, anche vuota. Senza prop la barra sulla selezione non offre «Commenta» e il margine non c'è.

interface CommentoAncorato {
  id: string       // id del commento nel modulo
  ancora: string   // valore di data-commento (la colonna codancora)
  aperto: boolean  // aperto = evidenziato e segnato nel margine
}

Il flusso

  1. L'utente seleziona del testo e sceglie Commenta nella barra sulla selezione (AC-092).
  2. L'editor genera un'ancora nuova, la applica alla selezione ed emette commenta:
    interface SelezioneCommento {
      testo: string   // testo selezionato (la colonna selezionetesto)
      ancora: string  // ancora appena applicata, al massimo 64 caratteri
      html: string    // contenuto con l'ancora applicata
    }
    
  3. Il modulo apre il suo form. Se l'utente salva, il modulo registra il commento con ancora e lo aggiunge a commenti; se annulla, chiama rimuoviAncora(ancora).
  4. Il testo delle ancore dei commenti aperti è evidenziato in giallo e ogni commento aperto ha un indicatore nel margine destro, all'altezza della sua ancora (AC-093). Gli indicatori vicini si spostano in basso per non sovrapporsi.
  5. Il clic su un indicatore porta in vista il testo ancorato ed emette apriCommento(id): il modulo apre il commento nel suo pannello.
  6. Quando il commento viene risolto, il modulo mette aperto: false: evidenziazione e indicatore spariscono, l'ancora resta nel contenuto. Se lo elimina, può togliere l'ancora con rimuoviAncora.
<script setup lang="ts">
import { ref } from 'vue'
import { WikiEditor, type CommentoAncorato, type SelezioneCommento } from '@pzeta/vue-wiki'

const wiki = ref<InstanceType<typeof WikiEditor> | null>(null)
const commenti = ref<CommentoAncorato[]>([])
const inCorso = ref<SelezioneCommento | null>(null)

const onCommenta = (selezione: SelezioneCommento) => {
  inCorso.value = selezione // apre il form del modulo
}

const salva = async (testoCommento: string) => {
  const s = inCorso.value
  if (!s) return
  const id = await commentiService.crea({
    testo: testoCommento,
    selezionetesto: s.testo,
    codancora: s.ancora,
  })
  commenti.value = [...commenti.value, { id: String(id), ancora: s.ancora, aperto: true }]
  inCorso.value = null
}

const annulla = () => {
  if (inCorso.value) wiki.value?.rimuoviAncora(inCorso.value.ancora)
  inCorso.value = null
}
</script>

<template>
  <WikiEditor
    ref="wiki"
    v-model="contenuto"
    :commenti="commenti"
    @commenta="onCommenta"
    @apri-commento="(id) => pannelloCommenti.apri(id)"
  />
</template>

Prova

L'editor è in sola lettura e ha già un commento aperto. Seleziona un'altra parte del testo e scegli Commenta: il commento si aggiunge all'elenco e il suo indicatore compare nel margine. Risolvi toglie evidenziazione e indicatore; il clic su un indicatore emette apriCommento.

In modifica e in sola lettura

In modificaIn sola lettura
«Commenta» sulla selezioneSì, insieme alla formattazioneSì, da solo
L'ancora entra nel contenutoSìSì, nella pagina mostrata
update:modelValueEmesso, come per ogni modificaNon emesso
Come salvare l'ancoraCon il salvataggio del contenutoCon html del payload di commenta, se l'utente può farlo

In sola lettura l'ancora vive solo nella pagina mostrata finché il modulo non salva html. Se il modulo non lo salva, il commento resta valido ma senza ancora: non compare nel margine, e il modulo può mostrarlo nel suo pannello con il testo citato (selezionetesto).

Dettagli

  • Ancore: sono crypto.randomUUID() (36 caratteri; fuori da un contesto sicuro, http senza localhost, un identificativo casuale più corto), sempre entro i 64 caratteri di codancora.
  • Sovrapposizioni: due commenti possono ancorarsi allo stesso testo o a testi che si sovrappongono; ognuno ha il proprio <span>.
  • Bordi: chi scrive subito prima o subito dopo il testo ancorato non allunga l'ancora.
  • Codice: dentro un blocco di codice non si commenta (la barra non compare).
  • Ancore orfane: un'ancora senza commento in commenti non è evidenziata e non ha indicatore.