ngx-dsxlibrary 2.21.3 → 2.21.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3658,6 +3658,223 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
3658
3658
|
}]
|
|
3659
3659
|
}] });
|
|
3660
3660
|
|
|
3661
|
+
function pickByKeys(source, keys) {
|
|
3662
|
+
const result = {};
|
|
3663
|
+
for (const key of keys) {
|
|
3664
|
+
result[key] = source[key];
|
|
3665
|
+
}
|
|
3666
|
+
return result;
|
|
3667
|
+
}
|
|
3668
|
+
function tryParseDateValue(value) {
|
|
3669
|
+
if (value instanceof Date) {
|
|
3670
|
+
const time = value.getTime();
|
|
3671
|
+
return Number.isNaN(time) ? null : time;
|
|
3672
|
+
}
|
|
3673
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
3674
|
+
const parsed = new Date(value);
|
|
3675
|
+
const time = parsed.getTime();
|
|
3676
|
+
return Number.isNaN(time) ? null : time;
|
|
3677
|
+
}
|
|
3678
|
+
return null;
|
|
3679
|
+
}
|
|
3680
|
+
function normalizeComparableValue(base, current) {
|
|
3681
|
+
const baseDateValue = tryParseDateValue(base);
|
|
3682
|
+
if (baseDateValue !== null) {
|
|
3683
|
+
const currentDateValue = tryParseDateValue(current);
|
|
3684
|
+
return currentDateValue ?? current;
|
|
3685
|
+
}
|
|
3686
|
+
return current;
|
|
3687
|
+
}
|
|
3688
|
+
function normalizeBaseEntity(baseValue, keys) {
|
|
3689
|
+
const normalized = {};
|
|
3690
|
+
const selectedKeys = keys ?? Object.keys(baseValue);
|
|
3691
|
+
for (const key of selectedKeys) {
|
|
3692
|
+
const base = baseValue[key];
|
|
3693
|
+
normalized[key] = normalizeComparableValue(base, base);
|
|
3694
|
+
}
|
|
3695
|
+
return normalized;
|
|
3696
|
+
}
|
|
3697
|
+
function normalizeRawEntityAgainstBase(baseValue, rawValue, keys, useBaseValueForNullish = true) {
|
|
3698
|
+
const coerceByBaseType = (base, current) => {
|
|
3699
|
+
if (typeof base === 'number') {
|
|
3700
|
+
if (typeof current === 'string' && current.trim() !== '') {
|
|
3701
|
+
const normalizedText = current.trim();
|
|
3702
|
+
const direct = Number(normalizedText);
|
|
3703
|
+
if (!Number.isNaN(direct))
|
|
3704
|
+
return direct;
|
|
3705
|
+
const commaDecimal = Number(normalizedText.replace(',', '.'));
|
|
3706
|
+
if (!Number.isNaN(commaDecimal))
|
|
3707
|
+
return commaDecimal;
|
|
3708
|
+
const noSpaces = normalizedText.replace(/\s+/g, '');
|
|
3709
|
+
const noThousandsDots = Number(noSpaces.replace(/\./g, '').replace(',', '.'));
|
|
3710
|
+
if (!Number.isNaN(noThousandsDots))
|
|
3711
|
+
return noThousandsDots;
|
|
3712
|
+
return current;
|
|
3713
|
+
}
|
|
3714
|
+
return current;
|
|
3715
|
+
}
|
|
3716
|
+
if (typeof base === 'boolean') {
|
|
3717
|
+
if (typeof current === 'string') {
|
|
3718
|
+
const lowered = current.trim().toLowerCase();
|
|
3719
|
+
if (lowered === 'true')
|
|
3720
|
+
return true;
|
|
3721
|
+
if (lowered === 'false')
|
|
3722
|
+
return false;
|
|
3723
|
+
}
|
|
3724
|
+
return current;
|
|
3725
|
+
}
|
|
3726
|
+
if (base instanceof Date) {
|
|
3727
|
+
if (current instanceof Date)
|
|
3728
|
+
return current;
|
|
3729
|
+
if (typeof current === 'string' || typeof current === 'number') {
|
|
3730
|
+
const parsed = new Date(current);
|
|
3731
|
+
return Number.isNaN(parsed.getTime()) ? current : parsed;
|
|
3732
|
+
}
|
|
3733
|
+
return current;
|
|
3734
|
+
}
|
|
3735
|
+
if (typeof base === 'string') {
|
|
3736
|
+
if (current === null || current === undefined)
|
|
3737
|
+
return current;
|
|
3738
|
+
return typeof current === 'string' ? current : String(current);
|
|
3739
|
+
}
|
|
3740
|
+
return current;
|
|
3741
|
+
};
|
|
3742
|
+
const normalized = {};
|
|
3743
|
+
const selectedKeys = keys ?? Object.keys(baseValue);
|
|
3744
|
+
for (const key of selectedKeys) {
|
|
3745
|
+
const base = baseValue[key];
|
|
3746
|
+
const current = rawValue[key];
|
|
3747
|
+
const isNullish = current === null || current === undefined;
|
|
3748
|
+
const isEmptyString = typeof current === 'string' && current.trim() === '';
|
|
3749
|
+
const treatEmptyAsNullish = isEmptyString && typeof base !== 'string';
|
|
3750
|
+
const shouldUseBase = useBaseValueForNullish && (isNullish || treatEmptyAsNullish);
|
|
3751
|
+
normalized[key] = shouldUseBase ? base : coerceByBaseType(base, current);
|
|
3752
|
+
normalized[key] = normalizeComparableValue(base, normalized[key]);
|
|
3753
|
+
}
|
|
3754
|
+
return normalized;
|
|
3755
|
+
}
|
|
3756
|
+
/**
|
|
3757
|
+
* Servicio utilitario para detectar cambios en formularios o vistas
|
|
3758
|
+
* maestro-detalle sin acoplarse a una estructura de dominio concreta.
|
|
3759
|
+
*/
|
|
3760
|
+
class MasterDetailChangeService {
|
|
3761
|
+
static findFirstDifference(leftValue, rightValue, path = 'root') {
|
|
3762
|
+
if (leftValue instanceof Date && rightValue instanceof Date) {
|
|
3763
|
+
return leftValue.getTime() === rightValue.getTime()
|
|
3764
|
+
? null
|
|
3765
|
+
: { path, leftValue, rightValue };
|
|
3766
|
+
}
|
|
3767
|
+
if (Array.isArray(leftValue) && Array.isArray(rightValue)) {
|
|
3768
|
+
if (leftValue.length !== rightValue.length) {
|
|
3769
|
+
return {
|
|
3770
|
+
path: `${path}.length`,
|
|
3771
|
+
leftValue: leftValue.length,
|
|
3772
|
+
rightValue: rightValue.length,
|
|
3773
|
+
};
|
|
3774
|
+
}
|
|
3775
|
+
for (let index = 0; index < leftValue.length; index += 1) {
|
|
3776
|
+
const difference = MasterDetailChangeService.findFirstDifference(leftValue[index], rightValue[index], `${path}[${index}]`);
|
|
3777
|
+
if (difference) {
|
|
3778
|
+
return difference;
|
|
3779
|
+
}
|
|
3780
|
+
}
|
|
3781
|
+
return null;
|
|
3782
|
+
}
|
|
3783
|
+
if (leftValue != null &&
|
|
3784
|
+
rightValue != null &&
|
|
3785
|
+
typeof leftValue === 'object' &&
|
|
3786
|
+
typeof rightValue === 'object') {
|
|
3787
|
+
const leftKeys = Object.keys(leftValue);
|
|
3788
|
+
const rightKeys = Object.keys(rightValue);
|
|
3789
|
+
if (leftKeys.length !== rightKeys.length) {
|
|
3790
|
+
return {
|
|
3791
|
+
path: `${path}.__keys__`,
|
|
3792
|
+
leftValue: leftKeys,
|
|
3793
|
+
rightValue: rightKeys,
|
|
3794
|
+
};
|
|
3795
|
+
}
|
|
3796
|
+
for (const key of leftKeys) {
|
|
3797
|
+
const difference = MasterDetailChangeService.findFirstDifference(leftValue[key], rightValue[key], `${path}.${key}`);
|
|
3798
|
+
if (difference) {
|
|
3799
|
+
return difference;
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
return null;
|
|
3803
|
+
}
|
|
3804
|
+
return Object.is(leftValue, rightValue)
|
|
3805
|
+
? null
|
|
3806
|
+
: { path, leftValue, rightValue };
|
|
3807
|
+
}
|
|
3808
|
+
/**
|
|
3809
|
+
* Version simplificada para formularios: recibe `getRawValue()` directamente
|
|
3810
|
+
* y compara por claves sin requerir mapeo manual en el consumidor.
|
|
3811
|
+
*/
|
|
3812
|
+
createSimpleFormTracker(initialState, options) {
|
|
3813
|
+
const defaultMasterKeys = Object.keys(initialState.master);
|
|
3814
|
+
const defaultDetailKeys = initialState.detail.length > 0
|
|
3815
|
+
? Object.keys(initialState.detail[0])
|
|
3816
|
+
: [];
|
|
3817
|
+
const masterKeys = options?.masterKeys ?? defaultMasterKeys;
|
|
3818
|
+
const detailKeys = options?.detailKeys ?? defaultDetailKeys;
|
|
3819
|
+
const useBaseValueForNullish = options?.useBaseValueForNullish ?? true;
|
|
3820
|
+
let initialMaster = structuredClone(initialState.master);
|
|
3821
|
+
let initialDetail = structuredClone(initialState.detail);
|
|
3822
|
+
const buildComparisonPayload = (currentState) => {
|
|
3823
|
+
const normalizedBaseMaster = normalizeBaseEntity(initialMaster, masterKeys);
|
|
3824
|
+
const normalizedCurrentMaster = normalizeRawEntityAgainstBase(initialMaster, currentState.master, masterKeys, useBaseValueForNullish);
|
|
3825
|
+
const normalizedBaseDetail = initialDetail.map((item) => normalizeBaseEntity(item, detailKeys));
|
|
3826
|
+
const normalizedCurrentDetail = currentState.detail.map((item, index) => normalizeRawEntityAgainstBase(initialDetail[index] ?? {}, item, detailKeys, useBaseValueForNullish));
|
|
3827
|
+
return {
|
|
3828
|
+
normalizedBaseMaster,
|
|
3829
|
+
normalizedCurrentMaster,
|
|
3830
|
+
normalizedBaseDetail,
|
|
3831
|
+
normalizedCurrentDetail,
|
|
3832
|
+
};
|
|
3833
|
+
};
|
|
3834
|
+
const resolveChanges = (currentState) => {
|
|
3835
|
+
const { normalizedBaseMaster, normalizedCurrentMaster, normalizedBaseDetail, normalizedCurrentDetail, } = buildComparisonPayload(currentState);
|
|
3836
|
+
const masterDifference = MasterDetailChangeService.findFirstDifference(normalizedBaseMaster, normalizedCurrentMaster, 'master');
|
|
3837
|
+
const detailDifference = MasterDetailChangeService.findFirstDifference(normalizedBaseDetail, normalizedCurrentDetail, 'detail');
|
|
3838
|
+
return {
|
|
3839
|
+
hasChanges: masterDifference !== null || detailDifference !== null,
|
|
3840
|
+
masterChanged: masterDifference !== null,
|
|
3841
|
+
detailChanged: detailDifference !== null,
|
|
3842
|
+
firstDifference: masterDifference
|
|
3843
|
+
? {
|
|
3844
|
+
scope: 'master',
|
|
3845
|
+
path: masterDifference.path,
|
|
3846
|
+
baseValue: masterDifference.leftValue,
|
|
3847
|
+
currentValue: masterDifference.rightValue,
|
|
3848
|
+
}
|
|
3849
|
+
: detailDifference
|
|
3850
|
+
? {
|
|
3851
|
+
scope: 'detail',
|
|
3852
|
+
path: detailDifference.path,
|
|
3853
|
+
baseValue: detailDifference.leftValue,
|
|
3854
|
+
currentValue: detailDifference.rightValue,
|
|
3855
|
+
}
|
|
3856
|
+
: null,
|
|
3857
|
+
};
|
|
3858
|
+
};
|
|
3859
|
+
return {
|
|
3860
|
+
hasChanges: (currentState) => resolveChanges(currentState).hasChanges,
|
|
3861
|
+
getChanges: (currentState) => resolveChanges(currentState),
|
|
3862
|
+
reset: (state) => {
|
|
3863
|
+
initialMaster = structuredClone(state.master);
|
|
3864
|
+
initialDetail = structuredClone(state.detail);
|
|
3865
|
+
},
|
|
3866
|
+
};
|
|
3867
|
+
}
|
|
3868
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MasterDetailChangeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3869
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MasterDetailChangeService, providedIn: 'root' });
|
|
3870
|
+
}
|
|
3871
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MasterDetailChangeService, decorators: [{
|
|
3872
|
+
type: Injectable,
|
|
3873
|
+
args: [{
|
|
3874
|
+
providedIn: 'root',
|
|
3875
|
+
}]
|
|
3876
|
+
}] });
|
|
3877
|
+
|
|
3661
3878
|
class UtilityAddService {
|
|
3662
3879
|
_serviceAlerta = inject(AlertaService);
|
|
3663
3880
|
environment = inject(ENVIRONMENT);
|
|
@@ -4379,7 +4596,6 @@ class UtilityAddService {
|
|
|
4379
4596
|
checkFormValid(control) {
|
|
4380
4597
|
if (!control)
|
|
4381
4598
|
return;
|
|
4382
|
-
console.log(control);
|
|
4383
4599
|
// Marca todos los controles (incluyendo anidados en FormGroup/FormArray)
|
|
4384
4600
|
control.markAllAsTouched();
|
|
4385
4601
|
// Muestra un mensaje de alerta
|
|
@@ -4988,5 +5204,5 @@ function CUICorrecto(cui) {
|
|
|
4988
5204
|
* Generated bundle index. Do not edit.
|
|
4989
5205
|
*/
|
|
4990
5206
|
|
|
4991
|
-
export { AlertaService, AppMessageErrorComponent, ArrowNavigationDirective, AuthorizeService, BaseCRUDService, CACHE_KEYS, CacheService, CssV2Component, DocxPreviewComponent, DsxAddToolsModule, DteService, ENVIRONMENT, EndpointService, ErrorHandlerService, FileComponent, GTQFormatter, HttpHelpersService, INITIAL_PARAMETERS, IconDsxComponent, JoinByPipe, JsonHighlightPipe, JsonValuesDebujComponent, JsonViewerComponent, KpicardComponent, LoadingComponent, LoadingLottieComponent, LogoDsxComponent, NavbarDsxComponent, NetworkStatusComponent, OnlyRangoPatternDirective, ParameterValuesService, PrimeNgModule, SWEET_ALERT_THEMES, SecurityService, SelectAllOnFocusDirective, SpinnerLoadingService, TruncatePipe, UtilityAddService, atLeastOneFieldRequiredValidator, createCurrencyFormatter, createInitialCache, createTypedCacheProvider, cuiValidator, dateMinMaxValidator, dateRangeValidator, dateRangeValidatorFromTo, developmentEnvironment, getZeroBasedRolIndex, httpAuthorizeInterceptor, nitValidator, productionEnvironment, provideEnvironment, validateEnvironmentConfig };
|
|
5207
|
+
export { AlertaService, AppMessageErrorComponent, ArrowNavigationDirective, AuthorizeService, BaseCRUDService, CACHE_KEYS, CacheService, CssV2Component, DocxPreviewComponent, DsxAddToolsModule, DteService, ENVIRONMENT, EndpointService, ErrorHandlerService, FileComponent, GTQFormatter, HttpHelpersService, INITIAL_PARAMETERS, IconDsxComponent, JoinByPipe, JsonHighlightPipe, JsonValuesDebujComponent, JsonViewerComponent, KpicardComponent, LoadingComponent, LoadingLottieComponent, LogoDsxComponent, MasterDetailChangeService, NavbarDsxComponent, NetworkStatusComponent, OnlyRangoPatternDirective, ParameterValuesService, PrimeNgModule, SWEET_ALERT_THEMES, SecurityService, SelectAllOnFocusDirective, SpinnerLoadingService, TruncatePipe, UtilityAddService, atLeastOneFieldRequiredValidator, createCurrencyFormatter, createInitialCache, createTypedCacheProvider, cuiValidator, dateMinMaxValidator, dateRangeValidator, dateRangeValidatorFromTo, developmentEnvironment, getZeroBasedRolIndex, httpAuthorizeInterceptor, nitValidator, productionEnvironment, provideEnvironment, validateEnvironmentConfig };
|
|
4992
5208
|
//# sourceMappingURL=ngx-dsxlibrary.mjs.map
|