Skip to content

Commit 092cc8f

Browse files
committed
feat(MONIT-87):"Agregar advertencia en edicion de elementos rup"
1 parent ef3ccbb commit 092cc8f

2 files changed

Lines changed: 88 additions & 59 deletions

File tree

src/app/rupers/components/molecula-create-update/molecula-create-update.component.html

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,46 +11,46 @@
1111
<div class="grow">
1212

1313

14-
<plex-select label="Concepto" [multiple]="true" (getData)=searchConcept($event) [(ngModel)]="conceptos"
15-
idField="conceptId" labelField="term + '(' + semanticTag + ')'" required="true">
14+
<plex-select label="Concepto" [multiple]="true" (getData)="searchConcept($event)" [(ngModel)]="conceptos"
15+
(ngModelChange)="onConceptosChange($event)" idField="conceptId"
16+
labelField="term + ' (' + semanticTag + ')'" required="true">
1617
</plex-select>
17-
1818
</div>
1919
<div class="row">
2020
<div class="col-12">
2121
<plex-title titulo="Moléculas y átomos vinculados"></plex-title>
2222
<div class="grow">
2323
<plex-select label="Concepto" (getData)=searchConcept($event) [(ngModel)]="requerido"
24-
idField="conceptId" labelField="term + '(' + semanticTag + ')'"></plex-select>
24+
idField="conceptId" labelField="term + '(' + semanticTag + ')'"></plex-select>
2525

2626
<plex-button class="align-self-end" type="success" icon="check" (click)="onAddRequerido()"
27-
[disabled]="!requerido?.conceptId">
27+
[disabled]="!requerido?.conceptId">
2828
</plex-button>
2929

3030

3131
</div>
3232
<plex-list>
3333
<plex-item
34-
*ngFor="let requerido of elemento.requeridos;let i = index; let first$ = first; let last$ = last">
34+
*ngFor="let requerido of elemento.requeridos;let i = index; let first$ = first; let last$ = last">
3535
<plex-label [titulo]="requerido.concepto.conceptId"></plex-label>
3636
<plex-label [titulo]="requerido.concepto.term" [tituloBold]="false"></plex-label>
3737

3838
<plex-label [titulo]="getComponente(requerido.concepto)" [tituloBold]="false"></plex-label>
3939

4040

4141
<plex-button size="sm" tooltip="Editar" type="warning" icon="pencil"
42-
(click)="abrirMolecula(requerido)">
42+
(click)="abrirMolecula(requerido)">
4343

4444
</plex-button>
4545
<plex-button tooltip="Eliminar" type="danger" icon="delete" size="sm"
46-
(click)="onRemoveRequerido(i)"></plex-button>
46+
(click)="onRemoveRequerido(i)"></plex-button>
4747
<ng-container ngProjectAs="plex-button">
4848
<div class="d-flex flex-column">
4949
<plex-button type="info" icon="flecha-arriba" size="sm" (click)="onUpRequerido(i)"
50-
*ngIf="!first$">
50+
*ngIf="!first$">
5151
</plex-button>
5252
<plex-button type="info" icon="flecha-abajo" size="sm" (click)="onDownRequerido(i)"
53-
*ngIf="!last$">
53+
*ngIf="!last$">
5454
</plex-button>
5555
</div>
5656
</ng-container>
@@ -68,25 +68,26 @@
6868
<plex-layout-sidebar type="invert" *ngIf="moleculaSeleccionado" class="sidebar-fijo">
6969
<plex-title justify [titulo]="'EDITAR ' + (tituloSidebar || '-')" size="sm">
7070
<plex-button size="sm" tooltip="Aceptar" type="success" (click)="confirmarMolecula()"
71-
icon="check"></plex-button>
71+
icon="check"></plex-button>
7272
<plex-button type="danger" size="sm" icon="close" ariaLabel="cerrar panel lateral" tooltip="Cerrar"
73-
(click)="moleculaSeleccionado = null; tituloSidebar = ''">
73+
(click)="moleculaSeleccionado = null; tituloSidebar = ''">
7474
</plex-button>
7575
</plex-title>
7676
<div class="grow">
7777

