@@ -10,6 +10,7 @@ import sanitizeHtml from 'sanitize-html'
1010import debounce from 'debounce' ;
1111import type { AdminForthResourceColumnInputCommon , Predicate } from '@/types/Common' ;
1212import { i18nInstance } from '../i18n'
13+ import { useI18n } from 'vue-i18n' ;
1314
1415
1516
@@ -524,9 +525,10 @@ export function atob_function(source: string): string {
524525 return atob ( source ) ;
525526}
526527
527- export function compareOldAndNewRecord ( oldRecord : Record < string , any > , newRecord : Record < string , any > ) : boolean {
528+ export function compareOldAndNewRecord ( oldRecord : Record < string , any > , newRecord : Record < string , any > ) : { ok : boolean , changedFields : Record < string , { oldValue : any , newValue : any } > } {
528529 const newKeys = Object . keys ( newRecord ) ;
529530 const coreStore = useCoreStore ( ) ;
531+ const changedColumns : Record < string , { oldValue : any , newValue : any } > = { } ;
530532
531533 for ( const key of newKeys ) {
532534 const oldValue = typeof oldRecord [ key ] === 'object' && oldRecord [ key ] !== null ? JSON . stringify ( oldRecord [ key ] ) : oldRecord [ key ] ;
@@ -537,30 +539,63 @@ export function compareOldAndNewRecord(oldRecord: Record<string, any>, newRecord
537539 oldValue === undefined ||
538540 oldValue === null ||
539541 oldValue === '' ||
540- ( Array . isArray ( oldValue ) && oldValue . length === 0 )
542+ ( Array . isArray ( oldValue ) && oldValue . length === 0 ) ||
543+ oldValue === '[]'
541544 )
542545 &&
543546 (
544547 newValue === undefined ||
545548 newValue === null ||
546549 newValue === '' ||
547- ( Array . isArray ( newValue ) && newValue . length === 0 )
550+ ( Array . isArray ( newValue ) && newValue . length === 0 ) ||
551+ newValue === '[]'
548552 )
549553 ) {
550554 // console.log(`Value for key ${key} is considered equal (empty)`)
551555 continue ;
552556 }
553557
554- const column = coreStore . resource . columns . find ( ( c ) => c . name === key ) ;
558+ const column = coreStore . resource ? .columns . find ( ( c ) => c . name === key ) ;
555559 if ( column ?. foreignResource ) {
556560 if ( newRecord [ key ] === oldRecord [ key ] ?. pk ) {
557561 // console.log(`Value for key ${key} is considered equal (foreign key)`)
558562 continue ;
559563 }
560564 }
561565 // console.log(`Value for key ${key} is different`, { oldValue: oldValue, newValue: newValue });
562- return false ;
566+ changedColumns [ key ] = { oldValue , newValue } ;
563567 }
564568 }
565- return true ;
569+ return { ok : Object . keys ( changedColumns ) . length !== 0 , changedFields : changedColumns } ;
570+ }
571+
572+ export function generateMessageHtmlForRecordChange ( changedFields : Record < string , { oldValue : any , newValue : any } > , t : ReturnType < typeof useI18n > [ 't' ] ) : string {
573+ const coreStore = useCoreStore ( ) ;
574+
575+ const escapeHtml = ( value : any ) => {
576+ if ( value === null || value === undefined || value === '' ) return `<em>${ t ( 'empty' ) } </em>` ;
577+ let s : string ;
578+ if ( typeof value === 'object' ) {
579+ try {
580+ s = JSON . stringify ( value ) ;
581+ } catch ( e ) {
582+ s = String ( value ) ;
583+ }
584+ } else {
585+ s = String ( value ) ;
586+ }
587+ return s . replace ( / & / g, '&' ) . replace ( / < / g, '<' ) . replace ( / > / g, '>' ) . replace ( / " / g, '"' ) . replace ( / ' / g, ''' ) ;
588+ } ;
589+
590+ const items = Object . keys ( changedFields || { } ) . map ( key => {
591+ const column = coreStore . resource ?. columns ?. find ( ( c : any ) => c . name === key ) ;
592+ const label = column ?. label || key ;
593+ const oldV = escapeHtml ( changedFields [ key ] . oldValue ) ;
594+ const newV = escapeHtml ( changedFields [ key ] . newValue ) ;
595+ return `<li class="truncate"><strong>${ escapeHtml ( label ) } </strong>: <span class="af-old-value text-muted">${ oldV } </span> → <span class="af-new-value">${ newV } </span></li>` ;
596+ } ) . join ( '' ) ;
597+
598+ const listHtml = items ? `<ul class="mt-2 list-disc list-inside">${ items } </ul>` : '' ;
599+ const messageHtml = `<div>${ escapeHtml ( t ( 'There are unsaved changes. Are you sure you want to leave this page?' ) ) } ${ listHtml } </div>` ;
600+ return messageHtml ;
566601}
0 commit comments