Guardar resultados dinámicos
Pivotes y enriquecimiento termina con una ingesta: los candidatos elegidos están en el lienzo, etiquetados con el pivote que los trajo, y en ningún otro lugar. save es el paso atrás: el pivot escribe sus propios resultados en el sistema del que provienen y la biblioteca guarda los libros sobre lo que ha cruzado.
summarize → fetch → triage → ingest → save
"2,143" the 210 the 12 on canvas in the source systemLa biblioteca nunca escribe en ningún lugar y no tiene credenciales. Lo que aporta es la contabilidad: qué elementos creó una ejecución, si se han escrito, cuáles falló y qué debería llevarse a cabo en un reintento, porque esa es la parte que sólo él conoce.
declarando uno
const objects = {
id: 'objects',
label: 'Objects & attributes',
fetch: (nodes, narrowing, ctx) => api.objects(nodes[0].id, { signal: ctx.signal }),
save: async ({ origin, nodes, children, edges }, ctx) => {
const written = await api.createObjects(origin[0].id, [...nodes, ...children], {
signal: ctx.signal,
})
return {
savedNodeIds: written.ok.map(o => o.localId),
savedEdgeIds: edges.map(e => e.id),
canonicalIds: Object.fromEntries(written.ok.map(o => [o.localId, o.uuid])),
message: written.failed.length ? `${written.failed.length} refused` : undefined,
}
},
}La carga útil son objetos de gráficos en vivo, no fragmentos sin formato:
| campo | lo que contiene |
|---|---|
origin | en qué se ejecutó el pivote: "a qué evento se adjunta esto" |
nodes | Los nodos que creó esta ejecución. |
children | contenido del contenedor añadido con unión, aplanado; cada uno accesible desde su contenedor a través de parentNode |
edges | los bordes que esta carrera creó |
vouched | Lo que ya estaba en el lienzo antes de esta carrera. |
attempt | 1 la primera vez, más alto en un reintento |
Omita save y los resultados del pivote son no se pueden guardar. Nunca ingresan al libro mayor, son nunca se cuentan como no guardados y no aparece ningún Guardar para ellos. Ésa es la declaración correcta para un pivote sobre los datos derivados (la salida de un motor de correlación no es suya para escribirla) y es lo que detiene un permanente "210 no salvo" sin remedio.
lo que regresas
| Devuelto | Medios |
|---|---|
undefined / true | toda la carga útil fue escrita |
false, o tirar | nada de eso lo era; el error llega al brindis de reintento |
{ savedNodeIds, savedEdgeIds } | una escritura parcial: todo lo que no tenga nombre no se guarda |
{ canonicalIds } | identifica el sistema fuente asignado, codificado por la identificación local |
{ message } | se muestra textualmente en el brindis resultante |
{ cancelled: true } | el analista se echó atrás: nada registrado, ni brindis, ni intento |
savedNodeIds cubre nodes y children juntos. Una identificación que nombra un elemento que hizo esta ejecución. no crear se ignora: un pivot nunca escribe lo que no produjo, por lo que no puede informarlo escrito tampoco.
Un guardado que informa un borde escrito pero no los nodos que conecta se toma al pie de la letra. Lo que el sistema fuente dice que escribió no es algo que la biblioteca pueda anular.
Preguntar primero al analista
Una escritura a veces necesita una respuesta antes de poder enviarse, como qué relación une a cada uno. resultado al nodo desde el que se enriqueció. ctx.promptData abre el propio modal de la biblioteca, con las mismas opciones que la que está detrás de la creación de nodos y bordes: declarativa fields, o render + getValues para el tuyo HTML. Se resuelve en los valores, o null al cancelar.
save: async (payload, ctx) => {
const answer = await ctx.promptData({
fields: [{ key: 'relationship', label: 'Relationship', type: 'text', defaultValue: 'related-to' }],
})
if (!answer) return { cancelled: true }
await api.attach(payload, answer.relationship, { signal: ctx.signal })
},El modal se titula y se envía con Guardar a menos que title y submitLabel digan de lo contrario. Regresar { cancelled: true } deja la carrera exactamente como estaba antes de la haga clic en: aún sin guardar, sin notificación, sin reintentar y el siguiente intento sigue siendo attempt: 1. un ahorro durante varias ejecuciones se detiene en la primera cancelación y el informe lo cuenta en cancelled más que como un fracaso. Un reintento cancelado devuelve el brindis a su estado original.
Solo un guardado en el que alguien hizo clic puede preguntar. Guardar del panel Pivote, Guardar del panel Revisar y el pase de reintento del brindis interactive: true; autoSave y un simple graph.pivots.save() hacer no, por lo que su promptData resuelve null de inmediato sin sacar nada. Un anfitrión con un Guardar El botón propio también pasa la bandera:
await graph.pivots.save(undefined, { interactive: true })pidiendo uno
await graph.pivots.save() // every savable run with something still unsaved
await graph.pivots.save(runId) // one run
await graph.pivots.save(pivotId) // every unsaved run of one pivot
graph.pivots.unsaved() // the runs still waiting
graph.pivots.unsavedCount() // { nodes, edges } — exact, not advisory
graph.pivots.unsavedCount(pivotId) // one pivot's share of it
graph.pivots.isSaved(node) // false for the unsaved *and* the not-savable
graph.pivots.isSavable(node) // which of those two it isparte de una carrera
const selected = graph.renderer.getGraphInteraction().getSelectedNodeIDs() ?? []
await graph.pivots.save({ elements: selected }) // Nodes, Edges or their idsA cada ejecución que creó uno de los elementos nombrados se le pregunta una vez, con una carga útil reducida a lo que se nombró. Un nodo con nombre trae los hijos pendientes debajo de él y aparece una ventaja cuando se nombra un extremo y el otro también se nombra o no quedará sin escribir: el origen, un nodo ya guardado, cualquier cosa que el libro mayor no esté esperando. Una ventaja para un pendiente el nodo excluido se queda con él, por lo que una escritura nunca envía una línea a nada. Nombrado Los elementos que no están esperando se ignoran y la llamada recibe un brindis por cada ejecución. preguntó.
El resto queda pendiente, y cuenta, Reintentar y canonicalIds funcionan como lo hacen durante todo un correr. Una ejecución se marca como persistente en el historial solo cuando no queda nada por escribir. isSavable(el) y isSaved(el) indican si una entrada de menú como Guardar seleccionada tiene cualquier cosa que hacer.
Las ejecuciones se realizan de una en una y a cada una se le envía solo lo que aún no se ha guardado, por lo que volver a intentarlo es lo mismo. llamar. El resultado llega como un brindis: Saved 12 nodes, o Saved 9 of 12 con un Reintentar que se hace cargo de esa misma tostada en lugar de apilar una segunda.
En la interfaz de usuario, el recuento y el botón se encuentran al pie del panel Pivote y en un panel Revisar. lleva la participación de su propio proveedor en su encabezado. No aparece nada mientras el número sea cero.
Ambos escriben todo lo pendiente, sin forma de escoger. Una aplicación que ofrece ahorro en otro lugar, como una entrada Guardar seleccionado en el menú del nodo, puede desactivarlos:
new Pivotick(el, data, { pivots: [objects], pivotSaveControls: false })
graph.pivots.saveControls = true // and back, at runtimeSolo van los dos mandos. El libro mayor, los recuentos, save(...), su brindis y reintento, y canonicalIds trabajar como antes.
autoSave: true escribe cada ejecución en el momento en que aterriza, sin ningún gesto. Corre tras el ingerir se resuelve en lugar de dentro de él, por lo que un backend lento nunca sostiene el lienzo, y un informa de fallas a través del notificador y deja los datos donde están. Combínalo con autoIngest: true para un pivote que no intervenga de un extremo a otro: expandir un evento a objetos que ya son propios de la fuente.
Identifica el sistema fuente mints
Guardar generalmente crea algo, y lo creado generalmente obtiene una identificación de la fuente elección del sistema, no la que utilizó su proveedor cuando era candidato. la carrera de mañana luego devuelve los mismos objetos bajo identificadores que dedup no reconoce, y el analista obtiene doce Duplicados de lo que guardaron ayer.
Devuelve canonicalIds y la biblioteca conserva el alias. Ingest dedup, la unión de los niños y Todos los puntos finales de Edge lo consultan, por lo que la repetición dice 12 ya en el lienzo.
graph.pivots.canonicalId(node) // 'a1b2…' — the id the source assignedPor qué el nodo mantiene la identificación con la que aterrizó
La nueva clave alcanzaría los bordes, los grupos, la selección, el motor de consulta, la procedencia y el historia, para un beneficio el alias ya entrega donde importa. El costo honesto: graph.getNode(canonicalId) todavía falla y canonicalId() es la lectura que no.
Deshacer no llega al sistema fuente
Al deshacer una ejecución guardada se eliminan sus nodos del lienzo. no elimina nada de el sistema en el que fueron escritos, y la biblioteca no emite escrituras de compensación: deshacer un La vista local no es una transacción entre dos sistemas.
La historia lo dice en lugar de dejar que usted lo descubra: una tirada marcada como escrita es desconchado guardado, y el pie de página del menú cuenta lo que dejaría un lapso. PivotRun lleva un conteo saved para una superficie que quiere avisar antes del clic. Ver Deshacer e historial para saber cómo trata una entrada persistente.
Una salvada fallida tampoco toca la lona. El analista aceptó esos doce nodos; un El rechazo del backend es información sobre el backend, no una revocación de su decisión. ellos permanecer, permanecer sin guardar y permanecer reintentable.
Marcar nodos no guardados
new Pivotick(el, data, { pivots: [objects], pivotMarkUnsaved: true })Pone una clase pvt-node-unsaved en cada nodo creado por una ejecución y que no se ha reescrito, lo que una hoja de estilo puede funcionar; el valor predeterminado es un borde discontinuo. Desactivado de forma predeterminada y una clase en lugar de que una insignia de borde: un nodo tiene cuatro esquinas de borde y solo dos una vez que tiene hijos, y una Un marcador que saca del aro un potencial declarado cuesta más de lo que dice.