7878
<plex-select label="Nombre orientativo"
79-
[data]="moleculaSeleccionado?.concepto ? [moleculaSeleccionado.concepto] : []"
80-
[ngModel]="moleculaSeleccionado?.concepto" [disabled]="true" labelField="term" idField="conceptId"
81-
required="true">
79+
[data]="moleculaSeleccionado?.concepto ? [moleculaSeleccionado.concepto] : []"
80+
[ngModel]="moleculaSeleccionado?.concepto" [disabled]="true" labelField="term"
81+
idField="conceptId" required="true">
8282
</plex-select>
8383

8484
</div>
8585
<div class="grow">
8686
<plex-select label="Concepto"
87-
[data]="moleculaSeleccionado?.conceptos || (moleculaSeleccionado?.concepto ? [moleculaSeleccionado.concepto] : [])"
88-
[ngModel]="getConceptoSeleccionado()" (ngModelChange)="setConceptoSeleccionado($event)"
89-
[disabled]="true" idField="conceptId" labelField="term + ' (' + semanticTag + ')'" required="true">
87+
[data]="moleculaSeleccionado?.conceptos || (moleculaSeleccionado?.concepto ? [moleculaSeleccionado.concepto] : [])"
88+
[ngModel]="getConceptoSeleccionado()" (ngModelChange)="setConceptoSeleccionado($event)"
89+
[disabled]="true" idField="conceptId" labelField="term + ' (' + semanticTag + ')'"
90+
required="true">
9091
</plex-select>
9192

9293

@@ -95,7 +96,7 @@
9596

9697

9798
<plex-select label="Tipo de Atomo" [data]="tipoAtomos" [ngModel]="tipoAtomo" [disabled]="true"
98-
labelField="nombre" valueField="id" required="true">
99+
labelField="nombre" valueField="id" required="true">
99100
</plex-select>
100101
</div>
101102

@@ -111,39 +112,39 @@
111112

112113
<div class="ml-4 mt-5">
113114
<plex-bool type="slide" [(ngModel)]="params.multiple" label="Multiple"
114-
name="params-multiple"></plex-bool>
115+
name="params-multiple"></plex-bool>
115116
<plex-bool type="slide" [(ngModel)]="params.required" label="Requerido"
116-
name="params-required"></plex-bool>
117+
name="params-required"></plex-bool>
117118
<plex-text [(ngModel)]="params.allowOtherQuery" label="Otros Snomed Query"
118-
name="params-query-otros"></plex-text>
119+
name="params-query-otros"></plex-text>
119120

120121
<plex-radio label="Horientacion" [(ngModel)]="params.type" [data]="checkOrientacionType"
121-
type="horizontal" name="params-type"></plex-radio>
122+
type="horizontal" name="params-type"></plex-radio>
122123
</div>
123124
</div>
124125

125126
<div *ngSwitchCase="'ValorNumericoComponent'">
126127

127128
<plex-grid type="full" size="sm" class="plex-dark">
128129
<plex-int [ngModel]="params.min" (ngModelChange)="params.min = $event" label="Mínimo"
129-
name="params-min"></plex-int>
130+
name="params-min"></plex-int>
130131
<plex-int [ngModel]="params.max" (ngModelChange)="params.max = $event" label="Máximo"
131-
name="params-max"></plex-int>
132+
name="params-max"></plex-int>
132133
<plex-text [ngModel]="params.unit || ''" (ngModelChange)="params.unit = $event" label="Unidad"
133-
name="params-unit"></plex-text>
134+
name="params-unit"></plex-text>
134135
</plex-grid>
135136
<plex-text [ngModel]="params.title || ''" (ngModelChange)="params.title = $event" label="Titulo"
136-
name="params-title">
137+
name="params-title">
137138
</plex-text>
138139
<plex-radio [(ngModel)]="params.numericType" [data]="valorNumericoType" name="params-type"></plex-radio>
139140
</div>
140141

