diff --git a/src/model/elemento/elemento.ts b/src/model/elemento/elemento.ts index a6b36abe..879629c4 100644 --- a/src/model/elemento/elemento.ts +++ b/src/model/elemento/elemento.ts @@ -43,4 +43,5 @@ export class Elemento extends Referencia { artigoDefinido?: string; elementoAnteriorNaSequenciaDeLeitura?: Referencia; revisao?: Revisao; + ultimoFilhoDireto?: Referencia; } diff --git a/src/model/elemento/elementoUtil.ts b/src/model/elemento/elementoUtil.ts index ec6382fc..51b3b221 100644 --- a/src/model/elemento/elementoUtil.ts +++ b/src/model/elemento/elementoUtil.ts @@ -134,6 +134,8 @@ export const createElemento = (dispositivo: Dispositivo, acoes = true, procurarE tiposAgrupadoresQuePodemSerInseridosDepois: getTiposAgrupadoresQuePodemSerInseridosDepois(dispositivo), artigoDefinido: dispositivo.artigoDefinido, elementoAnteriorNaSequenciaDeLeitura, + ultimoFilhoDireto: + isAgrupador(dispositivo) && isDispositivoAlteracao(dispositivo) && dispositivo.filhos.length ? createElemento(dispositivo.filhos[dispositivo.filhos.length - 1]) : undefined, }; }; diff --git a/src/redux/elemento/reducer/redo.ts b/src/redux/elemento/reducer/redo.ts index fad126c0..dcd91024 100644 --- a/src/redux/elemento/reducer/redo.ts +++ b/src/redux/elemento/reducer/redo.ts @@ -1,4 +1,9 @@ -import { ajustarAtributosAgrupadorIncluidoPorUndoRedo, isUndoRedoInclusaoExclusaoAgrupador, processarRestaurados } from './../util/undoRedoReducerUtil'; +import { + ajustarAtributosAgrupadorIncluidoPorUndoRedo, + ajustarHierarquivoAgrupadorIncluidoPorUndoRedo, + isUndoRedoInclusaoExclusaoAgrupador, + processarRestaurados, +} from './../util/undoRedoReducerUtil'; import { DispositivoSuprimido } from '../../../model/lexml/situacao/dispositivoSuprimido'; import { State, StateEvent, StateType } from '../../state'; import { Eventos } from '../evento/eventos'; @@ -44,16 +49,21 @@ export const redo = (state: any): State => { tempState.present = []; tempState.future = []; - if (eventos[0].stateType === StateType.ElementoIncluido) { - const ref = eventos.find((ev: StateEvent) => ev.stateType === StateType.ElementoReferenciado)!.elementos[0]; - const elementoASerIncluido = eventos[0].elementos[0]; + const listaSemEventosDeRevisao = eventos.filter( + (se: StateEvent) => ![StateType.RevisaoAceita, StateType.RevisaoRejeitada, StateType.RevisaoAdicionalRejeitada].includes(se.stateType) + ); + + if (listaSemEventosDeRevisao[0].stateType === StateType.ElementoIncluido) { + const ref = listaSemEventosDeRevisao.find((ev: StateEvent) => ev.stateType === StateType.ElementoReferenciado)!.elementos[0]; + const elementoASerIncluido = listaSemEventosDeRevisao[0].elementos[0]; tempState = agrupaElemento(tempState, { atual: ref, novo: { tipo: elementoASerIncluido.tipo, uuid: elementoASerIncluido.uuid, posicao: 'antes', manterNoMesmoGrupoDeAspas: elementoASerIncluido.manterNoMesmoGrupoDeAspas }, }); - ajustarAtributosAgrupadorIncluidoPorUndoRedo(state.articulacao, eventos, tempState.ui!.events); + ajustarAtributosAgrupadorIncluidoPorUndoRedo(state.articulacao, listaSemEventosDeRevisao, tempState.ui!.events); + ajustarHierarquivoAgrupadorIncluidoPorUndoRedo(state.articulacao, listaSemEventosDeRevisao, tempState.ui!.events); } else { - tempState = removeElemento(tempState, { atual: eventos[0].elementos[0] }); + tempState = removeElemento(tempState, { atual: listaSemEventosDeRevisao[0].elementos[0] }); } const eventosRevisao = getEventosDeRevisao(eventos); diff --git a/src/redux/elemento/reducer/undo.ts b/src/redux/elemento/reducer/undo.ts index 38534a26..aab12baf 100644 --- a/src/redux/elemento/reducer/undo.ts +++ b/src/redux/elemento/reducer/undo.ts @@ -7,6 +7,7 @@ import { processarRestaurados, processarSuprimidos, processarRevisoesAceitasOuRejeitadas, + ajustarHierarquivoAgrupadorIncluidoPorUndoRedo, } from './../util/undoRedoReducerUtil'; import { State, StateEvent, StateType } from '../../state'; import { Eventos } from '../evento/eventos'; @@ -61,6 +62,7 @@ export const undo = (state: any): State => { novo: { tipo: elementoASerIncluido.tipo, uuid: elementoASerIncluido.uuid, posicao: 'antes', manterNoMesmoGrupoDeAspas: elementoASerIncluido.manterNoMesmoGrupoDeAspas }, }); ajustarAtributosAgrupadorIncluidoPorUndoRedo(state.articulacao, eventosFiltrados, tempState.ui!.events); + ajustarHierarquivoAgrupadorIncluidoPorUndoRedo(state.articulacao, eventosFiltrados, tempState.ui!.events); } const eventosRevisao = [ diff --git a/src/redux/elemento/util/undoRedoReducerUtil.ts b/src/redux/elemento/util/undoRedoReducerUtil.ts index ebb9c1f1..a007c1dd 100644 --- a/src/redux/elemento/util/undoRedoReducerUtil.ts +++ b/src/redux/elemento/util/undoRedoReducerUtil.ts @@ -8,9 +8,11 @@ import { validaDispositivo } from '../../../model/lexml/dispositivo/dispositivoV import { buscaDispositivoById, findDispositivoByUuid, + getDispositivoAndFilhosAsLista, getDispositivoAnterior, getTiposAgrupadorArtigoOrdenados, getUltimoFilho, + isAdicionado, isArticulacaoAlteracao, isSuprimido, } from '../../../model/lexml/hierarquia/hierarquiaUtil'; @@ -313,6 +315,37 @@ export const ajustarAtributosAgrupadorIncluidoPorUndoRedo = (articulacao: Articu eventosResultantes[0].elementos!.push(createElemento(dispositivo)); }; +export const ajustarHierarquivoAgrupadorIncluidoPorUndoRedo = (articulacao: Articulacao, eventosFonte: StateEvent[], eventosResultantes: StateEvent[]): void => { + const elAgrupador = eventosFonte[0].elementos![0]; + + if (!elAgrupador.dispositivoAlteracao || !elAgrupador.ultimoFilhoDireto) { + return; + } + + const agrupador = getDispositivoFromElemento(articulacao, elAgrupador)!; + const pai = agrupador.pai!; + const ultimoFilhoDireto = getDispositivoFromElemento(articulacao, elAgrupador.ultimoFilhoDireto)!; + + let index = pai.filhos.indexOf(agrupador) + 1; + + while (index < pai.filhos.length) { + const d = pai.filhos[index]; + if (isAdicionado(d)) { + pai.removeFilho(d); + d.pai = agrupador; + agrupador.addFilho(d); + + if (d.uuid === ultimoFilhoDireto.uuid) { + break; + } + } else { + index++; + } + } + + eventosResultantes.push({ stateType: StateType.SituacaoElementoModificada, elementos: getDispositivoAndFilhosAsLista(agrupador).map(d => createElemento(d)) }); +}; + export const processarRestaurados = (state: State, evento: StateEvent, acao: string): StateEvent => { const elementoDeReferencia = evento.elementos![acao === 'UNDO' ? 0 : 1]; const d = getDispositivoFromElemento(state.articulacao!, elementoDeReferencia, true)!;