mirror of https://github.com/abpframework/abp.git
28 changed files with 521 additions and 18 deletions
@ -0,0 +1,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.MultiTenancy.HttpApi</AssemblyName> |
|||
<PackageId>Volo.Abp.MultiTenancy.HttpApi</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="2.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc\Volo.Abp.AspNetCore.Mvc.csproj" /> |
|||
<ProjectReference Include="..\Volo.Abp.MultiTenancy.Application\Volo.Abp.MultiTenancy.Application.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,26 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.MultiTenancy |
|||
{ |
|||
[DependsOn(typeof(AbpMultiTenancyApplicationModule), typeof(AbpAspNetCoreMvcModule))] |
|||
public class AbpMultiTenancyHttpApiModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddAssemblyOf<AbpMultiTenancyHttpApiModule>(); |
|||
|
|||
services.Configure<AbpAspNetCoreMvcOptions>(options => |
|||
{ |
|||
options.ConventionalControllers.Create( |
|||
typeof(AbpMultiTenancyApplicationModule).Assembly, |
|||
opts => |
|||
{ |
|||
opts.RootPath = "multi-tenancy"; |
|||
} |
|||
); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using AutoMapper; |
|||
using Volo.Abp.MultiTenancy.Web.Pages.MultiTenancy.Tenants; |
|||
|
|||
namespace Volo.Abp.MultiTenancy.Web |
|||
{ |
|||
public class AbpMultiTenancyWebAutoMapperProfile : Profile |
|||
{ |
|||
public AbpMultiTenancyWebAutoMapperProfile() |
|||
{ |
|||
CreateRoleMappings(); |
|||
} |
|||
|
|||
private void CreateRoleMappings() |
|||
{ |
|||
//List
|
|||
CreateMap<TenantDto, EditModalModel.TenantInfoModel>(); |
|||
|
|||
//CreateModal
|
|||
CreateMap<CreateModalModel.TenantInfoModel, TenantCreateDto>(); |
|||
|
|||
//EditModal
|
|||
CreateMap<EditModalModel.TenantInfoModel, TenantUpdateDto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,6 +1,7 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
|
|||
"NewTenant": "New tenant", |
|||
"TenantName": "Tenant name" |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
@page |
|||
@using Microsoft.Extensions.Localization |
|||
@using Volo.Abp.MultiTenancy.Web.Localization.Resources.AbpMultiTenancy |
|||
@using Volo.Abp.MultiTenancy.Web.Pages.MultiTenancy.Tenants |
|||
@model CreateModalModel |
|||
@inject IStringLocalizer<AbpMultiTenancyResource> L |
|||
@{ |
|||
Layout = null; |
|||
} |
|||
|
|||
<form method="post" asp-page="/MultiTenancy/Tenants/CreateModal"> |
|||
|
|||
<abp-modal> |
|||
|
|||
<abp-modal-header title="@L["NewTenant"]"></abp-modal-header> |
|||
|
|||
<abp-modal-body> |
|||
|
|||
<div class="form-group"> |
|||
<label asp-for="TenantModel.Name"></label> |
|||
<input asp-for="TenantModel.Name" class="form-control" /> |
|||
<span asp-validation-for="TenantModel.Name" class="text-danger"></span> |
|||
</div> |
|||
|
|||
<div asp-validation-summary="All" class="text-danger"></div> |
|||
|
|||
</abp-modal-body> |
|||
|
|||
<abp-modal-footer></abp-modal-footer> |
|||
|
|||
</abp-modal> |
|||
|
|||
</form> |
|||
@ -0,0 +1,38 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.RazorPages; |
|||
|
|||
namespace Volo.Abp.MultiTenancy.Web.Pages.MultiTenancy.Tenants |
|||
{ |
|||
public class CreateModalModel : AbpPageModel |
|||
{ |
|||
[BindProperty] |
|||
public TenantInfoModel TenantModel { get; set; } |
|||
|
|||
private readonly ITenantAppService _tenantAppService; |
|||
|
|||
public CreateModalModel(ITenantAppService tenantAppService) |
|||
{ |
|||
_tenantAppService = tenantAppService; |
|||
} |
|||
|
|||
public async Task<IActionResult> OnPostAsync() |
|||
{ |
|||
ValidateModel(); |
|||
|
|||
var input = ObjectMapper.Map<TenantInfoModel, TenantCreateDto>(TenantModel); |
|||
await _tenantAppService.CreateAsync(input); |
|||
|
|||
return NoContent(); |
|||
} |
|||
|
|||
public class TenantInfoModel |
|||
{ |
|||
[Required] |
|||
[StringLength(TenantConsts.MaxNameLength)] |
|||
[Display(Name = "TenantName")] |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
@page |
|||
@using Microsoft.Extensions.Localization |
|||
@using Volo.Abp.MultiTenancy.Web.Localization.Resources.AbpMultiTenancy |
|||
@using Volo.Abp.MultiTenancy.Web.Pages.MultiTenancy.Tenants |
|||
@model EditModalModel |
|||
@inject IStringLocalizer<AbpMultiTenancyResource> L |
|||
@{ |
|||
Layout = null; |
|||
} |
|||
|
|||
<form method="post" asp-page="/MultiTenancy/Tenants/EditModal" autocomplete="off"> |
|||
|
|||
<abp-modal> |
|||
|
|||
<abp-modal-header title="@L["Edit"]"></abp-modal-header> |
|||
|
|||
<abp-modal-body> |
|||
|
|||
<input asp-for="TenantInfo.Id" /> |
|||
|
|||
<div class="form-group"> |
|||
<label asp-for="TenantInfo.Name"></label> |
|||
<input asp-for="TenantInfo.Name" class="form-control"/> |
|||
<span asp-validation-for="TenantInfo.Name" class="text-danger"></span> |
|||
</div> |
|||
|
|||
<div asp-validation-summary="All" class="text-danger"></div> |
|||
|
|||
</abp-modal-body> |
|||
|
|||
<abp-modal-footer></abp-modal-footer> |
|||
|
|||
</abp-modal> |
|||
|
|||
</form> |
|||
@ -0,0 +1,49 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.RazorPages; |
|||
|
|||
namespace Volo.Abp.MultiTenancy.Web.Pages.MultiTenancy.Tenants |
|||
{ |
|||
public class EditModalModel : AbpPageModel |
|||
{ |
|||
[BindProperty] |
|||
public TenantInfoModel TenantInfo { get; set; } |
|||
|
|||
private readonly ITenantAppService _tenantAppService; |
|||
|
|||
public EditModalModel(ITenantAppService tenantAppService) |
|||
{ |
|||
_tenantAppService = tenantAppService; |
|||
} |
|||
|
|||
public async Task OnGetAsync(Guid id) |
|||
{ |
|||
TenantInfo = ObjectMapper.Map<TenantDto, TenantInfoModel>( |
|||
await _tenantAppService.GetAsync(id) |
|||
); |
|||
} |
|||
|
|||
public async Task<IActionResult> OnPostAsync() |
|||
{ |
|||
ValidateModel(); |
|||
|
|||
var input = ObjectMapper.Map<TenantInfoModel, TenantUpdateDto>(TenantInfo); |
|||
await _tenantAppService.UpdateAsync(TenantInfo.Id, input); |
|||
|
|||
return NoContent(); |
|||
} |
|||
|
|||
public class TenantInfoModel |
|||
{ |
|||
[HiddenInput] |
|||
public Guid Id { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(TenantConsts.MaxNameLength)] |
|||
[Display(Name = "TenantName")] |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -1,7 +1,45 @@ |
|||
@page |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.MultiTenancy.Web.Localization.Resources.AbpMultiTenancy |
|||
@using Volo.Abp.MultiTenancy.Web.Pages.MultiTenancy.Tenants |
|||
@model IndexModel |
|||
@{ |
|||
} |
|||
@inject IHtmlLocalizer<AbpMultiTenancyResource> L |
|||
@section styles { |
|||
<link rel="stylesheet" type="text/css" href="~/modules/multi-tenancy/views/tenants/index.css" /> |
|||
} |
|||
|
|||
@section scripts { |
|||
<script type="text/javascript" src="~/abp/helpers/jquery.js"></script> |
|||
<script type="text/javascript" src="~/abp/helpers/datatables.extensions.js"></script> |
|||
<script type="text/javascript" src="~/abp/helpers/ResourceLoader.js"></script> |
|||
<script type="text/javascript" src="~/abp/helpers/ModalManager.js"></script> |
|||
<script type="text/javascript" src="~/modules/multi-tenancy/views/tenants/index.js"></script> |
|||
} |
|||
|
|||
Tenants page... |
|||
<abp-card id="TenantsWrapper"> |
|||
<abp-card-header> |
|||
<div class="row"> |
|||
<div class="col-md-6"> |
|||
<h2>@L["Tenants"]</h2> |
|||
</div> |
|||
<div class="col-md-6 text-right"> |
|||
<button type="button" class="btn btn-primary" v-on:click="openCreateModal"> |
|||
<i class="fa fa-plus" aria-hidden="true"></i> |
|||
@L["NewTenant"] |
|||
</button> |
|||
</div> |
|||
</div> |
|||
</abp-card-header> |
|||
<abp-card-body> |
|||
<table class="table table-striped nowrap"> |
|||
<thead> |
|||
<tr> |
|||
<th>@L["Actions"]</th> |
|||
<th>@L["Name"]</th> |
|||
</tr> |
|||
</thead> |
|||
</table> |
|||
</abp-card-body> |
|||
</abp-card> |
|||
@ -0,0 +1,2 @@ |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@ -0,0 +1,6 @@ |
|||
[ |
|||
{ |
|||
"outputFile": "wwwroot/modules/multi-tenancy/views/tenants/index.css", |
|||
"inputFile": "wwwroot/modules/multi-tenancy/views/tenants/index.less" |
|||
} |
|||
] |
|||
@ -0,0 +1,49 @@ |
|||
{ |
|||
"compilers": { |
|||
"less": { |
|||
"autoPrefix": "", |
|||
"cssComb": "none", |
|||
"ieCompat": true, |
|||
"strictMath": false, |
|||
"strictUnits": false, |
|||
"relativeUrls": true, |
|||
"rootPath": "", |
|||
"sourceMapRoot": "", |
|||
"sourceMapBasePath": "", |
|||
"sourceMap": false |
|||
}, |
|||
"sass": { |
|||
"includePath": "", |
|||
"indentType": "space", |
|||
"indentWidth": 2, |
|||
"outputStyle": "nested", |
|||
"Precision": 5, |
|||
"relativeUrls": true, |
|||
"sourceMapRoot": "", |
|||
"sourceMap": false |
|||
}, |
|||
"stylus": { |
|||
"sourceMap": false |
|||
}, |
|||
"babel": { |
|||
"sourceMap": false |
|||
}, |
|||
"coffeescript": { |
|||
"bare": false, |
|||
"runtimeMode": "node", |
|||
"sourceMap": false |
|||
} |
|||
}, |
|||
"minifiers": { |
|||
"css": { |
|||
"enabled": true, |
|||
"termSemicolons": true, |
|||
"gzip": false |
|||
}, |
|||
"javascript": { |
|||
"enabled": true, |
|||
"termSemicolons": true, |
|||
"gzip": false |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
.dataTable { |
|||
width: 100% !important; |
|||
border-spacing: 0 !important; |
|||
} |
|||
.table td, |
|||
.table th { |
|||
padding: 8px 10px; |
|||
} |
|||
.dataTable tbody tr td button { |
|||
cursor: pointer; |
|||
} |
|||
.dataTable tbody tr td div.dropdown ul.dropdown-menu li { |
|||
cursor: pointer; |
|||
padding: 5px; |
|||
} |
|||
.dataTable tbody tr td div.dropdown ul.dropdown-menu li a { |
|||
display: block; |
|||
} |
|||
.dataTable tbody tr td div.dropdown ul.dropdown-menu li:hover { |
|||
background: #f4f5f8; |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
'use strict'; |
|||
|
|||
$(function () { |
|||
$('#IdentityUsersTable').DataTable(); |
|||
}); |
|||
|
|||
@ -0,0 +1 @@ |
|||
"use strict";$(function(){$("#IdentityUsersTable").DataTable()}); |
|||
@ -0,0 +1,84 @@ |
|||
(function () { |
|||
|
|||
var l = abp.localization.getResource('AbpMultiTenancy'); |
|||
var _tenantAppService = volo.abp.multiTenancy.tenant; |
|||
|
|||
var _editModal = new abp.ModalManager(abp.appPath + 'MultiTenancy/Tenants/EditModal'); |
|||
var _createModal = new abp.ModalManager(abp.appPath + 'MultiTenancy/Tenants/CreateModal'); |
|||
|
|||
var app = new Vue({ |
|||
el: '#TenantsWrapper', |
|||
methods: { |
|||
openCreateModal: function () { |
|||
_createModal.open(); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
$(function () { |
|||
|
|||
var _$wrapper = $('#TenantsWrapper'); |
|||
var _$table = _$wrapper.find('table'); |
|||
|
|||
var _dataTable = _$table.DataTable({ |
|||
order: [[1, "asc"]], |
|||
ajax: abp.libs.datatables.createAjax(_tenantAppService.getList), |
|||
columnDefs: [ |
|||
{ |
|||
//TODO: Can we eleminate targets, data, orderable, autoWidth, defaultContent fields or make these values default
|
|||
targets: 0, |
|||
data: null, |
|||
orderable: false, |
|||
autoWidth: false, |
|||
defaultContent: '', |
|||
rowAction: { |
|||
text: '<i class="fa fa-cog"></i> ' + l('Actions') + ' <span class="caret"></span>', //TODO: Add icon option and set text as only l('Actions')
|
|||
items: |
|||
[ |
|||
{ |
|||
//TODO: Allow to add icon
|
|||
text: l('Edit'), |
|||
visible: function () { //TODO: Allow visible to be a boolean for simple cases
|
|||
return true; |
|||
}, |
|||
action: function (data) { |
|||
_editModal.open({ |
|||
id: data.record.id |
|||
}); |
|||
} |
|||
}, |
|||
{ |
|||
text: l('Delete'), |
|||
visible: function () { |
|||
return true; |
|||
}, |
|||
action: function (data) { |
|||
if (confirm(l('TenantDeletionConfirmationMessage', data.record.name))) { |
|||
_tenantAppService |
|||
.delete(data.record.id) |
|||
.then(function () { |
|||
_dataTable.ajax.reload(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
{ |
|||
targets: 1, |
|||
data: "name" |
|||
} |
|||
] |
|||
}); |
|||
|
|||
_createModal.onResult(function () { |
|||
_dataTable.ajax.reload(); |
|||
}); |
|||
|
|||
_editModal.onResult(function () { |
|||
_dataTable.ajax.reload(); |
|||
}); |
|||
}); |
|||
|
|||
})(); |
|||
@ -0,0 +1,39 @@ |
|||
//TODO: This code is duplicated for other pages too. Unify them. |
|||
.dataTable { |
|||
width: 100% !important; |
|||
border-spacing: 0 !important; |
|||
} |
|||
|
|||
.table td, .table th { |
|||
padding: 8px 10px; |
|||
} |
|||
|
|||
.dataTable { |
|||
tbody { |
|||
tr { |
|||
td { |
|||
|
|||
button { |
|||
cursor: pointer; |
|||
} |
|||
|
|||
div.dropdown { |
|||
ul.dropdown-menu { |
|||
li { |
|||
cursor: pointer; |
|||
padding: 5px; |
|||
|
|||
a { |
|||
display: block; |
|||
} |
|||
} |
|||
|
|||
li:hover { |
|||
background: #f4f5f8; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1 @@ |
|||
.dataTable{width:100% !important;border-spacing:0 !important;}.table td,.table th{padding:8px 10px;}.dataTable tbody tr td button{cursor:pointer;}.dataTable tbody tr td div.dropdown ul.dropdown-menu li{cursor:pointer;padding:5px;}.dataTable tbody tr td div.dropdown ul.dropdown-menu li a{display:block;}.dataTable tbody tr td div.dropdown ul.dropdown-menu li:hover{background:#f4f5f8;} |
|||
Loading…
Reference in new issue