141142
<div *ngSwitchCase="'ObservacionesComponent'">
142143
<plex-text [ngModel]="params.title || ''" (ngModelChange)="params.title = $event" label="Titulo"
143-
name="params-title">
144+
name="params-title">
144145
</plex-text>
145146
<plex-bool class="ml-2 mt-3" type="slide" [(ngModel)]="params.required" label="Requerido"
146-
name="params-required">
147+
name="params-required">
147148
</plex-bool>
148149

149150
</div>
@@ -158,14 +159,14 @@
158159
<plex-bool type="slide" [(ngModel)]="params.required" label="Requerido" name="params-required">
159160
</plex-bool>
160161
<plex-bool type="slide" [(ngModel)]="params.allowOther" label="Texto libre"
161-
name="params-allowOther">
162+
name="params-allowOther">
162163
</plex-bool>
163164
<plex-bool type="slide" [(ngModel)]="params.preload" label="Precarga los datos"
164-
name="params-preload">
165+
name="params-preload">
165166
</plex-bool>
166167
</div>
167168
<plex-text [ngModel]="params.title || ''" (ngModelChange)="params.title = $event" label="Titulo"
168-
name="params-title">
169+
name="params-title">
169170
</plex-text>
170171
</div>
171172

@@ -179,14 +180,14 @@
179180
<plex-bool type="slide" [(ngModel)]="params.required" label="Requerido" name="params-required">
180181
</plex-bool>
181182
<plex-bool type="slide" [(ngModel)]="params.allowOther" label="Texto libre"
182-
name="params-allowOther">
183+
name="params-allowOther">
183184
</plex-bool>
184185
<plex-bool type="slide" [(ngModel)]="params.preload" label="Precarga los datos"
185-
name="params-preload">
186+
name="params-preload">
186187
</plex-bool>
187188
</div>
188189
<plex-text [ngModel]="params.title || ''" (ngModelChange)="params.title = $event" label="Titulo"
189-
name="params-title">
190+
name="params-title">
190191
</plex-text>
191192

192193
</div>
@@ -195,7 +196,7 @@
195196
<div *ngSwitchCase="'SelectSnomedComponent'">
196197

197198
<plex-text [ngModel]="params.title || ''" (ngModelChange)="params.title = $event" label="Titulo"
198-
name="params-title">
199+
name="params-title">
199200
</plex-text>
200201
<plex-text [(ngModel)]="params.query" label="Snomed Query" name="params-query"></plex-text>
201202

@@ -205,10 +206,10 @@
205206
<plex-bool type="slide" [(ngModel)]="params.required" label="Requerido" name="params-required">
206207
</plex-bool>
207208
<plex-bool type="slide" [(ngModel)]="params.allowOther" label="Texto libre"
208-
name="params-allowOther">
209+
name="params-allowOther">
209210
</plex-bool>
210211
<plex-bool type="slide" [(ngModel)]="params.preload" label="Precarga los datos"
211-
name="params-preload">
212+
name="params-preload">
212213
</plex-bool>
213214
</div>
214215

src/app/rupers/components/molecula-create-update/molecula-create-update.component.ts

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export class RUPMoleculaCreateUpdateComponent implements OnInit {
6161
this.elementosRup = elementosRup;
6262
if (this.id) {
6363
this.elemento = this.elementosRup.find(e => e.id === this.id);
64-
this.conceptos = [...(this.elemento.conceptos || [])];
6564
this.params = { ...this.elemento.params };
6665
this.items = this.params.items ? [...this.params.items] : [];
6766
this.tipoAtomo = this.tipoAtomos.find(t => t.id === this.elemento.componente) || null;
@@ -125,48 +124,77 @@ export class RUPMoleculaCreateUpdateComponent implements OnInit {
125124

126125
@Unsubscribe()
127126
searchConcept($event) {
128-
if ($event.query.length > 3) {
129-
const query = {
130-
search: $event.query
131-
};
132-
127+
if ($event.query && $event.query.length > 3) {
128+
const query = { search: $event.query };
133129
this.snomedService.get(query).subscribe((conceptos: ISnomedConcept[]) => {
134-
$event.callback(conceptos);
130+
const conceptosValidos = (conceptos || []).filter(c => !!c && !!c.conceptId);
131+
const fusion = [
132+
...this.conceptos,
133+
...conceptosValidos.filter(c => !this.conceptos.some(sel => sel.conceptId === c.conceptId))
134+
];
135+
136+
$event.callback(fusion);
135137
});
136138
} else {
137-
$event.callback([]);
139+
$event.callback(this.conceptos || []);
138140
}
139141
}
142+
onConceptosChange(event) {
143+
this.conceptos = (event || []).filter(c => !!c);
144+
}
140145
onSave() {
141146
this.elemento.nombre = this.nombre;
147+
148+
if (!this.conceptos || this.conceptos.length === 0) {
149+
this.plex.toast('danger', 'La molécula debe tener al menos un concepto.');
150+
return;
151+
}
152+
142153
this.elemento.conceptos = [...this.conceptos];
143-
const conceptosIds = this.conceptos.map(c => String(c.conceptId));
154+
const conceptosIdsSeleccionados = this.conceptos
155+
.map(c => String(c.conceptId))
156+
.filter(id => !!id);
157+
144158
const conceptoDuplicado = this.elementosRup
145159
.filter(e => e.id !== this.id)
146-
.map(e => e.conceptos || [])
147-
.reduce((acc, val) => acc.concat(val), [])
148-
.find(c => conceptosIds.includes(String(c.conceptId)));
149-
160+
.reduce((acc, e) => acc.concat(e.conceptos || []), [])
161+
.find(c => conceptosIdsSeleccionados.includes(String(c.conceptId)));
150162
if (conceptoDuplicado) {
151-
this.plex.toast(
152-
'danger',
153-
`El concepto "${conceptoDuplicado.term}" ya existe en otra molécula`
154-
);
163+
const rupersDuplicados = this.elementosRup
164+
.filter(e =>
165+
e.id !== this.id &&
166+
(e.conceptos || []).some(c => String(c.conceptId) === String(conceptoDuplicado.conceptId))
167+
);
168+
169+
const nombresRuper = rupersDuplicados.map(e => `<b>${e.nombre}</b>`).join('; ') || 'desconocido';
170+
171+
this.plex.confirm(
172+
`⚠️ El concepto "${conceptoDuplicado.fsn}" ya existe en los Ruper: ${nombresRuper}.<br>¿Deseas igualmente agregarlo aquí?`,
173+
'Concepto duplicado'
174+
).then(confirmado => {
175+
if (confirmado) {
176+
this.guardarMolecula();
177+
} else {
178+
this.plex.toast('info', 'Operación cancelada por el usuario');
179+
}
180+
});
155181
return;
182+
} else {
183+
this.guardarMolecula();
156184
}
157-
// Guardá la molécula completa (incluye todos los requeridos y sus params actualizados)
185+
}
186+
187+
guardarMolecula() {
158188
this.elementosRUPService.save(this.elemento).subscribe(
159189
() => {
160190
this.plex.toast('success', 'Molécula guardada correctamente');
161-
this.router.navigate(['/rupers/elementos-rup'], { replaceUrl: true }); // 👈 redirige como antes
162-
191+
this.router.navigate(['/rupers/elementos-rup'], { replaceUrl: true });
163192
},
164193
(err) => {
165194
this.plex.toast('danger', 'Error al guardar la molécula');
166195
}
167196
);
168197
}
169-
170198
volver() {
171199
this.router.navigate(['/rupers/elementos-rup'], { replaceUrl: true });
172200
}

0 commit comments

Comments
 (0)