Hi,
we've used the AspNetZero RAD Tool to auto-generate our html and ts files along with the entities.
Is there any very basic example on how have the html & ts look like for having an editable table? I read the example on the documentation page of PrimeNg here but the the html pages created by AspNetZero RAD Tool are quite more code-heavy.
Here is an example html page with only one entity:
<div [@routerTransition]>
<div class="kt-subheader kt-grid__item">
<div class="kt-subheader__main">
<h3 class="kt-subheader__title">
<span>{{l("Anlasses")}}</span>
</h3>
<span class="kt-subheader__separator kt-subheader__separator--v"></span>
<span class="kt-subheader__desc">
{{l("AnlassesHeaderInfo")}}
</span>
</div>
<div class="kt-subheader__toolbar">
<div class="kt-subheader__wrapper">
<button (click)="exportToExcel()" class="btn btn-outline-success"><i class="fa fa-file-excel"></i> {{l("ExportToExcel")}}</button>
<button *ngIf="isGranted('Pages.Administration.Anlasses.Create')" (click)="createAnlass()"
class="btn btn-primary blue"><i class="fa fa-plus"></i> {{l("CreateNewAnlass")}}</button>
</div>
</div>
</div>
<div class="kt-content">
<div class="kt-portlet kt-portlet--mobile">
<div class="kt-portlet__body">
<form class="kt-form" autocomplete="off">
<div>
<div class="row align-items-center">
<div class="col-xl-12">
<div class="form-group m-form__group align-items-center">
<div class="input-group">
<input [(ngModel)]="filterText" name="filterText" autoFocus class="form-control m-input" [placeholder]="l('SearchWithThreeDot')" type="text">
<span class="input-group-btn">
<button (click)="getAnlasses()" class="btn btn-primary" type="submit"><i class="flaticon-search-1"></i></button>
</span>
</div>
</div>
</div>
</div>
<div class="row" [hidden]="!advancedFiltersAreShown">
<div class="col-md-12">
<div class="kt-separator kt-separator--border-dashed"></div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="AnlassTypFilter">{{l("AnlassTyp")}}</label>
<input type="text" class="form-control" id="AnlassTypFilter" name="anlassTypFilter" [(ngModel)]="anlassTypFilter">
</div>
</div>
</div>
<div class="row mb-2">
<div class="col-sm-12">
<span class="clickable-item text-muted" *ngIf="!advancedFiltersAreShown" (click)="advancedFiltersAreShown=!advancedFiltersAreShown"><i class="fa fa-angle-down"></i> {{l("ShowAdvancedFilters")}}</span>
<span class="clickable-item text-muted" *ngIf="advancedFiltersAreShown" (click)="advancedFiltersAreShown=!advancedFiltersAreShown"><i class="fa fa-angle-up"></i> {{l("HideAdvancedFilters")}}</span>
</div>
</div>
</div>
</form>
<div class="row align-items-center">
<!--<Primeng-Datatable-Start>-->
<div class="primeng-datatable-container col-12"
[busyIf]="primengTableHelper.isLoading">
<p-table #dataTable
(onLazyLoad)="getAnlasses($event)"
[value]="primengTableHelper.records"
rows="{{primengTableHelper.defaultRecordsCountPerPage}}"
[paginator]="false"
[lazy]="true"
[scrollable]="true"
ScrollWidth="100%"
[responsive]="primengTableHelper.isResponsive"
[resizableColumns]="primengTableHelper.resizableColumns">
<ng-template pTemplate="header">
<tr>
<th style="width: 130px" [hidden]="!isGrantedAny('Pages.Administration.Anlasses.Edit', 'Pages.Administration.Anlasses.Delete')">{{l('Actions')}}</th>
<th style="width: 150px" pSortableColumn="anlassTyp">
{{l('AnlassTyp')}}
<p-sortIcon field="anlass.anlassTyp"></p-sortIcon>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-record="$implicit" let-rowData>
<tr>
<td style="width: 130px"
[hidden]="!isGrantedAny('Pages.Administration.Anlasses.Edit', 'Pages.Administration.Anlasses.Delete')">
<div class="btn-group dropdown" dropdown container="body">
<button class="dropdown-toggle btn btn-sm btn-primary" dropdownToggle>
<i class="fa fa-cog"></i><span class="caret"></span> {{l("Actions")}}
</button>
<ul class="dropdown-menu" *dropdownMenu>
<li>
<a href="javascript:;"
(click)="viewAnlassModal.show(record)">{{l('View')}}</a>
</li>
<li>
<a href="javascript:;" *ngIf="permission.isGranted('Pages.Administration.Anlasses.Edit')"
(click)="createOrEditAnlassModal.show(record.anlass.id)">{{l('Edit')}}</a>
</li>
<li>
<a href="javascript:;" *ngIf="permission.isGranted('Pages.Administration.Anlasses.Delete')"
(click)="deleteAnlass(record.anlass)">{{l('Delete')}}</a>
</li>
<li>
<a href="javascript:;" *ngIf="entityHistoryEnabled"
(click)="showHistory(record.anlass)">{{l('History')}}</a>
</li>
</ul>
</div>
</td>
<td style="width:150px" pEditableColumn>
<!--<span class="ui-column-title"> {{l('AnlassTyp')}}</span>
{{record.anlass.anlassTyp}}
-->
<p-cellEditor>
<ng-template pTemplate="input">
<input pInputText type="text" [(ngModel)]="record.anlass.anlassTyp">
</ng-template>
<ng-template pTemplate="output">
{{record.anlass.anlassTyp}}
</ng-template>
</p-cellEditor>
</td>
</tr>
</ng-template>
</p-table>
<div class="primeng-no-data" *ngIf="primengTableHelper.totalRecordsCount == 0">
{{l('NoData')}}
</div>
<div class="primeng-paging-container">
<p-paginator rows="{{primengTableHelper.defaultRecordsCountPerPage}}"
#paginator
(onPageChange)="getAnlasses($event)"
[totalRecords]="primengTableHelper.totalRecordsCount"
[rowsPerPageOptions]="primengTableHelper.predefinedRecordsCountPerPage">
</p-paginator>
<span class="total-records-count">
{{l('TotalRecordsCount', primengTableHelper.totalRecordsCount)}}
</span>
</div>
</div>
<!--<Primeng-Datatable-End>-->
</div>
</div>
</div>
</div>
<createOrEditAnlassModal #createOrEditAnlassModal (modalSave)="getAnlasses()"></createOrEditAnlassModal>
<viewAnlassModal #viewAnlassModal></viewAnlassModal>
<entityTypeHistoryModal #entityTypeHistoryModal></entityTypeHistoryModal>
</div>
And the corresponding ts
import { Component, Injector, ViewEncapsulation, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AnlassesServiceProxy, AnlassDto } from '@shared/service-proxies/service-proxies';
import { NotifyService } from '@abp/notify/notify.service';
import { AppComponentBase } from '@shared/common/app-component-base';
import { TokenAuthServiceProxy } from '@shared/service-proxies/service-proxies';
import { CreateOrEditAnlassModalComponent } from './create-or-edit-anlass-modal.component';
import { ViewAnlassModalComponent } from './view-anlass-modal.component';
import { appModuleAnimation } from '@shared/animations/routerTransition';
import { Table } from 'primeng/components/table/table';
import { Paginator } from 'primeng/components/paginator/paginator';
import { LazyLoadEvent } from 'primeng/components/common/lazyloadevent';
import { FileDownloadService } from '@shared/utils/file-download.service';
import { EntityTypeHistoryModalComponent } from '@app/shared/common/entityHistory/entity-type-history-modal.component';
import * as _ from 'lodash';
import * as moment from 'moment';
@Component({
templateUrl: './anlasses.component.html',
encapsulation: ViewEncapsulation.None,
animations: [appModuleAnimation()]
})
export class AnlassesComponent extends AppComponentBase {
@ViewChild('createOrEditAnlassModal', { static: true }) createOrEditAnlassModal: CreateOrEditAnlassModalComponent;
@ViewChild('viewAnlassModalComponent', { static: true }) viewAnlassModal: ViewAnlassModalComponent;
@ViewChild('entityTypeHistoryModal', { static: true }) entityTypeHistoryModal: EntityTypeHistoryModalComponent;
@ViewChild('dataTable', { static: true }) dataTable: Table;
@ViewChild('paginator', { static: true }) paginator: Paginator;
advancedFiltersAreShown = false;
filterText = '';
anlassTypFilter = '';
_entityTypeFullName = 'namespacex.MerkmaleSports.Anlass';
entityHistoryEnabled = false;
constructor(
injector: Injector,
private _anlassesServiceProxy: AnlassesServiceProxy,
private _notifyService: NotifyService,
private _tokenAuth: TokenAuthServiceProxy,
private _activatedRoute: ActivatedRoute,
private _fileDownloadService: FileDownloadService
) {
super(injector);
}
ngOnInit(): void {
this.entityHistoryEnabled = this.setIsEntityHistoryEnabled();
}
private setIsEntityHistoryEnabled(): boolean {
let customSettings = (abp as any).custom;
return customSettings.EntityHistory && customSettings.EntityHistory.isEnabled && _.filter(customSettings.EntityHistory.enabledEntities, entityType => entityType === this._entityTypeFullName).length === 1;
}
getAnlasses(event?: LazyLoadEvent) {
if (this.primengTableHelper.shouldResetPaging(event)) {
this.paginator.changePage(0);
return;
}
this.primengTableHelper.showLoadingIndicator();
this._anlassesServiceProxy.getAll(
this.filterText,
this.anlassTypFilter,
this.primengTableHelper.getSorting(this.dataTable),
this.primengTableHelper.getSkipCount(this.paginator, event),
this.primengTableHelper.getMaxResultCount(this.paginator, event)
).subscribe(result => {
this.primengTableHelper.totalRecordsCount = result.totalCount;
this.primengTableHelper.records = result.items;
this.primengTableHelper.hideLoadingIndicator();
});
}
reloadPage(): void {
this.paginator.changePage(this.paginator.getPage());
}
createAnlass(): void {
this.createOrEditAnlassModal.show();
}
showHistory(anlass: AnlassDto): void {
this.entityTypeHistoryModal.show({
entityId: anlass.id.toString(),
entityTypeFullName: this._entityTypeFullName,
entityTypeDescription: ''
});
}
deleteAnlass(anlass: AnlassDto): void {
this.message.confirm(
'',
(isConfirmed) => {
if (isConfirmed) {
this._anlassesServiceProxy.delete(anlass.id)
.subscribe(() => {
this.reloadPage();
this.notify.success(this.l('SuccessfullyDeleted'));
});
}
}
);
}
exportToExcel(): void {
this._anlassesServiceProxy.getAnlassesToExcel(
this.filterText,
this.anlassTypFilter,
)
.subscribe(result => {
this._fileDownloadService.downloadTempFile(result);
});
}
}
Thank you for your help.
Best, Tuna
Hi,
I'm trying to implement the tutorial for the PhoneBook for AspNet Core & Angular (here) and am failing in the last step when trying to run the application.
I added the documented source code to both projects, Core & Angular. Core is building & executing fine. I also executed nswag. But somehow the both components AddPhoneInputType
and PhoneInPersonListDtoType
that are required by Angular's phonebook.component.ts
file are missing in the service-proxies.ts
. I noticed that they are also missing in the Swagger UI. So somehow they are not part of the API interface.
What am I missing?
Thanks, Tuna
Hi,
I wanted to ask if anyone has experiences setting up Asp.Net Zero with Azure & SendGrid? The default fields for setting up SMTP don't match to the configuration settings of SendGrid so I wonder how to get that work.
Thanks for your feedback, Regards, Tuna
Hi Halil Ibrahim,
in our project, where we are using the tenant/host distinction, we also have a use case of a call-center where the agents are expected to have a global access to all tenants' tickets in the system (imagine it as a kind of 'superview‘ if you like). No change for tenants, they will be able to create & edit their own data, namely tickets.
I'm not sure if this question was already covered in another topic or on GitHub (eventually issue #530 which seems to have similarity?) and wanted to ask for your advice on how to achieve this.
Generally I think that this feature would be very helpful in your Product (out-of-the-box).
Thank you very much in advance, Best regards, Tuna
I'm developing a mobile application (iOS/Android) with Xamarin (C#) and wanted to connect to my ASP.NET backend. I've read in the forum that I should just call Account/Login and use cookies for subsequent requests. I haven't really tried the last part yet (I guess it should work fine with cookies), but I've got a question to the first one.
I'm using RestSharp in my project and calling Account/Login is no problem. Just some easy-to-understand code of the request to put this in context:
RestRequest request = new RestRequest ("Account/Login", Method.POST);
request.AddParameter ("tenancyName", "foo");
request.AddParameter ("usernameOrEmailAddress", "bar");
request.AddParameter ("password", "baz");
If the login is successful, I get this JSON response:
{
"targetUrl": "/Application",
"success": true,
"result": null,
"error": null,
"unAuthorizedRequest": false
}
This is great! I can work with that. But if the credentials are wrong, I get an HTML response (and not a JSON response) and this is something I can't parse. Is there a way to always get a JSON response? I've already tried this:
request.AddHeader("Accept", "application/json");
But that doesn't seem to do anything. Is there some way to achieve this?