Both very useful answers. Thanks.
dotnet-core, angular, Zero 6.8.0, .NET framework 4.6.1 In Azure I have two deployment slots for my dotnet-core project, testing and staging. I create an appsettings json file for each of my environments: In Azure I create an ASPNETCORE_ENVIRONMENT variable for each of these slots and check the slot setting: This is great, I can now release initially to testing and then swap with staging for focus-group review and then swap staging with production when all UATs are passed. Each slot reads the correct appsettings json file and data is persisted to and delivered from the relevant testing, staging or production datastore (and any other settings I have in the appsettings file such as PayPal sandboxes etc.).
In the Angular project the position is different. I'm not fully conversant with the inner workings because I leave this kind of black magic to the Zero (thanks, guys). I believe the compile process reads the environment.ts file which exports the const environment value:
// The file contents for the current environment will overwrite these during build.
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
// The list of which env maps to which file can be found in `angular-cli.json`.
export const environment = {
production: false,
hmr: false,
appConfig: 'appconfig.json'
};
Thus, if I run ng build --testing
I believe the system will now read the appsettings.testing.json file for my server variables which will connect my angular app to the relevant dotnet-core API.
My question is:
Is there any way to have the angular app read an application setting from the relevant deployment slot and thus force the system to use the relevant appsettings file?
At the moment my only solution is to carry out the deployment slot swap and then copy a new version of appsettings.production.json to both environments with the relevant settings for the appropriate dotnet-core API. This means having to keep three copies of appsettings.production.json, one for each environment, testing staging and production, which I deploy via FTP after the swap. This also means bringing down my app for a few seconds whilst the appsettings file is transferred, something I can live with but hardly ideal. Any ideas anyone?
Ok. It is still a problem and I have it on my issues list but there are more pressing issues. Re-opening this means having to get to know the entity history module all over again plus the changes you implemented at a later date. Thanks for the heads up.
Thanks, @maliming. It's not elegant to change the typings.d.ts file, it messes up the merge during the upgrade process. At the end of the day if the user selects the "No" button on the confirm dialogue it doesn't throw errors so I will watch your issue with interest. Thanks again for the help.
HI maliming, thanks for your attention but this is hieroglyphics to me. In my .ts file how do refer to sweet alert directly? In the code above you refer to "Swal.
", do I have to import this in some way? The sweet alert documentation is not entirely clear, I have read it but I'm not spending hours and hours to fix something that's not a show stopper.
How do invoke the Swal api?
Hi Aaron, I suppose you're suggesting I do something like this:
abp.libs.sweetAlert.config.confirm.buttons = [abp.localization.abpWeb('Ok')];
But what module do I import for abp.libs
?
Property libs does not exist on type 'typeof abp'
What am I missing?
angular, dotnet-core, 6.8.0, .NET 4.6.1 Is it possible to modify the abp implementation of sweet alert confirm (abp.message.confirm(...)) ? When a user refreshes a grid (or uses the search functionality in Zero grids) it is possible that the authorization cookie has expired and I want to redirect the user to the sign in page. At the moment there are two buttons, I would like to replace them with a single button: "Ok". My code reads as below:
}, (error: HttpErrorResponse) => {
this.gridLoading = false;
if (error.status === 401) {
//this to capture refresh of grid when login has expired
abp.message.confirm(null, this.l('LoginHasExpired'), function (isConfirmed) {
if (isConfirmed) {
abp.auth.clearToken();
abp.utils.setCookieValue(AppConsts.authorization.encrptedAuthTokenName, undefined, undefined, abp.appPath);
location.href = '';
}
});
} else { ... code removed for brevity ...
It seems it is not possible to add a function to the info, success, warn or error messages to carry out the same. Also - please note the spelling mistake at: AppConsts.authorization.encrptedAuthTokenName Which should read: AppConsts.authorization.encryptedAuthTokenName In the same file (AppConsts) you also have: subscriptionExpireNootifyDayCount which should read: subscriptionExpireNotifyDayCount
@dev_frontrush, There doesn't seem to be a method of adding files to this forum. If you want to post your email I can help by sending you my code files but I haven't the time to document exactly how to implement at the moment, I'm in the middle of an implementation. The code below shows how I implement filters, hopefully it may help, I suspect you may be having a problem with the long descriptor.
[DontWrapResult(WrapOnError = true)]
public async Task<JsonResult> GetEntities([DataSourceRequest]DataSourceRequest request, int isDeleted)
{
//for testing...
isDeleted = 0;
//cast string to Guid
if (request.Filters != null)
{
ModifyFilters(request.Filters);
}
var query = await _ncEntityService.GetSPEntityIQueryableForKendoGrid(isDeleted);
var model = await query.ToDataSourceResultAsync(request);
return Json(model);
}
And the modified filter code:
private void ModifyFilters(IList<IFilterDescriptor> filters)
{
if (filters.Any())
{
foreach (var filter in filters)
{
var descriptor = filter as FilterDescriptor;
if (descriptor != null && descriptor.Member == "id")
{
descriptor.Value = ToGuid(descriptor.Value.ToString());
descriptor.MemberType = typeof(Guid);
}
else if (descriptor != null && descriptor.Member == "userName")
{
var user = _userRepository.FirstOrDefault(m => m.UserName == descriptor.Value.ToString());
descriptor.Value = 0;
if (user != null)
{
descriptor.Value = user.Id;
}
descriptor.Member = "userId";
descriptor.MemberType = typeof(long);
}
else if (filter is CompositeFilterDescriptor)
{
ModifyFilters(((CompositeFilterDescriptor)filter).FilterDescriptors);
}
}
}
}
@dev_frontrush, yep I use the grid in two or three different flavours but it's something I didn't document. It might take a couple of days but I'll try get some basic instructions together for you, I'm up to my ears right now.