mirror of https://github.com/abpframework/abp.git
562 changed files with 50273 additions and 43136 deletions
File diff suppressed because it is too large
@ -1,33 +0,0 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Options; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Ldap; |
|||
|
|||
public class AbpAbpLdapOptionsManager : AbpDynamicOptionsManager<AbpLdapOptions> |
|||
{ |
|||
protected ISettingProvider SettingProvider { get; } |
|||
|
|||
public AbpAbpLdapOptionsManager(IOptionsFactory<AbpLdapOptions> factory, ISettingProvider settingProvider) |
|||
: base(factory) |
|||
{ |
|||
SettingProvider = settingProvider; |
|||
} |
|||
|
|||
protected override async Task OverrideOptionsAsync(string name, AbpLdapOptions options) |
|||
{ |
|||
options.ServerHost = await GetSettingOrDefaultValue(LdapSettingNames.ServerHost, options.ServerHost); |
|||
options.ServerPort = await SettingProvider.GetAsync(LdapSettingNames.ServerPort, options.ServerPort); |
|||
options.BaseDc = await GetSettingOrDefaultValue(LdapSettingNames.BaseDc, options.BaseDc); |
|||
options.UserName = await GetSettingOrDefaultValue(LdapSettingNames.UserName, options.UserName); |
|||
options.Password = await GetSettingOrDefaultValue(LdapSettingNames.Password, options.Password); |
|||
} |
|||
|
|||
protected virtual async Task<string> GetSettingOrDefaultValue(string name, string defaultValue) |
|||
{ |
|||
var value = await SettingProvider.GetOrNullAsync(name); |
|||
return value.IsNullOrWhiteSpace() ? defaultValue : value; |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
namespace Volo.Abp.Ldap; |
|||
|
|||
public class AbpLdapOptions |
|||
{ |
|||
public string ServerHost { get; set; } |
|||
|
|||
public int ServerPort { get; set; } |
|||
|
|||
public string BaseDc { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// BindDN
|
|||
/// </summary>
|
|||
public string UserName { get; set; } |
|||
|
|||
/// <summary>
|
|||
///BindPassword
|
|||
/// </summary>
|
|||
public string Password { get; set; } |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Ldap; |
|||
|
|||
public interface ILdapSettingProvider |
|||
{ |
|||
public Task<string> GetServerHostAsync(); |
|||
|
|||
public Task<int> GetServerPortAsync(); |
|||
|
|||
public Task<string> GetBaseDcAsync(); |
|||
|
|||
public Task<string> GetDomainAsync(); |
|||
|
|||
public Task<string> GetUserNameAsync(); |
|||
|
|||
public Task<string> GetPasswordAsync(); |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
using Volo.Abp.Ldap.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Ldap; |
|||
|
|||
public class LdapSettingDefinitionProvider : SettingDefinitionProvider |
|||
{ |
|||
public override void Define(ISettingDefinitionContext context) |
|||
{ |
|||
context.Add( |
|||
new SettingDefinition( |
|||
LdapSettingNames.ServerHost, |
|||
"", |
|||
L("DisplayName:Abp.Ldap.ServerHost"), |
|||
L("Description:Abp.Ldap.ServerHost")), |
|||
|
|||
new SettingDefinition( |
|||
LdapSettingNames.ServerPort, |
|||
"389", |
|||
L("DisplayName:Abp.Ldap.ServerPort"), |
|||
L("Description:Abp.Ldap.ServerPort")), |
|||
|
|||
new SettingDefinition( |
|||
LdapSettingNames.BaseDc, |
|||
"", |
|||
L("DisplayName:Abp.Ldap.BaseDc"), |
|||
L("Description:Abp.Ldap.BaseDc")), |
|||
|
|||
new SettingDefinition( |
|||
LdapSettingNames.Domain, |
|||
"", |
|||
L("DisplayName:Abp.Ldap.Domain"), |
|||
L("Description:Abp.Ldap.Domain")), |
|||
|
|||
new SettingDefinition( |
|||
LdapSettingNames.UserName, |
|||
"", |
|||
L("DisplayName:Abp.Ldap.UserName"), |
|||
L("Description:Abp.Ldap.UserName")), |
|||
|
|||
new SettingDefinition( |
|||
LdapSettingNames.Password, |
|||
"", |
|||
L("DisplayName:Abp.Ldap.Password"), |
|||
L("Description:Abp.Ldap.Password"), |
|||
isEncrypted: true) |
|||
); |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<LdapResource>(name); |
|||
} |
|||
} |
|||
@ -1,49 +1,46 @@ |
|||
using Volo.Abp.Ldap.Localization; |
|||
using Volo.Abp.Localization; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Ldap; |
|||
|
|||
public class LdapSettingProvider : SettingDefinitionProvider |
|||
public class LdapSettingProvider : ILdapSettingProvider, ITransientDependency |
|||
{ |
|||
public override void Define(ISettingDefinitionContext context) |
|||
protected ISettingProvider SettingProvider { get; } |
|||
|
|||
public LdapSettingProvider(ISettingProvider settingProvider) |
|||
{ |
|||
SettingProvider = settingProvider; |
|||
} |
|||
|
|||
public async Task<string> GetServerHostAsync() |
|||
{ |
|||
return await SettingProvider.GetOrNullAsync(LdapSettingNames.ServerHost); |
|||
} |
|||
|
|||
public async Task<int> GetServerPortAsync() |
|||
{ |
|||
return (await SettingProvider.GetOrNullAsync(LdapSettingNames.ServerPort))?.To<int>() ?? default; |
|||
} |
|||
|
|||
public async Task<string> GetBaseDcAsync() |
|||
{ |
|||
return await SettingProvider.GetOrNullAsync(LdapSettingNames.BaseDc); |
|||
} |
|||
|
|||
public async Task<string> GetDomainAsync() |
|||
{ |
|||
return await SettingProvider.GetOrNullAsync(LdapSettingNames.Domain); |
|||
} |
|||
|
|||
public async Task<string> GetUserNameAsync() |
|||
{ |
|||
context.Add( |
|||
new SettingDefinition( |
|||
LdapSettingNames.ServerHost, |
|||
"", |
|||
L("DisplayName:Abp.Ldap.ServerHost"), |
|||
L("Description:Abp.Ldap.ServerHost")), |
|||
|
|||
new SettingDefinition( |
|||
LdapSettingNames.ServerPort, |
|||
"389", |
|||
L("DisplayName:Abp.Ldap.ServerPort"), |
|||
L("Description:Abp.Ldap.ServerPort")), |
|||
|
|||
new SettingDefinition( |
|||
LdapSettingNames.BaseDc, |
|||
"", |
|||
L("DisplayName:Abp.Ldap.BaseDc"), |
|||
L("Description:Abp.Ldap.BaseDc")), |
|||
|
|||
new SettingDefinition( |
|||
LdapSettingNames.UserName, |
|||
"", |
|||
L("DisplayName:Abp.Ldap.UserName"), |
|||
L("Description:Abp.Ldap.UserName")), |
|||
|
|||
new SettingDefinition( |
|||
LdapSettingNames.Password, |
|||
"", |
|||
L("DisplayName:Abp.Ldap.Password"), |
|||
L("Description:Abp.Ldap.Password"), |
|||
isEncrypted: true) |
|||
); |
|||
return await SettingProvider.GetOrNullAsync(LdapSettingNames.UserName); |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
public async Task<string> GetPasswordAsync() |
|||
{ |
|||
return LocalizableString.Create<LdapResource>(name); |
|||
return await SettingProvider.GetOrNullAsync(LdapSettingNames.Password); |
|||
} |
|||
} |
|||
|
|||
@ -1,20 +0,0 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using Shouldly; |
|||
using Volo.Abp.Testing; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Ldap; |
|||
|
|||
public class LdapOptions_Tests : AbpIntegratedTest<AbpLdapTestModule> |
|||
{ |
|||
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
|||
{ |
|||
options.UseAutofac(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Resolve_AbpAbpLdapOptionsFactory() |
|||
{ |
|||
GetRequiredService<IOptions<AbpLdapOptions>>().ShouldBeOfType(typeof(AbpAbpLdapOptionsManager)); |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Ldap; |
|||
|
|||
public class TestLdapSettingValueProvider : ISettingValueProvider, ITransientDependency |
|||
{ |
|||
public const string ProviderName = "Test"; |
|||
|
|||
public string Name => ProviderName; |
|||
|
|||
public Task<string> GetOrNullAsync(SettingDefinition setting) |
|||
{ |
|||
switch (setting.Name) |
|||
{ |
|||
case LdapSettingNames.ServerHost: |
|||
return Task.FromResult("localhost"); |
|||
|
|||
case LdapSettingNames.ServerPort: |
|||
return Task.FromResult("389"); |
|||
|
|||
case LdapSettingNames.BaseDc: |
|||
return Task.FromResult("dc=abp,dc=io"); |
|||
|
|||
case LdapSettingNames.Domain: |
|||
return Task.FromResult<string>(null); |
|||
|
|||
case LdapSettingNames.UserName: |
|||
return Task.FromResult("admin"); |
|||
|
|||
case LdapSettingNames.Password: |
|||
return Task.FromResult("123qwe"); |
|||
|
|||
default: |
|||
return Task.FromResult<string>(null); |
|||
} |
|||
} |
|||
|
|||
public Task<List<SettingValue>> GetAllAsync(SettingDefinition[] settings) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
@ -1,2 +1,3 @@ |
|||
export * from './localization.pipe'; |
|||
export * from './sort.pipe'; |
|||
export * from './to-injector.pipe'; |
|||
|
|||
@ -0,0 +1,28 @@ |
|||
import { InjectionToken, Injector, Pipe, PipeTransform } from '@angular/core'; |
|||
|
|||
export const INJECTOR_PIPE_DATA_TOKEN = new InjectionToken<PipeTransform>( |
|||
'INJECTOR_PIPE_DATA_TOKEN', |
|||
); |
|||
|
|||
@Pipe({ |
|||
name: 'toInjector', |
|||
}) |
|||
export class ToInjectorPipe implements PipeTransform { |
|||
constructor(private injector: Injector) {} |
|||
transform( |
|||
value: any, |
|||
token: InjectionToken<any> = INJECTOR_PIPE_DATA_TOKEN, |
|||
name = 'ToInjectorPipe', |
|||
): Injector { |
|||
return Injector.create({ |
|||
providers: [ |
|||
{ |
|||
provide: token, |
|||
useValue: value, |
|||
}, |
|||
], |
|||
parent: this.injector, |
|||
name, |
|||
}); |
|||
} |
|||
} |
|||
@ -1 +1,2 @@ |
|||
export * from './components'; |
|||
export * from './user-menu-items'; |
|||
|
|||
@ -0,0 +1,4 @@ |
|||
export const enum eUserMenuItems { |
|||
MyAccount = 'UserMenu.MyAccount', |
|||
Logout = 'UserMenu.Logout', |
|||
} |
|||
@ -1,2 +1,3 @@ |
|||
export * from './nav-item.provider'; |
|||
export * from './styles.provider'; |
|||
export * from './user-menu.provider'; |
|||
|
|||
@ -0,0 +1,44 @@ |
|||
import { AuthService, NAVIGATE_TO_MANAGE_PROFILE } from '@abp/ng.core'; |
|||
import { UserMenuService } from '@abp/ng.theme.shared'; |
|||
import { APP_INITIALIZER, Injector } from '@angular/core'; |
|||
import { eUserMenuItems } from '../enums/user-menu-items'; |
|||
|
|||
export const BASIC_THEME_USER_MENU_PROVIDERS = [ |
|||
{ |
|||
provide: APP_INITIALIZER, |
|||
useFactory: configureUserMenu, |
|||
deps: [Injector], |
|||
multi: true, |
|||
}, |
|||
]; |
|||
|
|||
export function configureUserMenu(injector: Injector) { |
|||
const userMenu = injector.get(UserMenuService); |
|||
const authService = injector.get(AuthService); |
|||
const navigateToManageProfile = injector.get(NAVIGATE_TO_MANAGE_PROFILE); |
|||
|
|||
return () => { |
|||
userMenu.addItems([ |
|||
{ |
|||
id: eUserMenuItems.MyAccount, |
|||
order: 100, |
|||
textTemplate: { |
|||
text: 'AbpAccount::MyAccount', |
|||
icon: 'fa fa-cog', |
|||
}, |
|||
action: () => navigateToManageProfile(), |
|||
}, |
|||
{ |
|||
id: eUserMenuItems.Logout, |
|||
order: 101, |
|||
textTemplate: { |
|||
text: 'AbpUi::Logout', |
|||
icon: 'fa fa-power-off', |
|||
}, |
|||
action: () => { |
|||
authService.logout().subscribe(); |
|||
}, |
|||
}, |
|||
]); |
|||
}; |
|||
} |
|||
@ -1,5 +1,6 @@ |
|||
export * from './common'; |
|||
export * from './confirmation'; |
|||
export * from './nav-item'; |
|||
export * from './statistics'; |
|||
export * from './toaster'; |
|||
export * from './nav-item'; |
|||
export * from './user-menu'; |
|||
|
|||
@ -0,0 +1,10 @@ |
|||
import { NavItem } from './nav-item'; |
|||
|
|||
export class UserMenu extends NavItem { |
|||
textTemplate?: UserMenuTextTemplate; |
|||
} |
|||
|
|||
export interface UserMenuTextTemplate { |
|||
text: string; |
|||
icon?: string; |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
import { BehaviorSubject, Observable } from 'rxjs'; |
|||
import { NavItem } from '../models/nav-item'; |
|||
|
|||
export abstract class AbstractMenuService<T extends NavItem> { |
|||
protected abstract baseClass; |
|||
|
|||
protected _items$ = new BehaviorSubject<T[]>([]); |
|||
|
|||
get items(): T[] { |
|||
return this._items$.value; |
|||
} |
|||
|
|||
get items$(): Observable<T[]> { |
|||
return this._items$.asObservable(); |
|||
} |
|||
|
|||
addItems(newItems: T[]) { |
|||
const items = [...this.items]; |
|||
newItems.forEach(item => { |
|||
const index = items.findIndex(i => i.id === item.id); |
|||
const data = new this.baseClass(item); |
|||
|
|||
if (index > -1) { |
|||
items[index] = data; |
|||
return; |
|||
} |
|||
|
|||
items.push(data); |
|||
}); |
|||
items.sort(this.sortItems); |
|||
this._items$.next(items); |
|||
} |
|||
|
|||
removeItem(id: string | number) { |
|||
const index = this.items.findIndex(item => item.id === id); |
|||
|
|||
if (index < 0) return; |
|||
|
|||
const items = [...this.items.slice(0, index), ...this.items.slice(index + 1)]; |
|||
this._items$.next(items); |
|||
} |
|||
|
|||
patchItem(id: string | number, item: Partial<Omit<T, 'id'>>) { |
|||
const index = this.items.findIndex(i => i.id === id); |
|||
|
|||
if (index < 0) return; |
|||
|
|||
const items = [...this.items]; |
|||
items[index] = new this.baseClass({ ...items[index], ...item }); |
|||
items.sort(this.sortItems); |
|||
this._items$.next(items); |
|||
} |
|||
|
|||
private sortItems(a: T, b: T) { |
|||
if (!a.order) return 1; |
|||
if (!b.order) return -1; |
|||
|
|||
return a.order - b.order; |
|||
} |
|||
} |
|||
@ -1,50 +1,8 @@ |
|||
import { Injectable } from '@angular/core'; |
|||
import { BehaviorSubject, Observable } from 'rxjs'; |
|||
import { NavItem } from '../models/nav-item'; |
|||
import { AbstractMenuService } from './abstract-menu.service'; |
|||
|
|||
@Injectable({ providedIn: 'root' }) |
|||
export class NavItemsService { |
|||
private _items$ = new BehaviorSubject<NavItem[]>([]); |
|||
|
|||
get items(): NavItem[] { |
|||
return this._items$.value; |
|||
} |
|||
|
|||
get items$(): Observable<NavItem[]> { |
|||
return this._items$.asObservable(); |
|||
} |
|||
|
|||
addItems(newItems: NavItem[]) { |
|||
const items = [...this.items]; |
|||
newItems.forEach(item => items.push(new NavItem(item))); |
|||
items.sort(sortItems); |
|||
this._items$.next(items); |
|||
} |
|||
|
|||
removeItem(id: string | number) { |
|||
const index = this.items.findIndex(item => item.id === id); |
|||
|
|||
if (index < 0) return; |
|||
|
|||
const items = [...this.items.slice(0, index), ...this.items.slice(index + 1)]; |
|||
this._items$.next(items); |
|||
} |
|||
|
|||
patchItem(id: string | number, item: Partial<Omit<NavItem, 'id'>>) { |
|||
const index = this.items.findIndex(i => i.id === id); |
|||
|
|||
if (index < 0) return; |
|||
|
|||
const items = [...this.items]; |
|||
items[index] = new NavItem({ ...items[index], ...item }); |
|||
items.sort(sortItems); |
|||
this._items$.next(items); |
|||
} |
|||
} |
|||
|
|||
function sortItems(a: NavItem, b: NavItem) { |
|||
if (!a.order) return 1; |
|||
if (!b.order) return -1; |
|||
|
|||
return a.order - b.order; |
|||
export class NavItemsService extends AbstractMenuService<NavItem> { |
|||
protected baseClass = NavItem; |
|||
} |
|||
|
|||
@ -0,0 +1,8 @@ |
|||
import { Injectable } from '@angular/core'; |
|||
import { UserMenu } from '../models/user-menu'; |
|||
import { AbstractMenuService } from './abstract-menu.service'; |
|||
|
|||
@Injectable({ providedIn: 'root' }) |
|||
export class UserMenuService extends AbstractMenuService<UserMenu> { |
|||
protected baseClass = UserMenu; |
|||
} |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,212 +0,0 @@ |
|||
table.dataTable { |
|||
clear: both; |
|||
margin-top: 6px !important; |
|||
margin-bottom: 6px !important; |
|||
max-width: none !important; |
|||
border-collapse: separate !important; |
|||
border-spacing: 0; |
|||
} |
|||
table.dataTable td, |
|||
table.dataTable th { |
|||
-webkit-box-sizing: content-box; |
|||
box-sizing: content-box; |
|||
} |
|||
table.dataTable td.dataTables_empty, |
|||
table.dataTable th.dataTables_empty { |
|||
text-align: center; |
|||
} |
|||
table.dataTable.nowrap th, |
|||
table.dataTable.nowrap td { |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_length label { |
|||
font-weight: normal; |
|||
text-align: left; |
|||
white-space: nowrap; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_length select { |
|||
width: auto; |
|||
display: inline-block; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_filter { |
|||
text-align: right; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_filter label { |
|||
font-weight: normal; |
|||
white-space: nowrap; |
|||
text-align: left; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_filter input { |
|||
margin-left: 0.5em; |
|||
display: inline-block; |
|||
width: auto; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_info { |
|||
padding-top: 0.85em; |
|||
white-space: nowrap; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_paginate { |
|||
margin: 0; |
|||
white-space: nowrap; |
|||
text-align: right; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_paginate ul.pagination { |
|||
margin: 2px 0; |
|||
white-space: nowrap; |
|||
justify-content: flex-end; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_processing { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
width: 200px; |
|||
margin-left: -100px; |
|||
margin-top: -26px; |
|||
text-align: center; |
|||
padding: 1em 0; |
|||
} |
|||
|
|||
table.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting, |
|||
table.dataTable thead > tr > td.sorting_asc, |
|||
table.dataTable thead > tr > td.sorting_desc, |
|||
table.dataTable thead > tr > td.sorting { |
|||
padding-right: 30px; |
|||
} |
|||
table.dataTable thead > tr > th:active, |
|||
table.dataTable thead > tr > td:active { |
|||
outline: none; |
|||
} |
|||
table.dataTable thead .sorting, |
|||
table.dataTable thead .sorting_asc, |
|||
table.dataTable thead .sorting_desc, |
|||
table.dataTable thead .sorting_asc_disabled, |
|||
table.dataTable thead .sorting_desc_disabled { |
|||
cursor: pointer; |
|||
position: relative; |
|||
} |
|||
table.dataTable thead .sorting:before, table.dataTable thead .sorting:after, |
|||
table.dataTable thead .sorting_asc:before, |
|||
table.dataTable thead .sorting_asc:after, |
|||
table.dataTable thead .sorting_desc:before, |
|||
table.dataTable thead .sorting_desc:after, |
|||
table.dataTable thead .sorting_asc_disabled:before, |
|||
table.dataTable thead .sorting_asc_disabled:after, |
|||
table.dataTable thead .sorting_desc_disabled:before, |
|||
table.dataTable thead .sorting_desc_disabled:after { |
|||
position: absolute; |
|||
bottom: 0.9em; |
|||
display: block; |
|||
opacity: 0.3; |
|||
} |
|||
table.dataTable thead .sorting:before, |
|||
table.dataTable thead .sorting_asc:before, |
|||
table.dataTable thead .sorting_desc:before, |
|||
table.dataTable thead .sorting_asc_disabled:before, |
|||
table.dataTable thead .sorting_desc_disabled:before { |
|||
right: 1em; |
|||
content: "\2191"; |
|||
} |
|||
table.dataTable thead .sorting:after, |
|||
table.dataTable thead .sorting_asc:after, |
|||
table.dataTable thead .sorting_desc:after, |
|||
table.dataTable thead .sorting_asc_disabled:after, |
|||
table.dataTable thead .sorting_desc_disabled:after { |
|||
right: 0.5em; |
|||
content: "\2193"; |
|||
} |
|||
table.dataTable thead .sorting_asc:before, |
|||
table.dataTable thead .sorting_desc:after { |
|||
opacity: 1; |
|||
} |
|||
table.dataTable thead .sorting_asc_disabled:before, |
|||
table.dataTable thead .sorting_desc_disabled:after { |
|||
opacity: 0; |
|||
} |
|||
|
|||
div.dataTables_scrollHead table.dataTable { |
|||
margin-bottom: 0 !important; |
|||
} |
|||
|
|||
div.dataTables_scrollBody table { |
|||
border-top: none; |
|||
margin-top: 0 !important; |
|||
margin-bottom: 0 !important; |
|||
} |
|||
div.dataTables_scrollBody table thead .sorting:before, |
|||
div.dataTables_scrollBody table thead .sorting_asc:before, |
|||
div.dataTables_scrollBody table thead .sorting_desc:before, |
|||
div.dataTables_scrollBody table thead .sorting:after, |
|||
div.dataTables_scrollBody table thead .sorting_asc:after, |
|||
div.dataTables_scrollBody table thead .sorting_desc:after { |
|||
display: none; |
|||
} |
|||
div.dataTables_scrollBody table tbody tr:first-child th, |
|||
div.dataTables_scrollBody table tbody tr:first-child td { |
|||
border-top: none; |
|||
} |
|||
|
|||
div.dataTables_scrollFoot > .dataTables_scrollFootInner { |
|||
box-sizing: content-box; |
|||
} |
|||
div.dataTables_scrollFoot > .dataTables_scrollFootInner > table { |
|||
margin-top: 0 !important; |
|||
border-top: none; |
|||
} |
|||
|
|||
@media screen and (max-width: 767px) { |
|||
div.dataTables_wrapper div.dataTables_length, |
|||
div.dataTables_wrapper div.dataTables_filter, |
|||
div.dataTables_wrapper div.dataTables_info, |
|||
div.dataTables_wrapper div.dataTables_paginate { |
|||
text-align: center; |
|||
} |
|||
div.dataTables_wrapper div.dataTables_paginate ul.pagination { |
|||
justify-content: center !important; |
|||
} |
|||
} |
|||
table.dataTable.table-sm > thead > tr > th :not(.sorting_disabled) { |
|||
padding-right: 20px; |
|||
} |
|||
table.dataTable.table-sm .sorting:before, |
|||
table.dataTable.table-sm .sorting_asc:before, |
|||
table.dataTable.table-sm .sorting_desc:before { |
|||
top: 5px; |
|||
right: 0.85em; |
|||
} |
|||
table.dataTable.table-sm .sorting:after, |
|||
table.dataTable.table-sm .sorting_asc:after, |
|||
table.dataTable.table-sm .sorting_desc:after { |
|||
top: 5px; |
|||
} |
|||
|
|||
table.table-bordered.dataTable { |
|||
border-right-width: 0; |
|||
} |
|||
table.table-bordered.dataTable th, |
|||
table.table-bordered.dataTable td { |
|||
border-left-width: 0; |
|||
} |
|||
table.table-bordered.dataTable th:last-child, table.table-bordered.dataTable th:last-child, |
|||
table.table-bordered.dataTable td:last-child, |
|||
table.table-bordered.dataTable td:last-child { |
|||
border-right-width: 1px; |
|||
} |
|||
table.table-bordered.dataTable tbody th, |
|||
table.table-bordered.dataTable tbody td { |
|||
border-bottom-width: 0; |
|||
} |
|||
|
|||
div.dataTables_scrollHead table.table-bordered { |
|||
border-bottom-width: 0; |
|||
} |
|||
|
|||
div.table-responsive > div.dataTables_wrapper > div.row { |
|||
margin: 0; |
|||
} |
|||
div.table-responsive > div.dataTables_wrapper > div.row > div[class^="col-"]:first-child { |
|||
padding-left: 0; |
|||
} |
|||
div.table-responsive > div.dataTables_wrapper > div.row > div[class^="col-"]:last-child { |
|||
padding-right: 0; |
|||
} |
|||
@ -1,184 +0,0 @@ |
|||
/*! DataTables Bootstrap 4 integration |
|||
* ©2011-2017 SpryMedia Ltd - datatables.net/license |
|||
*/ |
|||
|
|||
/** |
|||
* DataTables integration for Bootstrap 4. This requires Bootstrap 4 and |
|||
* DataTables 1.10 or newer. |
|||
* |
|||
* This file sets the defaults and adds options to DataTables to style its |
|||
* controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
|
|||
* for further information. |
|||
*/ |
|||
(function( factory ){ |
|||
if ( typeof define === 'function' && define.amd ) { |
|||
// AMD
|
|||
define( ['jquery', 'datatables.net'], function ( $ ) { |
|||
return factory( $, window, document ); |
|||
} ); |
|||
} |
|||
else if ( typeof exports === 'object' ) { |
|||
// CommonJS
|
|||
module.exports = function (root, $) { |
|||
if ( ! root ) { |
|||
root = window; |
|||
} |
|||
|
|||
if ( ! $ || ! $.fn.dataTable ) { |
|||
// Require DataTables, which attaches to jQuery, including
|
|||
// jQuery if needed and have a $ property so we can access the
|
|||
// jQuery object that is used
|
|||
$ = require('datatables.net')(root, $).$; |
|||
} |
|||
|
|||
return factory( $, root, root.document ); |
|||
}; |
|||
} |
|||
else { |
|||
// Browser
|
|||
factory( jQuery, window, document ); |
|||
} |
|||
}(function( $, window, document, undefined ) { |
|||
'use strict'; |
|||
var DataTable = $.fn.dataTable; |
|||
|
|||
|
|||
/* Set the defaults for DataTables initialisation */ |
|||
$.extend( true, DataTable.defaults, { |
|||
dom: |
|||
"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" + |
|||
"<'row'<'col-sm-12'tr>>" + |
|||
"<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", |
|||
renderer: 'bootstrap' |
|||
} ); |
|||
|
|||
|
|||
/* Default class modification */ |
|||
$.extend( DataTable.ext.classes, { |
|||
sWrapper: "dataTables_wrapper dt-bootstrap4", |
|||
sFilterInput: "form-control form-control-sm", |
|||
sLengthSelect: "custom-select custom-select-sm form-control form-control-sm", |
|||
sProcessing: "dataTables_processing card", |
|||
sPageButton: "paginate_button page-item" |
|||
} ); |
|||
|
|||
|
|||
/* Bootstrap paging button renderer */ |
|||
DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) { |
|||
var api = new DataTable.Api( settings ); |
|||
var classes = settings.oClasses; |
|||
var lang = settings.oLanguage.oPaginate; |
|||
var aria = settings.oLanguage.oAria.paginate || {}; |
|||
var btnDisplay, btnClass, counter=0; |
|||
|
|||
var attach = function( container, buttons ) { |
|||
var i, ien, node, button; |
|||
var clickHandler = function ( e ) { |
|||
e.preventDefault(); |
|||
if ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) { |
|||
api.page( e.data.action ).draw( 'page' ); |
|||
} |
|||
}; |
|||
|
|||
for ( i=0, ien=buttons.length ; i<ien ; i++ ) { |
|||
button = buttons[i]; |
|||
|
|||
if ( $.isArray( button ) ) { |
|||
attach( container, button ); |
|||
} |
|||
else { |
|||
btnDisplay = ''; |
|||
btnClass = ''; |
|||
|
|||
switch ( button ) { |
|||
case 'ellipsis': |
|||
btnDisplay = '…'; |
|||
btnClass = 'disabled'; |
|||
break; |
|||
|
|||
case 'first': |
|||
btnDisplay = lang.sFirst; |
|||
btnClass = button + (page > 0 ? |
|||
'' : ' disabled'); |
|||
break; |
|||
|
|||
case 'previous': |
|||
btnDisplay = lang.sPrevious; |
|||
btnClass = button + (page > 0 ? |
|||
'' : ' disabled'); |
|||
break; |
|||
|
|||
case 'next': |
|||
btnDisplay = lang.sNext; |
|||
btnClass = button + (page < pages-1 ? |
|||
'' : ' disabled'); |
|||
break; |
|||
|
|||
case 'last': |
|||
btnDisplay = lang.sLast; |
|||
btnClass = button + (page < pages-1 ? |
|||
'' : ' disabled'); |
|||
break; |
|||
|
|||
default: |
|||
btnDisplay = button + 1; |
|||
btnClass = page === button ? |
|||
'active' : ''; |
|||
break; |
|||
} |
|||
|
|||
if ( btnDisplay ) { |
|||
node = $('<li>', { |
|||
'class': classes.sPageButton+' '+btnClass, |
|||
'id': idx === 0 && typeof button === 'string' ? |
|||
settings.sTableId +'_'+ button : |
|||
null |
|||
} ) |
|||
.append( $('<a>', { |
|||
'href': '#', |
|||
'aria-controls': settings.sTableId, |
|||
'aria-label': aria[ button ], |
|||
'data-dt-idx': counter, |
|||
'tabindex': settings.iTabIndex, |
|||
'class': 'page-link' |
|||
} ) |
|||
.html( btnDisplay ) |
|||
) |
|||
.appendTo( container ); |
|||
|
|||
settings.oApi._fnBindAction( |
|||
node, {action: button}, clickHandler |
|||
); |
|||
|
|||
counter++; |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
// IE9 throws an 'unknown error' if document.activeElement is used
|
|||
// inside an iframe or frame.
|
|||
var activeEl; |
|||
|
|||
try { |
|||
// Because this approach is destroying and recreating the paging
|
|||
// elements, focus is lost on the select button which is bad for
|
|||
// accessibility. So we want to restore focus once the draw has
|
|||
// completed
|
|||
activeEl = $(host).find(document.activeElement).data('dt-idx'); |
|||
} |
|||
catch (e) {} |
|||
|
|||
attach( |
|||
$(host).empty().html('<ul class="pagination"/>').children('ul'), |
|||
buttons |
|||
); |
|||
|
|||
if ( activeEl !== undefined ) { |
|||
$(host).find( '[data-dt-idx='+activeEl+']' ).trigger('focus'); |
|||
} |
|||
}; |
|||
|
|||
|
|||
return DataTable; |
|||
})); |
|||
File diff suppressed because it is too large
@ -1,6 +0,0 @@ |
|||
/* |
|||
https://select2.org/troubleshooting/common-problems
|
|||
*/ |
|||
if ($.fn.modal) { |
|||
$.fn.modal.Constructor.prototype._enforceFocus = function () { }; |
|||
} |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue