Base solution for your next web application

Activities of "BigCDogCrew"

I have managed to corrupt some of the files in the metronic folderof my ASP.NET Zero MVC prroject and I want to rebuild the folder structure by downloading the current version (6.0.6).

For the sake of future readers..let's assume that all projects within the ASP.NET Zero solution need to be updated.

What is the process for updating the Metronic template in the MVC project?
Which folders and files do I need to copy from the Metronic ZIP file and into which folders do I place them?

How can I access a custom session from the client-side razor script?

The information in my database is structured like a supply chain. Some, but not all, information that tenants create must be available to other tenants down-stream. I have used the OrganizationUnits to construct the relationships between the tenants. I have also created custom filters that work with the OrganizationUnits, such as IncludeTenantChildren, IncludeTenantParent, IncludeTenantBranch, etc.

As I am now working on the more intricate details of my queries, I am finding that there are many times where an initial table determines what data should be seen by a tenant and then other subsequent tables are included in the query to provide additional details. However, those additional details in those subsequent tables come from data maintained by other tenants. Therefore, I need a simple way to state that the TenantId Filter should be applied only to a specific set (0 or more) of tables in the query and the other tables in the query should be treated as if the TenantId filters have been disabled.

As an example, a tenant may create a Package and then transfer the package to another tenant within their Organization. The TenantId on the Package table gets updated to the new tenant during the transfer process. Now, assume that there are two other tables, PackageContent and PackageTracking which both are linked to Package by PackageId. Data in the PackageContent table should be available only to the creator of the package and the recipient of the package. Data in the PackageTracking table should be available to anyone currently holding tenancy of the package.

So you see...having a TenantId filter that applies to all tables in the query will prevent the package recipient from seeing the PackageContent create by a different tenent. And each tenant will be able to see only the tracking records that they create themselves; not the full tracking history.

What's the best way to selectively apply the TenantId to specific tables (such as Package) and then ignore the TenantId filter on other tables (such as PackageContent and PackageTracking)? It is safe to assume that my custom filters are determining when/if it is appropriate to show PackageContent to the recipient.

What tool did the AspNetZero team use to produce the documentation website? https://docs.aspnetzero.com/en/common/latest

ScrollX does not appear to work. I'm using AspNetZero v8.6 MVC/jQuery. I am using no custom scripts or css. My sample code and result image are shown below.

What am I doing wrong?

var dataTable = _$peripheralsTable.DataTable({
	scrollX: true,
	paging: true,
	serverSide: true,
	processing: true,
	listAction: {
		ajaxFunction: _peripheralsService.getAll,
		inputFilter: function () {
			return {
				filter: $('#PeripheralsTableFilter').val(),
			};
		}
	},
	columnDefs: [{
		width: 120,
		targets: 0,
		data: null,
		orderable: false,
		autoWidth: false,
		defaultContent: '',
		rowAction: {
			cssClass: 'btn btn-brand dropdown-toggle',
			text: '<i class="fa fa-cog"></i> ' + app.localize('Actions') + ' <span class="caret"></span>',
			items: [
			{
				text: app.localize('View'),
				action: function (data) {
					_viewPeripheralModal.open({ id: data.record.peripheral.id });
				}
			},
			{
				text: app.localize('Edit'),
				visible: function () {
					return _permissions.edit;
				},
				action: function (data) {
					_createOrEditModal.open({ id: data.record.peripheral.id });
				}
			}]
		}
	},
	{
		targets: 1,
		visible: false,
		data: "peripheral.uid",
		name: "uid"   	
	},
	{
		targets: 2,
		data: "peripheral.serialNumber",
		name: "serialNumber"   
	},
	{
		targets: 3,
		data: "peripheral.assetTag",
		name: "assetTag"   
	},
	{
		targets: 4,
		data: "peripheral.firmwareVersion",
		name: "firmwareVersion"
	},
	{
		targets: 5,
		data: "peripheralModelCode" ,
		name: "peripheralModelFk.code" 
	}]
});

When I attempt to use the CDN source for DataTables, I get an error. So, I assume AspNetZero has customized its implementation of DataTables (and perhaps missed something with ScrollX?)

@section Styles
{
    <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css" />
}
@section Scripts
{
    <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
    <script abp-src="/view-resources/Areas/App/Views/Peripherals/Index.js" asp-append-version="true"></script>
}

For good measure...here is the cshtml for the sample. Advanced Filtering has been removed and the project name has been changed (to protect the innocent).

