Hi , We tried to reach you previously for this issue and you suggested to use the below code in AppPreBoostrap.ts file . But not sure we tried to change the Browser to use canada format but it still showed US Data format. I site is is in prod and we need your help urgently. let locale = window.navigator.language; moment.locale(locale); (window as any).moment.locale(locale);
I have attached the entire code code from our AppPreBoostrap.ts file. Please help ...
import { UtilsService } from '@abp/utils/utils.service';
import { CompilerOptions, NgModuleRef, Type } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppAuthService } from '@app/shared/common/auth/app-auth.service'; import { AppConsts } from '@shared/AppConsts'; import { SubdomainTenancyNameFinder } from '@shared/helpers/SubdomainTenancyNameFinder'; import * as moment from 'moment-timezone'; import * as _ from 'lodash'; import { UrlHelper } from './shared/helpers/UrlHelper'; import { XmlHttpRequestHelper } from '@shared/helpers/XmlHttpRequestHelper'; import { DynamicResourcesHelper } from '@shared/helpers/DynamicResourcesHelper'; import { environment } from './environments/environment'; import { LocaleMappingService } from '@shared/locale-mapping.service';
export class AppPreBootstrap {
static run(appRootUrl: string, callback: () => void, resolve: any, reject: any): void {
AppPreBootstrap.getApplicationConfig(appRootUrl, () => {
if (UrlHelper.isInstallUrl(location.href)) {
AppPreBootstrap.loadAssetsForInstallPage(callback);
return;
}
const queryStringObj = UrlHelper.getQueryParameters();
if (queryStringObj.redirect && queryStringObj.redirect === 'TenantRegistration') {
if (queryStringObj.forceNewRegistration) {
new AppAuthService().logout();
}
location.href = AppConsts.appBaseUrl + '/account/select-edition';
} else if (queryStringObj.impersonationToken) {
AppPreBootstrap.impersonatedAuthenticate(queryStringObj.impersonationToken, queryStringObj.tenantId, () => { AppPreBootstrap.getUserConfiguration(callback); });
} else if (queryStringObj.switchAccountToken) {
AppPreBootstrap.linkedAccountAuthenticate(queryStringObj.switchAccountToken, queryStringObj.tenantId, () => { AppPreBootstrap.getUserConfiguration(callback); });
} else {
AppPreBootstrap.getUserConfiguration(callback);
}
});
}
static bootstrap<TM>(moduleType: Type<TM>, compilerOptions?: CompilerOptions | CompilerOptions[]): Promise<NgModuleRef<TM>> {
return platformBrowserDynamic().bootstrapModule(moduleType, compilerOptions);
}
private static getApplicationConfig(appRootUrl: string, callback: () => void) {
let type = 'GET';
let url = appRootUrl + 'assets/' + environment.appConfig;
let customHeaders = [
{
name: 'Abp.TenantId',
value: abp.multiTenancy.getTenantIdCookie() + ''
}];
XmlHttpRequestHelper.ajax(type, url, customHeaders, null, (result) => {
const subdomainTenancyNameFinder = new SubdomainTenancyNameFinder();
let tenancyName = subdomainTenancyNameFinder.getCurrentTenancyNameOrNull(result.appBaseUrl);
//Custom changes for Okta Host widget--106375
if(tenancyName.toLowerCase().includes("host")) {tenancyName="Default"; }
// CUSTOM ADDITION HERE
let getTenantIdURL = result.remoteServiceBaseUrl + '/api/services/app/Account/IsTenantAvailable';
let getTenantIdData = {tenancyName: tenancyName};
XmlHttpRequestHelper.ajax('POST', getTenantIdURL, null, JSON.stringify(getTenantIdData), (tenantResult) => {
abp.multiTenancy.setTenantIdCookie(tenantResult.result.tenantId);
AppConsts.appBuildNumber = result.appBuildNumber;
AppConsts.appBaseUrlFormat = result.appBaseUrl;
AppConsts.remoteServiceBaseUrlFormat = result.remoteServiceBaseUrl;
AppConsts.localeMappings = result.localeMappings;
AppConsts.azureCdnUrl=result.azureCdnUrl;
if (tenancyName == null) {
AppConsts.appBaseUrl = result.appBaseUrl.replace(AppConsts.tenancyNamePlaceHolderInUrl + '.', '');
//AppConsts.remoteServiceBaseUrl = result.remoteServiceBaseUrl.replace(AppConsts.tenancyNamePlaceHolderInUrl + '.', '');
} else {
AppConsts.appBaseUrl = result.appBaseUrl.replace(AppConsts.tenancyNamePlaceHolderInUrl, tenancyName);
//AppConsts.remoteServiceBaseUrl = result.remoteServiceBaseUrl.replace(AppConsts.tenancyNamePlaceHolderInUrl, tenancyName);
}
AppConsts.remoteServiceBaseUrl = result.remoteServiceBaseUrl;
callback();
});
});
}
private static getCurrentClockProvider(currentProviderName: string): abp.timing.IClockProvider {
if (currentProviderName === 'unspecifiedClockProvider') {
return abp.timing.unspecifiedClockProvider;
}
if (currentProviderName === 'utcClockProvider') {
return abp.timing.utcClockProvider;
}
return abp.timing.localClockProvider;
}
private static impersonatedAuthenticate(impersonationToken: string, tenantId: number, callback: () => void): void {
abp.multiTenancy.setTenantIdCookie(tenantId);
const cookieLangValue = abp.utils.getCookieValue('Abp.Localization.CultureName');
let requestHeaders = {
'.AspNetCore.Culture': ('c=' + cookieLangValue + '|uic=' + cookieLangValue),
'Abp.TenantId': abp.multiTenancy.getTenantIdCookie()
};
XmlHttpRequestHelper.ajax(
'POST',
AppConsts.remoteServiceBaseUrl + '/api/TokenAuth/ImpersonatedAuthenticate?impersonationToken=' + impersonationToken,
requestHeaders,
null,
(response) => {
let result = response.result;
abp.auth.setToken(result.accessToken);
AppPreBootstrap.setEncryptedTokenCookie(result.encryptedAccessToken);
location.search = '';
callback();
}
);
}
private static linkedAccountAuthenticate(switchAccountToken: string, tenantId: number, callback: () => void): void {
abp.multiTenancy.setTenantIdCookie(tenantId);
const cookieLangValue = abp.utils.getCookieValue('Abp.Localization.CultureName');
let requestHeaders = {
'.AspNetCore.Culture': ('c=' + cookieLangValue + '|uic=' + cookieLangValue),
'Abp.TenantId': abp.multiTenancy.getTenantIdCookie()
};
XmlHttpRequestHelper.ajax(
'POST',
AppConsts.remoteServiceBaseUrl + '/api/TokenAuth/LinkedAccountAuthenticate?switchAccountToken=' + switchAccountToken,
requestHeaders,
null,
(response) => {
let result = response.result;
abp.auth.setToken(result.accessToken);
AppPreBootstrap.setEncryptedTokenCookie(result.encryptedAccessToken);
location.search = '';
callback();
}
);
}
private static getUserConfiguration(callback: () => void): any {
const cookieLangValue = abp.utils.getCookieValue('Abp.Localization.CultureName');
const token = abp.auth.getToken();
let requestHeaders = {
'.AspNetCore.Culture': ('c=' + cookieLangValue + '|uic=' + cookieLangValue),
'Abp.TenantId': abp.multiTenancy.getTenantIdCookie(),
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,PUT,POST'
};
if (token) {
requestHeaders['Authorization'] = 'Bearer ' + token;
}
return XmlHttpRequestHelper.ajax('GET', AppConsts.remoteServiceBaseUrl + '/api/services/app/UiCustomizationSettings/GetAll', requestHeaders, null, (response) => {
let result = JSON.parse(response).result;
_.merge(abp, result);
abp.clock.provider = this.getCurrentClockProvider(result.clock.provider);
let locale = window.navigator.language;
moment.locale(locale);
(window as any).moment.locale(locale);
if (abp.clock.provider.supportsMultipleTimezone) {
moment.tz.setDefault(abp.timing.timeZoneInfo.iana.timeZoneId);
(window as any).moment.tz.setDefault(abp.timing.timeZoneInfo.iana.timeZoneId);
} else {
moment.fn.toJSON = function () {
return this.locale('en').format();
};
moment.fn.toISOString = function () {
return this.locale('en').format();
};
}
abp.event.trigger('abp.dynamicScriptsInitialized');
AppConsts.noDirectAccessWorkflowPages = JSON.parse(abp.setting.get('App.UiManagement.Workflow.NoDirectAccessPages'));
AppConsts.recaptchaSiteKey = abp.setting.get('Recaptcha.SiteKey');
AppConsts.subscriptionExpireNootifyDayCount = parseInt(abp.setting.get('App.TenantManagement.SubscriptionExpireNotifyDayCount'));
DynamicResourcesHelper.loadResources(callback);
});
}
private static setEncryptedTokenCookie(encryptedToken: string) {
new UtilsService().setCookieValue(AppConsts.authorization.encrptedAuthTokenName,
encryptedToken,
new Date(new Date().getTime() + 365 * 86400000), //1 year
abp.appPath
);
}
private static loadAssetsForInstallPage(callback) {
abp.setting.values['App.UiManagement.Theme'] = 'default';
abp.setting.values['default.App.UiManagement.ThemeColor'] = 'default';
DynamicResourcesHelper.loadResources(callback);
}
}
Also in the prime ng grid i am adding the date format like this for the column
<ng-template pTemplate="body" let-record="$implicit"> <tr [ngClass]="record.selected && !isShow ? 'validated' :(record.scannedByotherUser && !isShow ? 'validatedByOthers' : '')"> <td ngFor="let col of shipOutCols" [hidden]="!col.isVisible"> {{col.field.includes('Time') || col.field.includes('Date') ? ** (record[col.field] | momentFormat:'L LTS'):record[col.field]}}* </td>
Hi Abp Zero,
We have a custom feature AppFeatures.EnableUserVisibilityRules, and I would like to make the feature value to be false when running the test project. Is there a way to do it?
context.Create( AppFeatures.EnableUserVisibilityRules, defaultValue: "true", displayName: L("EnableUserVisibilityRules"), inputType: new CheckboxInputType() );
Thank you,
Hi , We are running into performance issues with the .net core with angular app. Can you please guide in the best way to help improve performance
Are there libraries that come with aspnetzero / abp that we're not using that could be deleted? or not allow to load at start up ?
Are there resources that it would make sense to delay loading until after login page (like do in parallel with Okta login API call or load in background after user hits the main landing page )?
How can we Ensure all .css and .js is minified for all our environments ?> Is there a common place we can do that ?
Hi Abp Zero,
We're using .net Core 2.1 and Angular 8.
For certain reason I would like to overwrite MultiTenantLocalizationSource with my own CustomMultiTenantLocalizationSource.
I tried to use following code in the PreInitialize() in ProjectCoreModule but it didn't work as other replaced services:
Configuration.ReplaceService<IMultiTenantLocalizationSource, CustomMultiTenantLocalizationSource>(DependencyLifeStyle.Transient);
Could you please advise how I coud replace the IMultiTenantLocalizationSource service?
Thank you
Hi,
Our product is based on Core2.1 + Angular8, and we planned to turn on Redis for cache.
Before we turn on Redis, the default memory cache was being used.
Take GetRoleForEdit as an example,
Before Redis was turned on, The EditRole modal was rendered in 1-2 seconds.
After Redis was turned on: Whenever we click on GetRoleForEdit, it takes long time (more than 50s+, sometimes timeout) to render the modal.
Same thing happens for my local redis setup -- it takes 6.08 seconds for the result to come back when I use redis on my local workstation.
For GetLanguageTexts endpoint, the longest request duration was even 19min today.
One of assumptions is that Redis is reflecting what's happening under the hood -- GetRoleForEdit is visiting cache hundreds of time, and the performance issue emerges after we turned on Redis. Another assumption is the some logic in AbpRedisCacheManager causes the 'infinite' calls to Redis cache.
Please advise why this performance issue happens after turning on Redis.
Thank you,
Hi ,
we are trying to read local browser datetime format but it seems to be not working for me. we are using angular project with dotnetcore. I tried formatting as mentioned below and then switched my local browser setting my English(US) which has datetime format 4/13/2020 to English(Canada) which has datetime format of 2020-04-13. But it does not seems to be working that way . Can you please guide me ?. I could not find any examples
<td style="width: 150px">
<span class="ui-column-title">{{'Time' | localize}}</span>
{{ record.executionTime | momentFormat:'L LTS'}}
</td>
Hi --
Is there any sample code of before and after changes between a "prestine" version of AspNetZero download of AspNetCore and a well integrated with OAuth 2.0 Okta Integration?
What changes are required?
This is a common topic but I require a bit more of a guided "getting started" approach to making appropriate changes.
Reference: https://developer.okta.com/blog/2018/06/19/deploy-your-aspnet-core-app-to-azure
Thank you.
Hi Abp Zero Support,
Is there any particular reason for BackgroundJob to be Transient in the document? Is there any downside if I make it Singleton?
public class TestJob : BackgroundJob<int>, ITransientDependency
{
public override void Execute(int number)
{
Logger.Debug(number.ToString());
}
}
https://aspnetboilerplate.com/Pages/Documents/Background-Jobs-And-Workers
Thank you, R
Hi Abp Zero Support,
Our project is using C2A8. Today we upgraded to 4.10.1, and after upgrade, the AuditLogAppService_Tests.Should_Get_Entity_Changes unit test started failing but I didn't touch that unit test.
Shouldly.ShouldAssertException : entityChangeList.TotalCount
should be
2
but was
0
I checked MajesticTestBaseModule, and found following two lines are uncommented.
Configuration.EntityHistory.IsEnabled = true;
Configuration.EntityHistory.Selectors.Add("ProjectEntities", typeof(User), typeof(Tenant));
Not sure why the entity change capture is not happening.
Any related files to this EntityHistory that I could refer to? Like AuditingHelper/Intercepter to AuditLog...
Thank you,
Hi Abp Zero Support,
Our project is based on .Net Core 2 + Angular 8. I noticed in Preinitialize you're using Configuration.IocManager, but in Initialize, you're using IocManager directly. Just wonder what was the difference between these two IocManager? Is IocManager a singleton instance?
Thank you