@using ProjectX.Authorization
@using ProjectX.Web.Areas.App.Models.Peripherals
@using ProjectX.Web.Areas.App.Startup
@model PeripheralsViewModel
@{
    ViewBag.CurrentPageName = AppPageNames.Common.Peripherals;
}
@section Scripts
{
    <script abp-src="/view-resources/Areas/App/Views/Peripherals/Index.js" asp-append-version="true"></script>
}
<div class="kt-content  kt-grid__item kt-grid__item--fluid kt-grid kt-grid--hor">
    <div class="kt-subheader kt-grid__item">
        <div class="@(await GetContainerClass())">
            <div class="kt-subheader__main">
                <h3 class="kt-subheader__title">
                    <span>@L("Peripherals")</span>
                </h3>
                <span class="kt-subheader__separator kt-subheader__separator--v"></span>
                <span class="kt-subheader__desc">
                    @L("PeripheralsHeaderInfo")
                </span>
            </div>
            <div class="kt-subheader__toolbar">
                <div class="kt-subheader__wrapper">
                    <button id="ExportToExcelButton" class="btn btn-outline-success"><i class="fa fa-file-excel"></i> @L("ExportToExcel")</button>
                    @if (IsGranted(AppPermissions.Pages_Peripherals_Create))
                    {
                        <button id="CreateNewPeripheralButton" class="btn btn-primary blue"><i class="fa fa-plus"></i> @L("Peripheral_CreateNew")</button>
                    }
                </div>
            </div>
        </div>
    </div>
    <div class="@(await GetContainerClass()) kt-grid__item kt-grid__item--fluid">
        <div class="kt-portlet kt-portlet--mobile">
            <div class="kt-portlet__body">
                <div class="kt-form">
                    <div class="row align-items-center mb-4">
                        <div class="col-xl-12">
                            <div class="form-group align-items-center">
                                <div class="input-group">
                                    <input type="text" id="PeripheralsTableFilter" class="form-control m-input" placeholder="@L("SearchWithThreeDot")" value="@Model.FilterText">
                                    <span class="input-group-btn">
                                        <button id="GetPeripheralsButton" class="btn btn-primary" type="submit"><i class="flaticon-search-1"></i></button>
                                    </span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="row align-items-center">
                    <table id="PeripheralsTable" class="display table table-striped table-bordered table-hover dt-responsive">
                        <thead>
                            <tr>
                                <th>@L("Actions")</th>
                                <th>@L("UID")</th>
                                <th>@L("SerialNumber")</th>
                                <th>@L("AssetTag")</th>
                                <th>@L("FirmwareVersion")</th>
                                <th>@L("PeripheralModelCode")</th>
                            </tr>
                        </thead>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>

I found and applied the Metronic CSS class "table-scrollable". But that did not work.

I found an article on the DataTables Forum regarding ScrollX not working (actually reviewed that before posting this issue). That article led me to try a few style adjustments...but these did not work either.

<style>
.dataTables_scrollBody table {
    margin-left:0px;
}
.dataTables_blockRequired {
    display:inline-block; 
}
</style>

First, thank you to the whole AspNetTeam for being so responsive. I've submitted at least half a dozen emails and a few more support forum posts. The AspNetZero team has always answered within 24-48 hours. You're doing fantastic and the product is great.

Your solution works great too. I was able to find the CSS by searching for "dataTables_paginate" class. It was then a simple matter of removing the "div.bottom" descendant requirement. My resulting custom style script (as I left the original intact), follows below.

I'll do a little more work to make sure that the style update is bundled and that the appropriate theme styles are updated. Thanks, again.

P.S. - there may be a simple update that the AspNetZero team can do to fix this styling holistically for future users...and maybe autoset those DOM and RESPONSIVE options when scrollX is true and those options have not been specified yet.

<style>
    /*Pagination*/
    .dataTables_wrapper div.dataTables_paginate ul li {
      padding: 0;
      margin-right: 5px;
      display: inline-block;
    }
    .dataTables_wrapper div.dataTables_paginate ul li a {
      cursor: pointer;
      display: inline-block;
      height: 2.25rem;
      width: 2.25rem;
      padding: 0;
      -webkit-border-radius: 50%;
      -moz-border-radius: 50%;
      -ms-border-radius: 50%;
      -o-border-radius: 50%;
      border-radius: 50%;
      position: relative;
      display: -webkit-box;
      display: -moz-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-justify-content: center;
      -moz-justify-content: center;
      -ms-justify-content: center;
      justify-content: center;
      -webkit-align-items: center;
      -moz-align-items: center;
      -ms-align-items: center;
      align-items: center;
      text-align: center;
      vertical-align: middle;
      font-size: 1rem;
      line-height: 1rem;
      font-weight: 400;
    }
    .dataTables_wrapper div.dataTables_paginate ul li a {
      text-decoration: none;
    }

    .dataTables_wrapper div.dataTables_paginate ul li.active a,
    .dataTables_wrapper div.dataTables_paginate ul li.active a:hover {
        background: #5867dd;
        color: #fff;
    }

    .dataTables_wrapper div.dataTables_paginate ul li a:hover {
        background-color: #deddf3;
    }

    .dataTables_wrapper div.dataTables_paginate ul li a {
        background-color: #edecf8;
    }

</style>

After playing around with this issue a little more, it appears as though setting only two options are sufficient to make the scroll work properly.

scrollX: true,
responsive: false

However, it's very possible that I did not catch or reproduce the scenario where the "dom" option becomes necessary. Will you please provide some clarity as to why and when the dom option should be used?

Thanks.

Showing 1 to 10 of 46 entries