pull/1767/head
Alper Ebicoglu 6 years ago
commit d39c37d826

@ -23,5 +23,8 @@
"LicenseUpgradeMessage": "Your license is upgraded to {0}",
"LicenseAddDeveloperMessage": "{0} developers added to your license" ,
"Volo.AbpIo.Commercial:010004": "Can not find the specified user! The user must have already registered."
"LicenseAddDeveloperMessage": "{0} developers added to your license",
"MyOrganizations": "My organizations",
"ApiKey": "API key"
}
}

@ -20,5 +20,10 @@
"EndDate": "bitiş tarihi",
"Modules": "Modüller",
"Volo.AbpIo.Commercial:010004": "Kullanıcı bulunamadı! İlgili kullanıcının daha önceden sisteme kayıt olmuş olması gerekiyor."
"LicenseExtendMessage": "Lisans bitiş tarihiniz {0} tarihine kadar uzatıldı",
"LicenseUpgradeMessage": "Lisansınız {0} lisansa yükseltildi",
"LicenseAddDeveloperMessage": "Lisansınıza {0} geliştirici eklendi",
"MyOrganizations": "Organizasyonlarım",
"ApiKey": "API anahtarı"
}
}

@ -0,0 +1,60 @@
## Guia de Contribuição
O ABP é um projeto de [código aberto](https://github.com/abpframework) e orientado à comunidade. Este guia tem como objetivo ajudar alguém que queira contribuir com o projeto.
### Contribuição de código
Você sempre pode enviar solicitações pull ao repositório do Github.
- Clone o [repositório ABP](https://github.com/abpframework/abp/) do Github.
- Faça as alterações necessárias.
- Envie uma solicitação de recebimento.
Antes de fazer qualquer alteração, discuta-a sobre os [problemas](https://github.com/abpframework/abp/issues) do [Github](https://github.com/abpframework/abp/issues) . Dessa forma, nenhum outro desenvolvedor trabalhará no mesmo problema e seu PR terá uma chance melhor de ser aceito.
#### Correções de bugs e aprimoramentos
Você pode corrigir um bug conhecido ou trabalhar em uma melhoria planejada. Veja [a lista de problemas](https://github.com/abpframework/abp/issues) no Github.
#### Solicitações de recursos
Se você tem uma ideia de recurso para a estrutura ou módulos, [crie um problema](https://github.com/abpframework/abp/issues/new) no Github ou participe de uma discussão existente. Então você pode implementá-lo se for adotado pela comunidade.
### Tradução de documentos
Você pode traduzir a [documentação](https://abp.io/documents/) completa (incluindo esta) para o idioma materno. Nesse caso, siga estas etapas:
- Clone o [repositório ABP](https://github.com/abpframework/abp/) do Github.
- Para adicionar um novo idioma, crie uma nova pasta dentro da pasta [docs](https://github.com/abpframework/abp/tree/master/docs) . Os nomes das pastas podem ser "en", "es", "fr", "tr" e assim por diante, com base no idioma (consulte [todos os códigos de cultura](https://msdn.microsoft.com/en-us/library/hh441729.aspx) ).
- Obtenha a [pasta "en"](https://github.com/abpframework/abp/tree/master/docs/en) como uma referência para os nomes de arquivos e a estrutura de pastas. Mantenha o mesmo nome se estiver traduzindo a mesma documentação.
- Envie uma solicitação de recebimento (PR) depois de traduzir qualquer documento. Traduza documentos e envie PRs um por um. Não espere para terminar as traduções de todos os documentos.
Alguns documentos fundamentais precisam ser traduzidos antes da publicação de um idioma no [site de documentação](https://docs.abp.io/) da [ABP](https://docs.abp.io/) :
- Documentos de introdução
- Tutoriais
- CLI
Um novo idioma é publicado após a conclusão dessas traduções mínimas.
### Localização de Recursos
A estrutura ABP possui um [sistema de localização](../Localization.md) flexível . Você pode criar interfaces de usuário localizadas para seu próprio aplicativo.
Além disso, os módulos de estrutura e pré-construção já localizaram textos. Como exemplo, veja [os textos de localização para o pacote Volo.Abp.UI](https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json) . Você pode criar um novo arquivo na [mesma pasta](https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi) para traduzi-lo.
- Clone o [repositório ABP](https://github.com/abpframework/abp/) do Github.
- Crie um novo arquivo para o idioma de destino para um arquivo de texto de localização (json) (próximo ao arquivo en.json).
- Copie todos os textos do arquivo en.json.
- Traduzir os textos.
- Enviar solicitação de recebimento no Github.
ABP é uma estrutura modular. Portanto, existem muitos recursos de texto de localização, um por módulo. Para encontrar todos os arquivos .json, você pode procurar por "en.json" após clonar o repositório. Você também pode verificar [esta lista](https://docs.abp.io/en/abp/latest/Contribution/Localization-Text-Files) para obter uma lista de arquivos de texto de localização.
### Posts e tutoriais do blog
Se você decidir criar alguns tutoriais ou postagens de blog no ABP, informe-nos (criando um [problema no Github](https://github.com/abpframework/abp/issues) ), para que possamos adicionar um link ao seu tutorial / publicação na documentação oficial e podemos anunciá-lo em nossa [conta do Twitter](https://twitter.com/abpframework) .
### Relatório de erro
Se você encontrar algum erro, [crie um problema no repositório do Github](https://github.com/abpframework/abp/issues/new) .

@ -0,0 +1,126 @@
## Introdução ao modelo de aplicativo angular
Este tutorial explica como criar um novo aplicativo Angular usando o modelo de inicialização, configurar e executá-lo.
### Criando um novo projeto
Este tutorial usa o **ABP CLI** para criar um novo projeto. Consulte a página [Introdução](https://abp.io/get-started) para outras opções.
Instale a CLI ABP usando uma janela de linha de comando, se você não tiver instalado antes:
```bash
dotnet tool install -g Volo.Abp.Cli
```
Use o `abp new`comando em uma pasta vazia para criar seu projeto:
```bash
abp new Acme.BookStore -u angular
```
> Você pode usar diferentes níveis de namespaces; por exemplo, BookStore, Acme.BookStore ou Acme.Retail.BookStore.
`-u angular`A opção especifica que a estrutura da interface do usuário seja Angular. O provedor de banco de dados padrão é o EF Core. Consulte a [documentação](CLI.md) da [CLI](CLI.md) para todas as opções disponíveis.
#### Pré requisitos
A solução criada requer;
- [Visual Studio 2017 (v15.9.0 +)](https://visualstudio.microsoft.com/tr/downloads/)
- [.NET Core 2.2 ou superior](https://www.microsoft.com/net/download/dotnet-core/)
- [Node v10.16 +](https://nodejs.org/)
- [Yarn v1.17 +](https://yarnpkg.com/)
### A Estrutura da Solução
Abra a solução no **Visual Studio** :
![livraria-visual-studio-solução](images/bookstore-visual-studio-solution-for-spa.png)
A solução possui uma estrutura em camadas (baseada no [Domain Driven Design](Domain-Driven-Design.md) ) e contém projetos de teste de unidade e integração adequadamente configurados para trabalhar com o **banco de** dados de **memória** **EF Core** e **SQLite** .
> Consulte o [documento do modelo do aplicativo](Startup-Templates/Application.md) para entender a estrutura da solução em detalhes.
### Cadeia de Conexão de Banco de Dados
Verifique a **cadeia de conexão** no `appsettings.json`arquivo no `.HttpApi.Host`projeto:
```json
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=BookStore;Trusted_Connection=True"
}
}
```
A solução está configurada para usar o **Entity Framework Core** com o **MS SQL Server** . O EF Core suporta [vários](https://docs.microsoft.com/en-us/ef/core/providers/) provedores de banco de dados, para que você possa usar outro DBMS, se desejar. Mude a cadeia de conexão, se necessário.
### Criar banco de dados e aplicar migrações de banco de dados
Você tem duas opções para criar o banco de dados.
#### Usando o aplicativo DbMigrator
A solução contém um aplicativo de console (nomeado `Acme.BookStore.DbMigrator`nesta amostra) que pode criar banco de dados, aplicar migrações e propagar dados iniciais. É útil no desenvolvimento e no ambiente de produção.
> `.DbMigrator`projeto tem o seu próprio `appsettings.json`. Portanto, se você alterou a cadeia de conexão acima, também deve alterar esta.
Clique com o botão direito do mouse no `.DbMigrator`projeto e selecione **Definir como Projeto de Inicialização** :
![definir como projeto de inicialização](images/set-as-startup-project.png)
Pressione F5 (ou Ctrl + F5) para executar o aplicativo. Terá uma saída como mostrado abaixo:
![definir como projeto de inicialização](images/db-migrator-app.png)
#### Usando o comando EF Core Update-Database
O Ef Core possui um `Update-Database`comando que cria banco de dados, se necessário, e aplica migrações pendentes. Clique com o botão direito do mouse no `.Web`projeto e selecione **Definir como Projeto de Inicialização** :
![definir como projeto de inicialização](images/set-as-startup-project.png)
Abra o **Console do Gerenciador de Pacotes** , selecione o `.EntityFrameworkCore.DbMigrations`projeto como **Projeto Padrão** e execute o `Update-Database`comando:
![pcm-update-database](images/pcm-update-database-v2.png)
Isso criará um novo banco de dados com base na cadeia de conexão configurada.
> O uso da `.Migrator`ferramenta é a maneira sugerida, porque também semeia os dados iniciais para poder executar corretamente o aplicativo Web.
### Executando o aplicativo
#### Execute o host da API (lado do servidor)
Verifique se o `.HttpApi.Host`projeto é o projeto de inicialização e o aplicativo que abrirá uma interface do usuário do Swagger:
![livraria-homepage](images/bookstore-swagger-ui-host.png)
Você pode ver as APIs do aplicativo e testá-las aqui. Obtenha [mais informações](https://swagger.io/tools/swagger-ui/) sobre a interface do usuário do Swagger.
##### Autorização para a interface do usuário do Swagger
A maioria das APIs de aplicativos requer autenticação e autorização. Se você deseja testar APIs autorizadas, vá manualmente para a `/Account/Login`página, digite `admin`como o nome de usuário e `1q2w3E*`a senha para efetuar login no aplicativo. Você também poderá executar APIs autorizadas.
#### Execute o aplicativo angular (lado do cliente)
Vá para a `angular`pasta, abra um terminal de linha de comando, digite o `yarn`comando (sugerimos ao gerenciador de pacotes do [yarn](https://yarnpkg.com/) enquanto o npm install também funcionará na maioria dos casos):
```bash
yarn
```
Depois que todos os módulos do nó estiverem carregados, execute `yarn start`ou `npm start`comando:
```bash
yarn start
```
Abra seu navegador favorito e vá para `localhost:4200`URL. Nome de usuário inicial é `admin`e senha é `1q2w3E*`.
O modelo de inicialização inclui os módulos de **gerenciamento de** **identidade** e **gerenciamento de inquilino** . Após o login, o menu Administração estará disponível, onde você poderá gerenciar **inquilinos** , **funções** , **usuários** e suas **permissões** .
> Recomendamos o [Visual Studio Code](https://code.visualstudio.com/) como editor do projeto Angular, mas você pode usar seu editor favorito.
### Qual é o próximo?
- [Tutorial de desenvolvimento de aplicativos](Tutorials/Angular/Part-I.md)

@ -0,0 +1,183 @@
# Introdução ao ABP com o aplicativo Web MVC AspNet Core
Este tutorial explica como iniciar o ABP do zero com dependências mínimas. Você geralmente deseja começar com o **modelo de inicialização** .
## Criar um novo projeto
1. Crie um novo aplicativo da Web vazio do AspNet Core no Visual Studio:
![img](images/create-new-aspnet-core-application.png)
1. Selecionar modelo vazio
![img](images/select-empty-web-application.png)
Você pode selecionar outro modelo, mas quero mostrá-lo em um projeto claro.
## Instale o pacote Volo.Abp.AspNetCore.Mvc
Volo.Abp.AspNetCore.Mvc é um pacote de integração do AspNet Core MVC para ABP. Então, instale-o no seu projeto:
```
Install-Package Volo.Abp.AspNetCore.Mvc
```
## Criar o primeiro módulo ABP
O ABP é uma estrutura modular e requer uma classe de **módulo de inicialização (raiz)** derivada de `AbpModule`:
```csharp
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.AspNetCore.Modularity;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Modularity;
namespace BasicAspNetCoreApplication
{
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
public class AppModule : AbpModule
{
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvcWithDefaultRoute();
}
}
}
```
`AppModule` é um bom nome para o módulo de inicialização de um aplicativo.
Os pacotes ABP definem as classes do módulo e um módulo pode depender de outro módulo. No código acima, nosso `AppModule`depende `AbpAspNetCoreMvcModule`(definido pelo pacote Volo.Abp.AspNetCore.Mvc). É comum adicionar um `DependsOn`atributo após a instalação de um novo pacote de nuget ABP.
Em vez da classe Startup, estamos configurando o pipeline do ASP.NET Core nesta classe de módulo.
## A classe de inicialização
O próximo passo é modificar a classe Startup para integrar ao sistema do módulo ABP:
```csharp
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace BasicAspNetCoreApplication
{
public class Startup
{
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddApplication<AppModule>();
return services.BuildServiceProviderFromFactory();
}
public void Configure(IApplicationBuilder app)
{
app.InitializeApplication();
}
}
}
```
`ConfigureServices`Método alterado para retornar em `IServiceProvider`vez de `void`. Essa alteração nos permite substituir a injeção de dependência do AspNet Core por outra estrutura (consulte a seção de integração com Autofac abaixo). `services.AddApplication<AppModule>()`adiciona todos os serviços definidos em todos os módulos a partir do `AppModule`.
`app.InitializeApplication()`O `Configure`método call in inicializa e inicia o aplicativo.
## Olá Mundo!
O aplicativo acima não faz nada. Vamos criar um controlador MVC que faz algo:
```csharp
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
namespace BasicAspNetCoreApplication.Controllers
{
public class HomeController : AbpController
{
public IActionResult Index()
{
return Content("Hello World!");
}
}
}
```
Se você executar o aplicativo, verá um "Olá, mundo!" mensagem na página.
Derivado `HomeController`de em `AbpController`vez de `Controller`classe padrão . Isso não é necessário, mas a `AbpController`classe possui propriedades e métodos base úteis para facilitar seu desenvolvimento.
## Usando Autofac como a estrutura de injeção de dependência
Embora o sistema de Injeção de Dependência (DI) do AspNet Core seja adequado para requisitos básicos, o Autofac fornece recursos avançados, como Injeção de Propriedade e Interceptação de Método, exigidos pela ABP para executar recursos avançados da estrutura de aplicativos.
Substituir o sistema DI do AspNet Core pelo Autofac e integrar ao ABP é bastante fácil.
1. Instale o pacote [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac)
```
Install-Package Volo.Abp.Autofac
```
1. Adicionar `AbpAutofacModule`dependência
```csharp
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
[DependsOn(typeof(AbpAutofacModule))] //Add dependency to ABP Autofac module
public class AppModule : AbpModule
{
...
}
```
1. Altere a `services.AddApplication<AppModule>();`linha na `Startup`classe, como mostrado abaixo:
```csharp
services.AddApplication<AppModule>(options =>
{
options.UseAutofac(); //Integrate to Autofac
});
```
1. Atualize `Program.cs`para não usar o `WebHost.CreateDefaultBuilder()`método, pois ele usa o contêiner DI padrão:
```csharp
public class Program
{
public static void Main(string[] args)
{
/*
https://github.com/aspnet/AspNetCore/issues/4206#issuecomment-445612167
CurrentDirectoryHelpers exists in: \framework\src\Volo.Abp.AspNetCore.Mvc\Microsoft\AspNetCore\InProcess\CurrentDirectoryHelpers.cs
Will remove CurrentDirectoryHelpers.cs when upgrade to ASP.NET Core 3.0.
*/
CurrentDirectoryHelpers.SetCurrentDirectory();
BuildWebHostInternal(args).Run();
}
public static IWebHost BuildWebHostInternal(string[] args) =>
new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIIS()
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
}
```
## Código fonte
Obter código-fonte do projeto de exemplo criada neste tutorial a partir de [aqui](https://github.com/abpframework/abp/tree/master/samples/BasicAspNetCoreApplication) .

@ -0,0 +1,102 @@
## Introdução ao modelo ASP.NET Core MVC
Este tutorial explica como criar um novo aplicativo Web ASP.NET Core MVC usando o modelo de inicialização, configurá-lo e executá-lo.
### Criando um novo projeto
Este tutorial usa o **ABP CLI** para criar um novo projeto. Consulte a página [Introdução](https://abp.io/get-started) para outras opções.
Instale a CLI ABP usando uma janela de linha de comando, se você não tiver instalado antes:
```bash
dotnet tool install -g Volo.Abp.Cli
```
Use o `abp new`comando em uma pasta vazia para criar seu projeto:
```bash
abp new Acme.BookStore
```
> Você pode usar diferentes níveis de namespaces; por exemplo, BookStore, Acme.BookStore ou Acme.Retail.BookStore.
`new`O comando cria um **aplicativo MVC em camadas** com o **Entity Framework Core** como o provedor de banco de dados. No entanto, possui opções adicionais. Consulte a [documentação](CLI.md) da [CLI](CLI.md) para todas as opções disponíveis.
#### Pré requisitos
A solução criada requer;
- [Visual Studio 2017 (v15.9.0 +)](https://visualstudio.microsoft.com/tr/downloads/)
- [.NET Core 2.2 ou superior](https://www.microsoft.com/net/download/dotnet-core/)
### A Estrutura da Solução
Abra a solução no **Visual Studio** :
![livraria-visual-studio-solução](images/bookstore-visual-studio-solution-v3.png)
A solução possui uma estrutura em camadas (baseada no [Domain Driven Design](Domain-Driven-Design.md) ) e contém projetos de teste de unidade e integração adequadamente configurados para trabalhar com o **banco de** dados de **memória** **EF Core** e **SQLite** .
> Consulte o [documento do modelo de aplicativo](Startup-Templates/Application.md) para entender a estrutura da solução em detalhes.
### Cadeia de Conexão de Banco de Dados
Verifique a **cadeia de conexão** no `appsettings.json`arquivo no `.Web`projeto:
```json
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=BookStore;Trusted_Connection=True"
}
}
```
A solução está configurada para usar o **Entity Framework Core** com o **MS SQL Server** . O EF Core suporta [vários](https://docs.microsoft.com/en-us/ef/core/providers/) provedores de banco de dados, para que você possa usar outro DBMS, se desejar. Mude a cadeia de conexão, se necessário.
### Criar banco de dados e aplicar migrações de banco de dados
Você tem duas opções para criar o banco de dados.
#### Usando o aplicativo DbMigrator
A solução contém um aplicativo de console (nomeado `Acme.BookStore.DbMigrator`nesta amostra) que pode criar banco de dados, aplicar migrações e propagar dados iniciais. É útil no desenvolvimento e no ambiente de produção.
> `.DbMigrator`projeto tem o seu próprio `appsettings.json`. Portanto, se você alterou a cadeia de conexão acima, também deve alterar esta.
Clique com o botão direito do mouse no `.DbMigrator`projeto e selecione **Definir como Projeto de Inicialização** :
![definir como projeto de inicialização](images/set-as-startup-project.png)
Pressione F5 (ou Ctrl + F5) para executar o aplicativo. Terá uma saída como mostrado abaixo:
![definir como projeto de inicialização](images/db-migrator-app.png)
#### Usando o comando EF Core Update-Database
O Ef Core possui um `Update-Database`comando que cria banco de dados, se necessário, e aplica migrações pendentes. Clique com o botão direito do mouse no `.Web`projeto e selecione **Definir como Projeto de Inicialização** :
![definir como projeto de inicialização](images/set-as-startup-project.png)
Abra o **Console do Gerenciador de Pacotes** , selecione o `.EntityFrameworkCore.DbMigrations`projeto como **Projeto Padrão** e execute o `Update-Database`comando:
![pcm-update-database](images/pcm-update-database-v2.png)
Isso criará um novo banco de dados com base na cadeia de conexão configurada.
> O uso da `.Migrator`ferramenta é a maneira sugerida, porque também semeia os dados iniciais para poder executar corretamente o aplicativo Web.
### Executando o aplicativo
Verifique se o `.Web`projeto é o projeto de inicialização. Execute o aplicativo que abrirá a página **inicial** no seu navegador:
![livraria-homepage](images/bookstore-homepage.png)
Clique no botão **Login** , insira `admin`como nome de usuário e `1q2w3E*`senha para acessar o aplicativo.
O modelo de inicialização inclui os módulos de **gerenciamento de** **identidade** e **gerenciamento de inquilino** . Após o login, o menu Administração estará disponível, onde você poderá gerenciar **inquilinos** , **funções** , **usuários** e suas **permissões** . A página de gerenciamento de usuários é mostrada abaixo:
![livraria-gerenciamento de usuários](images/bookstore-user-management-v2.png)
### Qual é o próximo?
- [Tutorial de desenvolvimento de aplicativos](Tutorials/AspNetCore-Mvc/Part-I.md)

@ -0,0 +1,182 @@
# Introdução ao ABP com aplicativo de console
Este tutorial explica como iniciar o ABP do zero com dependências mínimas. Você geralmente deseja começar com um **modelo de inicialização** .
## Criar um novo projeto
Crie um novo aplicativo regular .Net Core Console do Visual Studio:
![img](images/create-new-net-core-console-application.png)
## Instale o pacote Volo.Abp
Volo.Abp.Core é o pacote principal de pepitas para criar aplicativos baseados em ABP. Então, instale-o no seu projeto:
```
Install-Package Volo.Abp.Core
```
## Criar o primeiro módulo ABP
O ABP é uma estrutura modular e requer uma classe de **módulo de inicialização (raiz)** derivada de `AbpModule`:
```csharp
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace AbpConsoleDemo
{
public class AppModule : AbpModule
{
}
}
```
`AppModule` é um bom nome para o módulo de inicialização de um aplicativo.
## Inicializar o aplicativo
A próxima etapa é inicializar o aplicativo usando o módulo de inicialização criado acima:
```csharp
using System;
using Volo.Abp;
namespace AbpConsoleDemo
{
class Program
{
static void Main(string[] args)
{
using (var application = AbpApplicationFactory.Create<AppModule>())
{
application.Initialize();
Console.WriteLine("Press ENTER to stop application...");
Console.ReadLine();
}
}
}
}
```
`AbpApplicationFactory`é usado para criar o aplicativo e carregar todos os módulos que tomam `AppModule`como módulo de inicialização. `Initialize()`O método inicia o aplicativo.
## Olá Mundo!
O aplicativo acima não faz nada. Vamos criar um serviço que faça algo:
```csharp
using System;
using Volo.Abp.DependencyInjection;
namespace AbpConsoleDemo
{
public class HelloWorldService : ITransientDependency
{
public void SayHello()
{
Console.WriteLine("Hello World!");
}
}
}
```
`ITransientDependency`é uma interface especial do ABP que registra automaticamente o serviço como transitório (consulte o [documento de injeção de dependência](Dependency-Injection.md) ).
Agora, podemos resolver o problema `HelloWorldService`e dizer olá. Altere o Program.cs como mostrado abaixo:
```csharp
using System;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
namespace AbpConsoleDemo
{
class Program
{
static void Main(string[] args)
{
using (var application = AbpApplicationFactory.Create<AppModule>())
{
application.Initialize();
//Resolve a service and use it
var helloWorldService =
application.ServiceProvider.GetService<HelloWorldService>();
helloWorldService.SayHello();
Console.WriteLine("Press ENTER to stop application...");
Console.ReadLine();
}
}
}
}
```
Embora seja suficiente para este exemplo de código simples, é sempre recomendável criar escopos no caso de resolver diretamente dependências de `IServiceProvider`(consulte a [documentação de Injeção de Dependências](Dependency-Injection.md)).
## Usando Autofac como a estrutura de injeção de dependência
Embora o sistema de Injeção de Dependência (DI) do AspNet Core seja adequado para requisitos básicos, o Autofac fornece recursos avançados, como Injeção de Propriedade e Interceptação de Método, exigidos pela ABP para executar recursos avançados da estrutura de aplicativos.
Substituir o sistema DI do AspNet Core pelo Autofac e integrar ao ABP é bastante fácil.
1. Instale o pacote [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac)
```
Install-Package Volo.Abp.Autofac
```
1. Adicionar `AbpAutofacModule`dependência
```csharp
[DependsOn(typeof(AbpAutofacModule))] //Add dependency to the AbpAutofacModule
public class AppModule : AbpModule
{
}
```
1. Mude o `Program.cs`arquivo como mostrado abaixo:
```csharp
using System;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
namespace AbpConsoleDemo
{
class Program
{
static void Main(string[] args)
{
using (var application = AbpApplicationFactory.Create<AppModule>(options =>
{
options.UseAutofac(); //Autofac integration
}))
{
application.Initialize();
//Resolve a service and use it
var helloWorldService =
application.ServiceProvider.GetService<HelloWorldService>();
helloWorldService.SayHello();
Console.WriteLine("Press ENTER to stop application...");
Console.ReadLine();
}
}
}
}
```
Apenas chamado `options.UseAutofac()`método nas `AbpApplicationFactory.Create`opções.
## Código fonte
Obter código-fonte do projeto de exemplo criada neste tutorial a partir de [aqui](https://github.com/abpframework/abp/tree/master/samples/BasicConsoleApplication) .

@ -0,0 +1,31 @@
# Documentação ABP
O ABP é uma **estrutura de aplicativos de código aberto** focada no desenvolvimento de aplicativos da Web baseado no ASP.NET Core, mas também suporta o desenvolvimento de outros tipos de aplicativos.
Explore o menu de navegação esquerdo para mergulhar fundo na documentação.
## Status do projeto
ABP é a **próxima geração** da estrutura de código aberto [ASP.NET Boilerplate](https://aspnetboilerplate.com/) . Atualmente, está em fase de visualização e não está pronto para uso na produção. A documentação ainda está em andamento e está longe de estar completa.
Para aplicativos de curto prazo e em nível de produção, é sugerido o uso da estrutura do [ASP.NET Boilerplate](https://aspnetboilerplate.com/) , que possui um rico conjunto de recursos, maduro, mantido ativamente e atualizado.
## Começando
A maneira mais fácil de iniciar um novo projeto com o ABP é usar os modelos de inicialização:
- [Modelo de interface do usuário do ASP.NET Core MVC (Razor Pages)](Getting-Started-AspNetCore-MVC-Template.md)
- [Modelo de interface do usuário angular](Getting-Started-Angular-Template.md)
Se você deseja começar do zero (com um projeto vazio), instale manualmente o ABP Framework e use os seguintes tutoriais:
- [Aplicação de console](Getting-Started-Console-Application.md)
- [Aplicativo da Web principal do ASP.NET](Getting-Started-AspNetCore-Application.md)
## Código fonte
ABP está hospedado no GitHub. Veja [o código fonte](https://github.com/abpframework/abp) .
## Deseja contribuir?
O ABP é um projeto de código aberto orientado pela comunidade. Consulte [o guia de contribuição](Contribution/Index.md) se você quiser fazer parte deste projeto.

@ -0,0 +1,462 @@
## Tutorial do ASP.NET Core MVC - Parte I
### Sobre este tutorial
Nesta série de tutoriais, você criará um aplicativo usado para gerenciar uma lista de livros e seus autores. **O Entity Framework Core** (EF Core) será usado como o provedor ORM, pois é o provedor de banco de dados padrão.
Esta é a primeira parte da série de tutoriais do ASP.NET Core MVC. Veja todas as peças:
- **Parte I: Crie o projeto e uma página de lista de livros (este tutorial)**
- [Parte II: Criar, atualizar e excluir livros](Part-II.md)
- [Parte III: Testes de Integração](Part-III.md)
Você pode acessar o **código fonte** do aplicativo [no repositório GitHub](https://github.com/abpframework/abp/tree/master/samples/BookStore) .
> Você também pode assistir a [este curso em vídeo](https://amazingsolutions.teachable.com/p/lets-build-the-bookstore-application) preparado por um membro da comunidade ABP, com base neste tutorial.
### Criando o projeto
Crie um novo projeto chamado `Acme.BookStore`, crie o banco de dados e execute o aplicativo seguindo o [documento Introdução](Getting-Started-AspNetCore-MVC-Template.md).
### Estrutura da solução
É assim que a estrutura da solução em camadas cuida da criação:
![livraria-visual-studio-solução](images/bookstore-visual-studio-solution-v3.png)
> Você pode ver o [documento do modelo de aplicativo](https://docs.abp.io/en/abp/latest/Startup-Templates/Application) para entender a estrutura da solução em detalhes. No entanto, você entenderá o básico com este tutorial.
### Criar a entidade do livro
A camada de domínio no modelo de inicialização é separada em dois projetos:
- `Acme.BookStore.Domain`contém suas [entidades](https://docs.abp.io/en/abp/latest/Entities.md) , [serviços de domínio](https://docs.abp.io/en/abp/latest/Domain-Services) e outros objetos principais de domínio.
- `Acme.BookStore.Domain.Shared` contém constantes, enumerações ou outros objetos relacionados ao domínio que podem ser compartilhados com os clientes.
Defina [entidades](https://docs.abp.io/en/abp/latest/Entities) na **camada de domínio** ( `Acme.BookStore.Domain`projeto) da solução. A entidade principal do aplicativo é a `Book`. Crie uma classe, chamada `Book`, no `Acme.BookStore.Domain`projeto, como mostrado abaixo:
```csharp
using System;
using Volo.Abp.Domain.Entities.Auditing;
namespace Acme.BookStore
{
public class Book : AuditedAggregateRoot<Guid>
{
public string Name { get; set; }
public BookType Type { get; set; }
public DateTime PublishDate { get; set; }
public float Price { get; set; }
}
}
```
- O ABP possui duas classes base fundamentais para entidades: `AggregateRoot`e `Entity`. **A raiz agregada** é um dos conceitos de **DDD (Domain Driven Design)** . Consulte o [documento da entidade](https://docs.abp.io/en/abp/latest/Entities) para obter detalhes e melhores práticas.
- `Book`entidade herda `AuditedAggregateRoot`que adiciona algumas propriedades de auditoria ( `CreationTime`, `CreatorId`, `LastModificationTime`... etc.) no topo da `AggregateRoot`classe.
- `Guid`é o **tipo** de **chave primária** da `Book`entidade.
#### BookType Enum
Defina a `BookType`enumeração no `Acme.BookStore.Domain.Shared`projeto:
```csharp
namespace Acme.BookStore
{
public enum BookType
{
Undefined,
Adventure,
Biography,
Dystopia,
Fantastic,
Horror,
Science,
ScienceFiction,
Poetry
}
}
```
#### Adicionar entidade de livro ao seu DbContext
O EF Core exige que você relacione entidades com seu DbContext. A maneira mais fácil de fazer isso é adicionar uma `DbSet`propriedade à `BookStoreDbContext`classe no `Acme.BookStore.EntityFrameworkCore`projeto, conforme mostrado abaixo:
```csharp
public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
{
public DbSet<Book> Books { get; set; }
...
}
```
#### Configure sua entidade do livro
Abra o `BookStoreDbContextModelCreatingExtensions.cs`arquivo no `Acme.BookStore.EntityFrameworkCore`projeto e adicione o seguinte código ao final do `ConfigureBookStore`método para configurar a entidade Livro:
```csharp
builder.Entity<Book>(b =>
{
b.ToTable(BookStoreConsts.DbTablePrefix + "Books", BookStoreConsts.DbSchema);
b.ConfigureByConvention(); //auto configure for the base class props
b.Property(x => x.Name).IsRequired().HasMaxLength(128);
});
```
#### Adicionar nova migração e atualizar o banco de dados
O modelo de inicialização usa [as primeiras migrações do código principal EF](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/) para criar e manter o esquema do banco de dados. Abra o **Gerenciador de Console Package (PMC)** (sob as *Ferramentas / Gerente Nuget Package* menu), selecione o `Acme.BookStore.EntityFrameworkCore.DbMigrations`como o **projeto padrão** e execute o seguinte comando:
![livraria-pmc-add-book-migration](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png)
Isso criará uma nova classe de migração dentro da `Migrations`pasta. Em seguida, execute o `Update-Database`comando para atualizar o esquema do banco de dados:
```
PM> Update-Database
```
#### Adicionar dados de amostra
`Update-Database`O comando criou a `AppBooks`tabela no banco de dados. Abra seu banco de dados e insira algumas linhas de amostra, para que você possa mostrá-las na página:
![livraria-livros-mesa](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-books-table.png)
### Crie o serviço de aplicativo
O próximo passo é criar um [serviço de aplicativo](https://docs.abp.io/en/abp/latest/Application-Services) para gerenciar (criar, listar, atualizar, excluir ...) os livros. A camada de aplicativo no modelo de inicialização é separada em dois projetos:
- `Acme.BookStore.Application.Contracts` contém principalmente seus DTOs e interfaces de serviço de aplicativo.
- `Acme.BookStore.Application` contém as implementações dos seus serviços de aplicativo.
#### BookDto
Crie uma classe DTO denominada `BookDto`no `Acme.BookStore.Application.Contracts`projeto:
```csharp
using System;
using Volo.Abp.Application.Dtos;
namespace Acme.BookStore
{
public class BookDto : AuditedEntityDto<Guid>
{
public string Name { get; set; }
public BookType Type { get; set; }
public DateTime PublishDate { get; set; }
public float Price { get; set; }
}
}
```
- **As** classes **DTO** são usadas para **transferir dados** entre a *camada de apresentação* e a *camada de aplicativo* . Consulte o [documento Objetos de transferência de dados](https://docs.abp.io/en/abp/latest/Data-Transfer-Objects) para obter mais detalhes.
- `BookDto` é usado para transferir dados do livro para a camada de apresentação para mostrar as informações do livro na interface do usuário.
- `BookDto`é derivado do `AuditedEntityDto<Guid>`que possui propriedades de auditoria exatamente como a `Book`classe definida acima.
Será necessário converter `Book`entidades em `BookDto`objetos enquanto retorna os livros para a camada de apresentação. [A](https://automapper.org/) biblioteca do [AutoMapper](https://automapper.org/) pode automatizar essa conversão quando você define o mapeamento adequado. O modelo de inicialização é fornecido com o AutoMapper configurado, para que você possa definir o mapeamento na `BookStoreApplicationAutoMapperProfile`classe no `Acme.BookStore.Application`projeto:
```csharp
using AutoMapper;
namespace Acme.BookStore
{
public class BookStoreApplicationAutoMapperProfile : Profile
{
public BookStoreApplicationAutoMapperProfile()
{
CreateMap<Book, BookDto>();
}
}
}
```
#### CreateUpdateBookDto
Crie uma classe DTO denominada `CreateUpdateBookDto`no `Acme.BookStore.Application.Contracts`projeto:
```csharp
using System;
using System.ComponentModel.DataAnnotations;
namespace Acme.BookStore
{
public class CreateUpdateBookDto
{
[Required]
[StringLength(128)]
public string Name { get; set; }
[Required]
public BookType Type { get; set; } = BookType.Undefined;
[Required]
public DateTime PublishDate { get; set; }
[Required]
public float Price { get; set; }
}
}
```
- Essa classe DTO é usada para obter informações do livro a partir da interface do usuário ao criar ou atualizar um livro.
- Ele define atributos de anotação de dados (como `[Required]`) para definir validações para as propriedades. Os DTOs são [validados automaticamente](https://docs.abp.io/en/abp/latest/Validation) pela estrutura ABP.
Em seguida, adicione um mapeamento `BookStoreApplicationAutoMapperProfile`do `CreateUpdateBookDto`objeto à `Book`entidade:
```csharp
CreateMap<CreateUpdateBookDto, Book>();
```
#### IBookAppService
Defina uma interface nomeada `IBookAppService`no `Acme.BookStore.Application.Contracts`projeto:
```csharp
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Acme.BookStore
{
public interface IBookAppService :
ICrudAppService< //Defines CRUD methods
BookDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting on getting a list of books
CreateUpdateBookDto, //Used to create a new book
CreateUpdateBookDto> //Used to update a book
{
}
}
```
- A definição de interfaces para serviços de aplicativos não é requerida pela estrutura. No entanto, é sugerido como uma prática recomendada.
- `ICrudAppService`define comuns **CRUD** métodos: `GetAsync`, `GetListAsync`, `CreateAsync`, `UpdateAsync`e `DeleteAsync`. Não é necessário estendê-lo. Em vez disso, você pode herdar da `IApplicationService`interface vazia e definir seus próprios métodos manualmente.
- Existem algumas variações de `ICrudAppService`onde você pode usar DTOs separados para cada método.
#### BookAppService
Implemente `IBookAppService`como nomeado `BookAppService`no `Acme.BookStore.Application`projeto:
```csharp
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore
{
public class BookAppService :
CrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto,
CreateUpdateBookDto, CreateUpdateBookDto>,
IBookAppService
{
public BookAppService(IRepository<Book, Guid> repository)
: base(repository)
{
}
}
}
```
- `BookAppService`é derivado do `CrudAppService<...>`qual implementa todos os métodos CRUD definidos acima.
- `BookAppService`injeta `IRepository<Book, Guid>`qual é o repositório padrão da `Book`entidade. O ABP cria automaticamente repositórios padrão para cada raiz (ou entidade) agregada. Veja o [documento](https://docs.abp.io/en/abp/latest/Repositories) do [repositório](https://docs.abp.io/en/abp/latest/Repositories) .
- `BookAppService`usa `IObjectMapper`para converter `Book`objetos em `BookDto`objetos e `CreateUpdateBookDto`objetos em `Book`objetos. O modelo de inicialização usa a biblioteca [AutoMapper](http://automapper.org/) como o provedor de mapeamento de objetos. Você definiu os mapeamentos antes, para que funcionem conforme o esperado.
### Controladores de API automática
Você normalmente cria **controladores** para expor serviços de aplicativos como pontos de extremidade da **API HTTP** . Assim, permite que navegadores ou clientes de terceiros os chamem via AJAX. O ABP pode configurar [**automaticamente**](https://docs.abp.io/en/abp/latest/AspNetCore/Auto-API-Controllers) seus serviços de aplicativo como controladores de API MVC por convenção.
#### UI do Swagger
O modelo de inicialização está configurado para executar a [interface do usuário](https://swagger.io/tools/swagger-ui/) do [swagger](https://swagger.io/tools/swagger-ui/) usando a biblioteca [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) . Execute o aplicativo e insira `https://localhost:XXXX/swagger/`(substitua XXXX por sua própria porta) como URL no seu navegador.
Você verá alguns pontos de extremidade de serviço internos, bem como o `Book`serviço e seus pontos de extremidade no estilo REST:
![livraria-arrogância](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-swagger.png)
O Swagger tem uma ótima interface para testar APIs. Você pode tentar executar a `[GET] /api/app/book`API para obter uma lista de livros.
### Proxies dinâmicos de JavaScript
É comum chamar pontos de extremidade da API HTTP via AJAX do lado do **JavaScript** . Você pode usar `$.ajax`ou outra ferramenta para chamar os pontos de extremidade. No entanto, o ABP oferece uma maneira melhor.
O ABP cria **dinamicamente** **proxies** JavaScript para todos os pontos de extremidade da API. Portanto, você pode usar qualquer **terminal,** assim como chamar uma **função JavaScript** .
#### Testando no console do desenvolvedor do navegador
Você pode testar facilmente os proxies JavaScript usando o **Console** do **desenvolvedor** do seu navegador favorito agora. Execute o aplicativo, abra as **ferramentas de desenvolvedor** do navegador (atalho: F12), vá para a guia **Console** , digite o seguinte código e pressione enter:
```js
acme.bookStore.book.getList({}).done(function (result) { console.log(result); });
```
- `acme.bookStore`é o espaço para nome do `BookAppService`convertido em [camelCase](https://en.wikipedia.org/wiki/Camel_case) .
- `book`é o nome convencional para o `BookAppService`(postfix do AppService removido e convertido em camelCase).
- `getList`é o nome convencional para o `GetListAsync`método definido na `AsyncCrudAppService`classe base (postfix assíncrono removido e convertido em camelCase).
- `{}`O argumento é usado para enviar um objeto vazio ao `GetListAsync`método que normalmente espera um objeto do tipo `PagedAndSortedResultRequestDto`usado para enviar opções de paginação e classificação ao servidor (todas as propriedades são opcionais, para que você possa enviar um objeto vazio).
- `getList`A função retorna a `promise`. Portanto, você pode passar um retorno de chamada para a função `done`(ou `then`) para obter o resultado do servidor.
A execução desse código produz a seguinte saída:
![livraria-teste-js-proxy-getlist](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist.png)
Você pode ver a **lista de livros** retornada do servidor. Você também pode verificar a guia de **rede** das ferramentas do desenvolvedor para ver a comunicação do cliente com o servidor:
![livraria-teste-js-proxy-getlist-rede](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist-network.png)
Vamos **criar um novo livro** usando a `create`função:
```js
acme.bookStore.book.create({ name: 'Foundation', type: 7, publishDate: '1951-05-24', price: 21.5 }).done(function (result) { console.log('successfully created the book with id: ' + result.id); });
```
Você deve ver uma mensagem no console, algo assim:
```
successfully created the book with id: f3f03580-c1aa-d6a9-072d-39e75c69f5c7
```
Verifique a `Books`tabela no banco de dados para ver a nova linha do livro. Você pode tentar `get`, `update`e `delete`funciona mesmo.
### Crie a página de livros
É hora de criar algo visível e utilizável! Em vez do MVC clássico, usaremos a nova abordagem de [interface do usuário do Razor Pages,](https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start) recomendada pela Microsoft.
Crie uma nova `Books`pasta na `Pages`pasta do `Acme.BookStore.Web`projeto e adicione uma nova página Razor denominada `Index.cshtml`:
![livraria-add-index-page](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page-v2.png)
Abra `Index.cshtml`e altere o conteúdo, como mostrado abaixo:
```html
@page
@using Acme.BookStore.Web.Pages.Books
@inherits Acme.BookStore.Web.Pages.BookStorePage
@model IndexModel
<h2>Books</h2>
```
- Esse código altera a herança padrão do Razor View Page Model para que ele **herda** da `BookStorePage`classe (em vez de `PageModel`). A `BookStorePage`classe que acompanha o modelo de inicialização e fornece algumas propriedades / métodos compartilhados usados por todas as páginas.
- Verifique se o `IndexModel`( *Index.cshtml.cs)* possui o `Acme.BookStore.Pages.Books`espaço para nome ou atualize-o no `Index.cshtml`.
#### Adicionar página de livros ao menu principal
Abra a `BookStoreMenuContributor`classe na `Menus`pasta e adicione o seguinte código ao final do `ConfigureMainMenuAsync`método:
```csharp
context.Menu.AddItem(
new ApplicationMenuItem("BooksStore", l["Menu:BookStore"])
.AddItem(new ApplicationMenuItem("BooksStore.Books", l["Menu:Books"], url: "/Books"))
);
```
#### Localizando os itens de menu
Os textos de localização estão localizados na `Localization/BookStore`pasta do `Acme.BookStore.Domain.Shared`projeto:
![arquivos de localização de livraria](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files-v2.png)
Abra o `en.json`arquivo e adicione textos de localização `Menu:BookStore`e `Menu:Books`chaves ao final do arquivo:
```json
{
"culture": "en",
"texts": {
"Menu:BookStore": "Book Store",
"Menu:Books": "Books"
}
}
```
- O sistema de localização da ABP é construído no sistema de [localização padrão do ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization) e o estende de várias maneiras. Consulte o [documento de localização](https://docs.abp.io/en/abp/latest/Localization) para obter detalhes.
- Os nomes das chaves de localização são arbitrários. Você pode definir qualquer nome. Preferimos adicionar `Menu:`prefixo aos itens de menu para distinguir de outros textos. Se um texto não estiver definido no arquivo de localização, ele **recuará** para a chave de localização (comportamento padrão do ASP.NET Core).
Execute o aplicativo e veja se o novo item de menu foi adicionado à barra superior:
![itens-menu-livraria](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-menu-items.png)
Quando você clica no item de menu Livros, você é redirecionado para a nova página Livros.
#### Lista de livros
Usaremos o plug-in [Datatables.net](https://datatables.net/) JQuery para mostrar a lista de tabelas na página. As tabelas de dados podem funcionar completamente via AJAX, são rápidas e oferecem uma boa experiência ao usuário. O plug-in Datatables está configurado no modelo de inicialização, para que você possa usá-lo diretamente em qualquer página sem incluir nenhum estilo ou arquivo de script em sua página.
##### Index.cshtml
Altere o `Pages/Books/Index.cshtml`seguinte:
```html
@page
@inherits Acme.BookStore.Web.Pages.BookStorePage
@model Acme.BookStore.Web.Pages.Books.IndexModel
@section scripts
{
<abp-script src="/Pages/Books/index.js" />
}
<abp-card>
<abp-card-header>
<h2>@L["Books"]</h2>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="BooksTable">
<thead>
<tr>
<th>@L["Name"]</th>
<th>@L["Type"]</th>
<th>@L["PublishDate"]</th>
<th>@L["Price"]</th>
<th>@L["CreationTime"]</th>
</tr>
</thead>
</abp-table>
</abp-card-body>
</abp-card>
```
- `abp-script` [O auxiliar de marca](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro) é usado para adicionar **scripts** externos à página. Possui muitos recursos adicionais em comparação com a `script`tag padrão . Ele lida com **minificação** e **controle** de **versão,** por exemplo. Consulte o [documento de compactação e redução](https://docs.abp.io/en/abp/latest/AspNetCore/Bundling-Minification) para obter detalhes.
- `abp-card`e `abp-table`são **auxiliares de tags** para o [componente de cartão](http://getbootstrap.com/docs/4.1/components/card/) do Twitter Bootstrap . Existem muitos auxiliares de tag no ABP para usar facilmente a maioria dos componentes de [autoinicialização](https://getbootstrap.com/) . Você também pode usar tags HTML regulares em vez desses auxiliares de tag, mas o uso de tag reduz o código HTML e evita erros com a ajuda do intellisense e da verificação do tipo de tempo de compilação. Consulte o [documento auxiliares](https://docs.abp.io/en/abp/latest/AspNetCore/Tag-Helpers) da [tag](https://docs.abp.io/en/abp/latest/AspNetCore/Tag-Helpers) .
- Você pode **localizar** os nomes das colunas no arquivo de localização, como fez nos itens de menu acima.
##### Adicionar um arquivo de script
Crie um `index.js`arquivo JavaScript na `Pages/Books/`pasta:
![arquivo-index-js-bookstore](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file-v2.png)
`index.js` o conteúdo é mostrado abaixo:
```js
$(function () {
var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({
ajax: abp.libs.datatables.createAjax(acme.bookStore.book.getList),
columnDefs: [
{ data: "name" },
{ data: "type" },
{ data: "publishDate" },
{ data: "price" },
{ data: "creationTime" }
]
}));
});
```
- `abp.libs.datatables.createAjax` é uma função auxiliar para adaptar os proxies dinâmicos da API JavaScript da ABP ao formato do Datatable.
- `abp.libs.datatables.normalizeConfiguration`é outra função auxiliar. Não há necessidade de usá-lo, mas simplifica a configuração das tabelas de dados, fornecendo valores convencionais para as opções ausentes.
- `acme.bookStore.book.getList` é a função para obter a lista de livros (você já viu isso antes).
- Consulte [a documentação do Datatable](https://datatables.net/manual/) para obter mais opções de configuração.
A interface do usuário final é mostrada abaixo:
![livraria-lista-de-livros](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-book-list-2.png)
### Próxima parte
Veja a [próxima parte](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-II) deste tutorial.

@ -0,0 +1,466 @@
## Tutorial do ASP.NET Core MVC - Parte II
### Sobre este tutorial
Esta é a segunda parte da série de tutoriais do ASP.NET Core MVC. Veja todas as peças:
- [Parte I: Crie o projeto e uma página da lista de livros](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-I)
- **Parte II: Criar, atualizar e excluir livros (este tutorial)**
- [Parte III: Testes de Integração](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-III)
Você pode acessar o **código fonte** do aplicativo [no repositório GitHub](https://github.com/volosoft/abp/tree/master/samples/BookStore) .
> Você também pode assistir a [este curso em vídeo](https://amazingsolutions.teachable.com/p/lets-build-the-bookstore-application) preparado por um membro da comunidade ABP, com base neste tutorial.
### Criando um novo livro
Nesta seção, você aprenderá como criar um novo formulário de diálogo modal para criar um novo livro. A caixa de diálogo do resultado será assim:
![livraria-criar-diálogo](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog-2.png)
#### Crie o formulário modal
Crie uma nova página de navalha, nomeada `CreateModal.cshtml`sob a `Pages/Books`pasta do `Acme.BookStore.Web`projeto:
![livraria-adicionar-criar-diálogo](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog-v2.png)
##### CreateModal.cshtml.cs
Abra o `CreateModal.cshtml.cs`arquivo ( `CreateModalModel`classe) e substitua pelo seguinte código:
```csharp
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Acme.BookStore.Web.Pages.Books
{
public class CreateModalModel : BookStorePageModel
{
[BindProperty]
public CreateUpdateBookDto Book { get; set; }
private readonly IBookAppService _bookAppService;
public CreateModalModel(IBookAppService bookAppService)
{
_bookAppService = bookAppService;
}
public async Task<IActionResult> OnPostAsync()
{
await _bookAppService.CreateAsync(Book);
return NoContent();
}
}
}
```
- Esta classe é derivada do em `BookStorePageModel`vez do padrão `PageModel`. `BookStorePageModel`herda o `PageModel`e adiciona algumas propriedades / métodos comuns que podem ser usados pelas classes de modelo de página.
- `[BindProperty]`O atributo na `Book`propriedade vincula os dados de solicitação posterior a essa propriedade.
- Essa classe simplesmente injeta o `IBookAppService`em seu construtor e chama o `CreateAsync`método no `OnPostAsync`manipulador.
##### CreateModal.cshtml
Abra o `CreateModal.cshtml`arquivo e cole o código abaixo:
```html
@page
@inherits Acme.BookStore.Web.Pages.BookStorePage
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@model Acme.BookStore.Web.Pages.Books.CreateModalModel
@{
Layout = null;
}
<abp-dynamic-form abp-model="Book" data-ajaxForm="true" asp-page="/Books/CreateModal">
<abp-modal>
<abp-modal-header title="@L["NewBook"].Value"></abp-modal-header>
<abp-modal-body>
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
</abp-dynamic-form>
```
- Este modal usa o
```
abp-dynamic-form
```
auxiliar de marca para criar automaticamente o formulário a partir da
```
CreateBookViewModel
```
classe.
- `abp-model`O atributo indica o objeto do modelo, a `Book`propriedade neste caso.
- `data-ajaxForm` O atributo faz com que o formulário seja enviado via AJAX, em vez de uma postagem de página clássica.
- `abp-form-content`O auxiliar de marca é um espaço reservado para renderizar os controles do formulário (isso é opcional e necessário apenas se você tiver adicionado outro conteúdo à `abp-dynamic-form`marca, como nesta página).
#### Adicione o botão "Novo livro"
Abra `Pages/Books/Index.cshtml`e altere a `abp-card-header`tag, como mostrado abaixo:
```html
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<h2>@L["Books"]</h2>
</abp-column>
<abp-column size-md="_6" class="text-right">
<abp-button id="NewBookButton"
text="@L["NewBook"].Value"
icon="plus"
button-type="Primary" />
</abp-column>
</abp-row>
</abp-card-header>
```
Acabei de adicionar um botão **Novo livro** no canto **superior direito** da tabela:
![livraria-novo-livro-botão](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-new-book-button.png)
Abra o `pages/books/index.js`e adicione o seguinte código logo após a configuração da tabela de dados:
```js
var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
createModal.onResult(function () {
dataTable.ajax.reload();
});
$('#NewBookButton').click(function (e) {
e.preventDefault();
createModal.open();
});
```
- `abp.ModalManager`é uma classe auxiliar para abrir e gerenciar modais no lado do cliente. Ele usa internamente o modal padrão do Twitter Bootstrap, mas abstrai muitos detalhes, fornecendo uma API simples.
Agora, você pode **executar o aplicativo** e adicionar novos livros usando o novo formulário modal.
### Atualizando um livro existente
Crie uma nova página de navalha, nomeada `EditModal.cshtml`sob a `Pages/Books`pasta do `Acme.BookStore.Web`projeto:
![livraria-adicionar-editar-diálogo](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-add-edit-dialog.png)
#### EditModal.cshtml.cs
Abra o `EditModal.cshtml.cs`arquivo ( `EditModalModel`classe) e substitua pelo seguinte código:
```csharp
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Acme.BookStore.Web.Pages.Books
{
public class EditModalModel : BookStorePageModel
{
[HiddenInput]
[BindProperty(SupportsGet = true)]
public Guid Id { get; set; }
[BindProperty]
public CreateUpdateBookDto Book { get; set; }
private readonly IBookAppService _bookAppService;
public EditModalModel(IBookAppService bookAppService)
{
_bookAppService = bookAppService;
}
public async Task OnGetAsync()
{
var bookDto = await _bookAppService.GetAsync(Id);
Book = ObjectMapper.Map<BookDto, CreateUpdateBookDto>(bookDto);
}
public async Task<IActionResult> OnPostAsync()
{
await _bookAppService.UpdateAsync(Id, Book);
return NoContent();
}
}
}
```
- `[HiddenInput]`e `[BindProperty]`são atributos padrão do ASP.NET Core MVC. Utilizado `SupportsGet`para obter o valor do ID a partir do parâmetro da string de consulta da solicitação.
- Mapeado `BookDto`(recebido de `BookAppService.GetAsync`) para `CreateUpdateBookDto`no `GetAsync`método
- O `OnPostAsync`simplesmente usa `BookAppService.UpdateAsync`para atualizar a entidade.
#### Mapeamento de BookDto para CreateUpdateBookDto
A fim de executar `BookDto`a `CreateUpdateBookDto`opor mapeamento, abrir o `BookStoreWebAutoMapperProfile.cs`no `Acme.BookStore.Web`projecto e alterá-lo como se mostra abaixo:
```csharp
using AutoMapper;
namespace Acme.BookStore.Web
{
public class BookStoreWebAutoMapperProfile : Profile
{
public BookStoreWebAutoMapperProfile()
{
CreateMap<BookDto, CreateUpdateBookDto>();
}
}
}
```
- Apenas adicionado `CreateMap<BookDto, CreateUpdateBookDto>();`como a definição de mapeamento.
#### EditModal.cshtml
Substitua o `EditModal.cshtml`conteúdo pelo seguinte:
```html
@page
@inherits Acme.BookStore.Web.Pages.BookStorePage
@using Acme.BookStore.Web.Pages.Books
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@model EditModalModel
@{
Layout = null;
}
<abp-dynamic-form abp-model="Book" data-ajaxForm="true" asp-page="/Books/EditModal">
<abp-modal>
<abp-modal-header title="@L["Update"].Value"></abp-modal-header>
<abp-modal-body>
<abp-input asp-for="Id" />
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
</abp-modal>
</abp-dynamic-form>
```
Esta página é muito semelhante à `CreateModal.cshtml`exceção;
- Ele inclui um `abp-input`para a `Id`propriedade armazenar o ID do livro de edição (que é uma entrada oculta).
- Ele usa `Books/EditModal`como URL de postagem e texto de *atualização* como cabeçalho modal.
#### Adicione o menu suspenso "Ações" à tabela
Adicionaremos um botão suspenso ("Ações") para cada linha da tabela. A interface do usuário final é assim:
![livraria-livros-mesa-ações](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-books-table-actions.png)
Abra a `Pages/Books/Index.cshtml`página e altere a seção da tabela como mostrado abaixo:
```html
<abp-table striped-rows="true" id="BooksTable">
<thead>
<tr>
<th>@L["Actions"]</th>
<th>@L["Name"]</th>
<th>@L["Type"]</th>
<th>@L["PublishDate"]</th>
<th>@L["Price"]</th>
<th>@L["CreationTime"]</th>
</tr>
</thead>
</abp-table>
```
- Acabei de adicionar uma nova `th`tag para as "Ações".
Abra `pages/books/index.js`e substitua o conteúdo como abaixo:
```js
$(function () {
var l = abp.localization.getResource('BookStore');
var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
var editModal = new abp.ModalManager(abp.appPath + 'Books/EditModal');
var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
autoWidth: false,
scrollCollapse: true,
order: [[1, "asc"]],
ajax: abp.libs.datatables.createAjax(acme.bookStore.book.getList),
columnDefs: [
{
rowAction: {
items:
[
{
text: l('Edit'),
action: function (data) {
editModal.open({ id: data.record.id });
}
}
]
}
},
{ data: "name" },
{ data: "type" },
{ data: "publishDate" },
{ data: "price" },
{ data: "creationTime" }
]
}));
createModal.onResult(function () {
dataTable.ajax.reload();
});
editModal.onResult(function () {
dataTable.ajax.reload();
});
$('#NewBookButton').click(function (e) {
e.preventDefault();
createModal.open();
});
});
```
- Utilizado `abp.localization.getResource('BookStore')`para poder usar os mesmos textos de localização definidos no lado do servidor.
- Adicionado um novo `ModalManager`nome `createModal`para abrir a caixa de diálogo criar modal.
- Adicionado um novo `ModalManager`nome `editModal`para abrir a caixa de diálogo modal de edição.
- Adicionada uma nova coluna no início da `columnDefs`seção. Esta coluna é usada para o botão suspenso "Ações".
- A ação "Novo livro" simplesmente chama `createModal.open`para abrir a caixa de diálogo Criar.
- A ação "Editar" simplesmente chama `editModal.open`para abrir a caixa de diálogo de edição. `Você pode executar o aplicativo e editar qualquer livro selecionando a ação de edição.
### Exclusão de um livro existente
Abra o `pages/books/index.js`e adicione um novo item ao `rowAction` `items`:
```js
{
text: l('Delete'),
confirmMessage: function (data) {
return l('BookDeletionConfirmationMessage', data.record.name);
},
action: function (data) {
acme.bookStore.book
.delete(data.record.id)
.then(function() {
abp.notify.info(l('SuccessfullyDeleted'));
dataTable.ajax.reload();
});
}
}
```
- `confirmMessage`A opção é usada para fazer uma pergunta de confirmação antes de executar o `action`.
- Utilizou a `acme.bookStore.book.delete`função de proxy javascript para executar uma solicitação AJAX para excluir um livro.
- `abp.notify.info` é usado para mostrar uma notificação toastr logo após a exclusão.
O `index.js`conteúdo final é mostrado abaixo:
```js
$(function () {
var l = abp.localization.getResource('BookStore');
var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
var editModal = new abp.ModalManager(abp.appPath + 'Books/EditModal');
var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
autoWidth: false,
scrollCollapse: true,
order: [[1, "asc"]],
ajax: abp.libs.datatables.createAjax(acme.bookStore.book.getList),
columnDefs: [
{
rowAction: {
items:
[
{
text: l('Edit'),
action: function (data) {
editModal.open({ id: data.record.id });
}
},
{
text: l('Delete'),
confirmMessage: function (data) {
return l('BookDeletionConfirmationMessage', data.record.name);
},
action: function (data) {
acme.bookStore.book
.delete(data.record.id)
.then(function() {
abp.notify.info(l('SuccessfullyDeleted'));
dataTable.ajax.reload();
});
}
}
]
}
},
{ data: "name" },
{ data: "type" },
{ data: "publishDate" },
{ data: "price" },
{ data: "creationTime" }
]
}));
createModal.onResult(function () {
dataTable.ajax.reload();
});
editModal.onResult(function () {
dataTable.ajax.reload();
});
$('#NewBookButton').click(function (e) {
e.preventDefault();
createModal.open();
});
});
```
Abra o `en.json`no `Acme.BookStore.Domain.Shared`projeto e adicione a seguinte linha:
```json
"BookDeletionConfirmationMessage": "Are you sure to delete the book {0}?"
```
Execute o aplicativo e tente excluir um livro.
### Próxima parte
Veja a [próxima parte](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-III) deste tutorial.

@ -0,0 +1,182 @@
## Tutorial do ASP.NET Core MVC - Parte III
### Sobre este tutorial
Esta é a terceira parte da série de tutoriais do ASP.NET Core MVC. Veja todas as peças:
- [Parte I: Crie o projeto e uma página da lista de livros](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-I)
- [Parte II: Criar, atualizar e excluir livros](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-II)
- **Parte III: Testes de Integração (este tutorial)**
Você pode acessar o **código fonte** do aplicativo [no repositório GitHub](https://github.com/volosoft/abp/tree/master/samples/BookStore) .
> Você também pode assistir a [este curso em vídeo](https://amazingsolutions.teachable.com/p/lets-build-the-bookstore-application) preparado por um membro da comunidade ABP, com base neste tutorial.
### Testar projetos na solução
Existem vários projetos de teste na solução:
![livraria-teste-projetos-v2](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects-v2.png)
Cada projeto é usado para testar o projeto de aplicativo relacionado. Os projetos de teste usam as seguintes bibliotecas para teste:
- [xunit](https://xunit.github.io/) como a principal estrutura de teste.
- [Altamente](http://shouldly.readthedocs.io/en/latest/) como uma biblioteca de asserções.
- [NSubstitute](http://nsubstitute.github.io/) como uma biblioteca de zombaria.
### Adicionando dados de teste
O modelo de inicialização contém a `BookStoreTestDataSeedContributor`classe no `Acme.BookStore.TestBase`projeto que cria alguns dados para executar os testes.
Mude a `BookStoreTestDataSeedContributor`classe como mostrado abaixo:
```csharp
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;
namespace Acme.BookStore
{
public class BookStoreTestDataSeedContributor
: IDataSeedContributor, ITransientDependency
{
private readonly IRepository<Book, Guid> _bookRepository;
private readonly IGuidGenerator _guidGenerator;
public BookStoreTestDataSeedContributor(
IRepository<Book, Guid> bookRepository,
IGuidGenerator guidGenerator)
{
_bookRepository = bookRepository;
_guidGenerator = guidGenerator;
}
public async Task SeedAsync(DataSeedContext context)
{
await _bookRepository.InsertAsync(
new Book
{
Id = _guidGenerator.Create(),
Name = "Test book 1",
Type = BookType.Fantastic,
PublishDate = new DateTime(2015, 05, 24),
Price = 21
}
);
await _bookRepository.InsertAsync(
new Book
{
Id = _guidGenerator.Create(),
Name = "Test book 2",
Type = BookType.Science,
PublishDate = new DateTime(2014, 02, 11),
Price = 15
}
);
}
}
}
```
- Injetado `IRepository<Book, Guid>`e usado no `SeedAsync`para criar duas entidades de livro como dados de teste.
- `IGuidGenerator`Serviço usado para criar GUIDs. Embora `Guid.NewGuid()`funcionasse perfeitamente para testes, `IGuidGenerator`possui recursos adicionais especialmente importantes ao usar bancos de dados reais (consulte o [documento de geração](https://docs.abp.io/en/abp/latest/Guid-Generation) do [Guid](https://docs.abp.io/en/abp/latest/Guid-Generation) para obter mais informações).
### Testando o BookAppService
Crie uma classe de teste denominada `BookAppService_Tests`no `Acme.BookStore.Application.Tests`projeto:
```csharp
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Application.Dtos;
using Xunit;
namespace Acme.BookStore
{
public class BookAppService_Tests : BookStoreApplicationTestBase
{
private readonly IBookAppService _bookAppService;
public BookAppService_Tests()
{
_bookAppService = GetRequiredService<IBookAppService>();
}
[Fact]
public async Task Should_Get_List_Of_Books()
{
//Act
var result = await _bookAppService.GetListAsync(
new PagedAndSortedResultRequestDto()
);
//Assert
result.TotalCount.ShouldBeGreaterThan(0);
result.Items.ShouldContain(b => b.Name == "Test book 1");
}
}
}
```
- `Should_Get_List_Of_Books`O teste simplesmente usa o `BookAppService.GetListAsync`método para obter e verificar a lista de usuários.
Adicione um novo teste que crie um novo livro válido:
```csharp
[Fact]
public async Task Should_Create_A_Valid_Book()
{
//Act
var result = await _bookAppService.CreateAsync(
new CreateUpdateBookDto
{
Name = "New test book 42",
Price = 10,
PublishDate = DateTime.Now,
Type = BookType.ScienceFiction
}
);
//Assert
result.Id.ShouldNotBe(Guid.Empty);
result.Name.ShouldBe("New test book 42");
}
```
Adicione um novo teste que tente criar um livro inválido e falhe:
```csharp
[Fact]
public async Task Should_Not_Create_A_Book_Without_Name()
{
var exception = await Assert.ThrowsAsync<AbpValidationException>(async () =>
{
await _bookAppService.CreateAsync(
new CreateUpdateBookDto
{
Name = "",
Price = 10,
PublishDate = DateTime.Now,
Type = BookType.ScienceFiction
}
);
});
exception.ValidationErrors
.ShouldContain(err => err.MemberNames.Any(mem => mem == "Name"));
}
```
- Como o `Name`está vazio, o ABP lança um `AbpValidationException`.
Abra a **janela Test Explorer** (use o menu Test -> Windows -> Test Explorer, se não estiver visível) e **execute Todos os** testes:
![testes de serviço de livraria](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-appservice-tests.png)
Parabéns, ícones verdes mostram que os testes foram aprovados com sucesso!

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Luxon
{
public class LuxonScriptContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("/libs/luxon/luxon.min.js");
}
}
}

@ -5,6 +5,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryForm;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidationUnobtrusive;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Lodash;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Luxon;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Select2;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.SweetAlert;
@ -25,6 +26,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling
typeof(SweetalertScriptContributor),
typeof(ToastrScriptBundleContributor),
typeof(MalihuCustomScrollbarPluginScriptBundleContributor),
typeof(LuxonScriptContributor),
typeof(TimeagoScriptContributor)
)]
public class SharedThemeGlobalScriptContributor : BundleContributor

@ -78,11 +78,6 @@ namespace Volo.Docs.Pages.Documents.Project
DocumentsUrlPrefix = _uiOptions.RoutePrefix;
ShowProjectsCombobox = _uiOptions.ShowProjectsCombobox;
if (IsDocumentCultureDifferentThanCurrent())
{
return ReloadPageWithCulture();
}
await SetProjectAsync();
if (ShowProjectsCombobox)
@ -103,6 +98,11 @@ namespace Volo.Docs.Pages.Documents.Project
return RedirectToDefaultLanguage();
}
if (IsDocumentCultureDifferentThanCurrent())
{
return ReloadPageWithCulture();
}
await SetDocumentAsync();
await SetNavigationAsync();
SetLanguageSelectListItems();
@ -122,7 +122,6 @@ namespace Volo.Docs.Pages.Documents.Project
{
return false;
}
}
private bool IsDefaultDocument()
@ -153,7 +152,8 @@ namespace Volo.Docs.Pages.Documents.Project
private IActionResult ReloadPageWithCulture()
{
var returnUrl = DocumentsUrlPrefix + LanguageCode + "/" + ProjectName + "/" + Version + "/" +
var returnUrl = DocumentsUrlPrefix + LanguageCode + "/" + ProjectName + "/"
+ (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version) + "/" +
DocumentName;
return Redirect("/Abp/Languages/Switch?culture=" + LanguageCode + "&uiCulture=" + LanguageCode + "&returnUrl=" + returnUrl);
@ -164,7 +164,7 @@ namespace Volo.Docs.Pages.Documents.Project
return RedirectToPage(new
{
projectName = ProjectName,
version = Version,
version = (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version),
languageCode = DefaultLanguageCode
});
}
@ -174,7 +174,7 @@ namespace Volo.Docs.Pages.Documents.Project
return RedirectToPage(new
{
projectName = ProjectName,
version = Version,
version = (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version),
documentName = "",
languageCode = DefaultLanguageCode
});
@ -355,7 +355,7 @@ namespace Volo.Docs.Pages.Documents.Project
LanguageSelectListItems.Add(
new SelectListItem(
language.DisplayName,
DocumentsUrlPrefix + language.Code + "/" + Project.ShortName + "/" + Version + "/" + DocumentName,
DocumentsUrlPrefix + language.Code + "/" + Project.ShortName + "/" + (LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Version) + "/" + DocumentName,
language.Code == LanguageCode
)
);

@ -2,10 +2,10 @@
* Generated bundle index. Do not edit.
*/
export * from './public-api';
export { AccountRoutingModule as ɵh } from './lib/account-routing.module';
export { LoginComponent as ɵc } from './lib/components/login/login.component';
export { RegisterComponent as ɵe } from './lib/components/register/register.component';
export { TenantBoxComponent as ɵg } from './lib/components/tenant-box/tenant-box.component';
export { Options as ɵd } from './lib/models/options';
export { AccountService as ɵf } from './lib/services/account.service';
export { ACCOUNT_OPTIONS as ɵb, optionsFactory as ɵa } from './lib/tokens/options.token';
export { AccountRoutingModule as ɵf } from './lib/account-routing.module';
export { LoginComponent as ɵa } from './lib/components/login/login.component';
export { RegisterComponent as ɵc } from './lib/components/register/register.component';
export { TenantBoxComponent as ɵe } from './lib/components/tenant-box/tenant-box.component';
export { Options as ɵb } from './lib/models/options';
export { AccountService as ɵd } from './lib/services/account.service';
export { ACCOUNT_OPTIONS as ɵh, optionsFactory as ɵg } from './lib/tokens/options.token';

File diff suppressed because one or more lines are too long

@ -1,8 +1,8 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@abp/ng.core'), require('@abp/ng.theme.shared'), require('@ng-bootstrap/ng-bootstrap'), require('@ngx-validate/core'), require('primeng/table'), require('@angular/router'), require('@angular/forms'), require('@ngxs/router-plugin'), require('@ngxs/store'), require('angular-oauth2-oidc'), require('rxjs'), require('rxjs/operators'), require('snq')) :
typeof define === 'function' && define.amd ? define('@abp/ng.account', ['exports', '@angular/core', '@abp/ng.core', '@abp/ng.theme.shared', '@ng-bootstrap/ng-bootstrap', '@ngx-validate/core', 'primeng/table', '@angular/router', '@angular/forms', '@ngxs/router-plugin', '@ngxs/store', 'angular-oauth2-oidc', 'rxjs', 'rxjs/operators', 'snq'], factory) :
(global = global || self, factory((global.abp = global.abp || {}, global.abp.ng = global.abp.ng || {}, global.abp.ng.account = {}), global.ng.core, global.ng_core, global.ng_theme_shared, global.ngBootstrap, global.core$1, global.table, global.ng.router, global.ng.forms, global.routerPlugin, global.store, global.angularOauth2Oidc, global.rxjs, global.rxjs.operators, global.snq));
}(this, function (exports, core, ng_core, ng_theme_shared, ngBootstrap, core$1, table, router, forms, routerPlugin, store, angularOauth2Oidc, rxjs, operators, snq) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@abp/ng.core'), require('@abp/ng.theme.shared'), require('@angular/core'), require('@ng-bootstrap/ng-bootstrap'), require('@ngx-validate/core'), require('primeng/table'), require('@angular/router'), require('@angular/forms'), require('@ngxs/router-plugin'), require('@ngxs/store'), require('angular-oauth2-oidc'), require('rxjs'), require('rxjs/operators'), require('snq')) :
typeof define === 'function' && define.amd ? define('@abp/ng.account', ['exports', '@abp/ng.core', '@abp/ng.theme.shared', '@angular/core', '@ng-bootstrap/ng-bootstrap', '@ngx-validate/core', 'primeng/table', '@angular/router', '@angular/forms', '@ngxs/router-plugin', '@ngxs/store', 'angular-oauth2-oidc', 'rxjs', 'rxjs/operators', 'snq'], factory) :
(global = global || self, factory((global.abp = global.abp || {}, global.abp.ng = global.abp.ng || {}, global.abp.ng.account = {}), global.ng_core, global.ng_theme_shared, global.ng.core, global.ngBootstrap, global.core$1, global.table, global.ng.router, global.ng.forms, global.routerPlugin, global.store, global.angularOauth2Oidc, global.rxjs, global.rxjs.operators, global.snq));
}(this, function (exports, ng_core, ng_theme_shared, core, ngBootstrap, core$1, table, router, forms, routerPlugin, store, angularOauth2Oidc, rxjs, operators, snq) { 'use strict';
snq = snq && snq.hasOwnProperty('default') ? snq['default'] : snq;
@ -203,55 +203,6 @@
return (mod && mod.__esModule) ? mod : { default: mod };
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} options
* @return {?}
*/
function optionsFactory(options) {
return __assign({ redirectUrl: '/' }, options);
}
/** @type {?} */
var ACCOUNT_OPTIONS = new core.InjectionToken('ACCOUNT_OPTIONS');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var RootAccountModule = /** @class */ (function () {
function RootAccountModule() {
}
/**
* @param {?=} options
* @return {?}
*/
RootAccountModule.forRoot = /**
* @param {?=} options
* @return {?}
*/
function (options) {
if (options === void 0) { options = (/** @type {?} */ ({})); }
return {
ngModule: RootAccountModule,
providers: [
{ provide: ACCOUNT_OPTIONS, useValue: options },
{
provide: 'ACCOUNT_OPTIONS',
useFactory: optionsFactory,
deps: [ACCOUNT_OPTIONS],
},
],
};
};
RootAccountModule.decorators = [
{ type: core.NgModule, args: [{},] }
];
return RootAccountModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
@ -688,6 +639,20 @@
TenantBoxComponent.prototype.accountService;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @param {?} options
* @return {?}
*/
function optionsFactory(options) {
return __assign({ redirectUrl: '/' }, options);
}
/** @type {?} */
var ACCOUNT_OPTIONS = new core.InjectionToken('ACCOUNT_OPTIONS');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
@ -704,6 +669,21 @@
];
return AccountModule;
}());
/**
* @param {?=} options
* @return {?}
*/
function AccountProviders(options) {
if (options === void 0) { options = (/** @type {?} */ ({})); }
return [
{ provide: ACCOUNT_OPTIONS, useValue: options },
{
provide: 'ACCOUNT_OPTIONS',
useFactory: optionsFactory,
deps: [ACCOUNT_OPTIONS],
},
];
}
/**
* @fileoverview added by tsickle
@ -829,17 +809,17 @@
exports.ACCOUNT_OPTIONS = ACCOUNT_OPTIONS;
exports.ACCOUNT_ROUTES = ACCOUNT_ROUTES;
exports.AccountModule = AccountModule;
exports.AccountProviders = AccountProviders;
exports.LoginComponent = LoginComponent;
exports.RegisterComponent = RegisterComponent;
exports.RootAccountModule = RootAccountModule;
exports.optionsFactory = optionsFactory;
exports.ɵa = optionsFactory;
exports.ɵb = ACCOUNT_OPTIONS;
exports.ɵc = LoginComponent;
exports.ɵe = RegisterComponent;
exports.ɵf = AccountService;
exports.ɵg = TenantBoxComponent;
exports.ɵh = AccountRoutingModule;
exports.ɵa = LoginComponent;
exports.ɵc = RegisterComponent;
exports.ɵd = AccountService;
exports.ɵe = TenantBoxComponent;
exports.ɵf = AccountRoutingModule;
exports.ɵg = optionsFactory;
exports.ɵh = ACCOUNT_OPTIONS;
Object.defineProperty(exports, '__esModule', { value: true });

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

@ -5,11 +5,11 @@
/**
* Generated bundle index. Do not edit.
*/
export { RootAccountModule, AccountModule, LoginComponent, RegisterComponent, ACCOUNT_ROUTES, optionsFactory, ACCOUNT_OPTIONS } from './public-api';
export { AccountRoutingModule as ɵh } from './lib/account-routing.module';
export { LoginComponent as ɵc } from './lib/components/login/login.component';
export { RegisterComponent as ɵe } from './lib/components/register/register.component';
export { TenantBoxComponent as ɵg } from './lib/components/tenant-box/tenant-box.component';
export { AccountService as ɵf } from './lib/services/account.service';
export { ACCOUNT_OPTIONS as ɵb, optionsFactory as ɵa } from './lib/tokens/options.token';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJwLW5nLmFjY291bnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AYWJwL25nLmFjY291bnQvIiwic291cmNlcyI6WyJhYnAtbmcuYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBSUEscUlBQWMsY0FBYyxDQUFDO0FBRTdCLE9BQU8sRUFBQyxvQkFBb0IsSUFBSSxFQUFFLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RSxPQUFPLEVBQUMsY0FBYyxJQUFJLEVBQUUsRUFBQyxNQUFNLHdDQUF3QyxDQUFDO0FBQzVFLE9BQU8sRUFBQyxpQkFBaUIsSUFBSSxFQUFFLEVBQUMsTUFBTSw4Q0FBOEMsQ0FBQztBQUNyRixPQUFPLEVBQUMsa0JBQWtCLElBQUksRUFBRSxFQUFDLE1BQU0sa0RBQWtELENBQUM7QUFFMUYsT0FBTyxFQUFDLGNBQWMsSUFBSSxFQUFFLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEVBQUMsZUFBZSxJQUFJLEVBQUUsRUFBQyxjQUFjLElBQUksRUFBRSxFQUFDLE1BQU0sNEJBQTRCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG5cbmV4cG9ydCB7QWNjb3VudFJvdXRpbmdNb2R1bGUgYXMgybVofSBmcm9tICcuL2xpYi9hY2NvdW50LXJvdXRpbmcubW9kdWxlJztcbmV4cG9ydCB7TG9naW5Db21wb25lbnQgYXMgybVjfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL2xvZ2luL2xvZ2luLmNvbXBvbmVudCc7XG5leHBvcnQge1JlZ2lzdGVyQ29tcG9uZW50IGFzIMm1ZX0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9yZWdpc3Rlci9yZWdpc3Rlci5jb21wb25lbnQnO1xuZXhwb3J0IHtUZW5hbnRCb3hDb21wb25lbnQgYXMgybVnfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3RlbmFudC1ib3gvdGVuYW50LWJveC5jb21wb25lbnQnO1xuZXhwb3J0IHtPcHRpb25zIGFzIMm1ZH0gZnJvbSAnLi9saWIvbW9kZWxzL29wdGlvbnMnO1xuZXhwb3J0IHtBY2NvdW50U2VydmljZSBhcyDJtWZ9IGZyb20gJy4vbGliL3NlcnZpY2VzL2FjY291bnQuc2VydmljZSc7XG5leHBvcnQge0FDQ09VTlRfT1BUSU9OUyBhcyDJtWIsb3B0aW9uc0ZhY3RvcnkgYXMgybVhfSBmcm9tICcuL2xpYi90b2tlbnMvb3B0aW9ucy50b2tlbic7Il19
export { AccountProviders, AccountModule, LoginComponent, RegisterComponent, ACCOUNT_ROUTES, optionsFactory, ACCOUNT_OPTIONS } from './public-api';
export { AccountRoutingModule as ɵf } from './lib/account-routing.module';
export { LoginComponent as ɵa } from './lib/components/login/login.component';
export { RegisterComponent as ɵc } from './lib/components/register/register.component';
export { TenantBoxComponent as ɵe } from './lib/components/tenant-box/tenant-box.component';
export { AccountService as ɵd } from './lib/services/account.service';
export { ACCOUNT_OPTIONS as ɵh, optionsFactory as ɵg } from './lib/tokens/options.token';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJwLW5nLmFjY291bnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AYWJwL25nLmFjY291bnQvIiwic291cmNlcyI6WyJhYnAtbmcuYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBSUEsb0lBQWMsY0FBYyxDQUFDO0FBRTdCLE9BQU8sRUFBQyxvQkFBb0IsSUFBSSxFQUFFLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RSxPQUFPLEVBQUMsY0FBYyxJQUFJLEVBQUUsRUFBQyxNQUFNLHdDQUF3QyxDQUFDO0FBQzVFLE9BQU8sRUFBQyxpQkFBaUIsSUFBSSxFQUFFLEVBQUMsTUFBTSw4Q0FBOEMsQ0FBQztBQUNyRixPQUFPLEVBQUMsa0JBQWtCLElBQUksRUFBRSxFQUFDLE1BQU0sa0RBQWtELENBQUM7QUFFMUYsT0FBTyxFQUFDLGNBQWMsSUFBSSxFQUFFLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEVBQUMsZUFBZSxJQUFJLEVBQUUsRUFBQyxjQUFjLElBQUksRUFBRSxFQUFDLE1BQU0sNEJBQTRCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG5cbmV4cG9ydCB7QWNjb3VudFJvdXRpbmdNb2R1bGUgYXMgybVmfSBmcm9tICcuL2xpYi9hY2NvdW50LXJvdXRpbmcubW9kdWxlJztcbmV4cG9ydCB7TG9naW5Db21wb25lbnQgYXMgybVhfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL2xvZ2luL2xvZ2luLmNvbXBvbmVudCc7XG5leHBvcnQge1JlZ2lzdGVyQ29tcG9uZW50IGFzIMm1Y30gZnJvbSAnLi9saWIvY29tcG9uZW50cy9yZWdpc3Rlci9yZWdpc3Rlci5jb21wb25lbnQnO1xuZXhwb3J0IHtUZW5hbnRCb3hDb21wb25lbnQgYXMgybVlfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3RlbmFudC1ib3gvdGVuYW50LWJveC5jb21wb25lbnQnO1xuZXhwb3J0IHtPcHRpb25zIGFzIMm1Yn0gZnJvbSAnLi9saWIvbW9kZWxzL29wdGlvbnMnO1xuZXhwb3J0IHtBY2NvdW50U2VydmljZSBhcyDJtWR9IGZyb20gJy4vbGliL3NlcnZpY2VzL2FjY291bnQuc2VydmljZSc7XG5leHBvcnQge0FDQ09VTlRfT1BUSU9OUyBhcyDJtWgsb3B0aW9uc0ZhY3RvcnkgYXMgybVnfSBmcm9tICcuL2xpYi90b2tlbnMvb3B0aW9ucy50b2tlbic7Il19

@ -12,6 +12,7 @@ import { AccountRoutingModule } from './account-routing.module';
import { LoginComponent } from './components/login/login.component';
import { RegisterComponent } from './components/register/register.component';
import { TenantBoxComponent } from './components/tenant-box/tenant-box.component';
import { ACCOUNT_OPTIONS, optionsFactory } from './tokens/options.token';
export class AccountModule {
}
AccountModule.decorators = [
@ -21,4 +22,18 @@ AccountModule.decorators = [
exports: [],
},] }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudC5tb2R1bGUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AYWJwL25nLmFjY291bnQvIiwic291cmNlcyI6WyJsaWIvYWNjb3VudC5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDMUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQU9sRixNQUFNLE9BQU8sYUFBYTs7O1lBTHpCLFFBQVEsU0FBQztnQkFDUixZQUFZLEVBQUUsQ0FBQyxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLENBQUM7Z0JBQ3JFLE9BQU8sRUFBRSxDQUFDLFVBQVUsRUFBRSxvQkFBb0IsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsaUJBQWlCLEVBQUUscUJBQXFCLENBQUM7Z0JBQ3JILE9BQU8sRUFBRSxFQUFFO2FBQ1oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb3JlTW9kdWxlIH0gZnJvbSAnQGFicC9uZy5jb3JlJztcbmltcG9ydCB7IFRoZW1lU2hhcmVkTW9kdWxlIH0gZnJvbSAnQGFicC9uZy50aGVtZS5zaGFyZWQnO1xuaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5nYkRyb3Bkb3duTW9kdWxlIH0gZnJvbSAnQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAnO1xuaW1wb3J0IHsgTmd4VmFsaWRhdGVDb3JlTW9kdWxlIH0gZnJvbSAnQG5neC12YWxpZGF0ZS9jb3JlJztcbmltcG9ydCB7IFRhYmxlTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90YWJsZSc7XG5pbXBvcnQgeyBBY2NvdW50Um91dGluZ01vZHVsZSB9IGZyb20gJy4vYWNjb3VudC1yb3V0aW5nLm1vZHVsZSc7XG5pbXBvcnQgeyBMb2dpbkNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9sb2dpbi9sb2dpbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVnaXN0ZXJDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvcmVnaXN0ZXIvcmVnaXN0ZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFRlbmFudEJveENvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy90ZW5hbnQtYm94L3RlbmFudC1ib3guY29tcG9uZW50JztcblxuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbTG9naW5Db21wb25lbnQsIFJlZ2lzdGVyQ29tcG9uZW50LCBUZW5hbnRCb3hDb21wb25lbnRdLFxuICBpbXBvcnRzOiBbQ29yZU1vZHVsZSwgQWNjb3VudFJvdXRpbmdNb2R1bGUsIFRoZW1lU2hhcmVkTW9kdWxlLCBUYWJsZU1vZHVsZSwgTmdiRHJvcGRvd25Nb2R1bGUsIE5neFZhbGlkYXRlQ29yZU1vZHVsZV0sXG4gIGV4cG9ydHM6IFtdLFxufSlcbmV4cG9ydCBjbGFzcyBBY2NvdW50TW9kdWxlIHt9XG4iXX0=
/**
* @param {?=} options
* @return {?}
*/
export function AccountProviders(options = (/** @type {?} */ ({}))) {
return [
{ provide: ACCOUNT_OPTIONS, useValue: options },
{
provide: 'ACCOUNT_OPTIONS',
useFactory: optionsFactory,
deps: [ACCOUNT_OPTIONS],
},
];
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudC5tb2R1bGUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AYWJwL25nLmFjY291bnQvIiwic291cmNlcyI6WyJsaWIvYWNjb3VudC5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDMUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUFFLFFBQVEsRUFBWSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUVsRixPQUFPLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBT3pFLE1BQU0sT0FBTyxhQUFhOzs7WUFMekIsUUFBUSxTQUFDO2dCQUNSLFlBQVksRUFBRSxDQUFDLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxrQkFBa0IsQ0FBQztnQkFDckUsT0FBTyxFQUFFLENBQUMsVUFBVSxFQUFFLG9CQUFvQixFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxxQkFBcUIsQ0FBQztnQkFDckgsT0FBTyxFQUFFLEVBQUU7YUFDWjs7Ozs7O0FBR0QsTUFBTSxVQUFVLGdCQUFnQixDQUFDLE9BQU8sR0FBRyxtQkFBQSxFQUFFLEVBQVc7SUFDdEQsT0FBTztRQUNMLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFO1FBQy9DO1lBQ0UsT0FBTyxFQUFFLGlCQUFpQjtZQUMxQixVQUFVLEVBQUUsY0FBYztZQUMxQixJQUFJLEVBQUUsQ0FBQyxlQUFlLENBQUM7U0FDeEI7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvcmVNb2R1bGUgfSBmcm9tICdAYWJwL25nLmNvcmUnO1xuaW1wb3J0IHsgVGhlbWVTaGFyZWRNb2R1bGUgfSBmcm9tICdAYWJwL25nLnRoZW1lLnNoYXJlZCc7XG5pbXBvcnQgeyBOZ01vZHVsZSwgUHJvdmlkZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5nYkRyb3Bkb3duTW9kdWxlIH0gZnJvbSAnQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAnO1xuaW1wb3J0IHsgTmd4VmFsaWRhdGVDb3JlTW9kdWxlIH0gZnJvbSAnQG5neC12YWxpZGF0ZS9jb3JlJztcbmltcG9ydCB7IFRhYmxlTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90YWJsZSc7XG5pbXBvcnQgeyBBY2NvdW50Um91dGluZ01vZHVsZSB9IGZyb20gJy4vYWNjb3VudC1yb3V0aW5nLm1vZHVsZSc7XG5pbXBvcnQgeyBMb2dpbkNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9sb2dpbi9sb2dpbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVnaXN0ZXJDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvcmVnaXN0ZXIvcmVnaXN0ZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFRlbmFudEJveENvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy90ZW5hbnQtYm94L3RlbmFudC1ib3guY29tcG9uZW50JztcbmltcG9ydCB7IE9wdGlvbnMgfSBmcm9tICcuL21vZGVscy9vcHRpb25zJztcbmltcG9ydCB7IEFDQ09VTlRfT1BUSU9OUywgb3B0aW9uc0ZhY3RvcnkgfSBmcm9tICcuL3Rva2Vucy9vcHRpb25zLnRva2VuJztcblxuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbTG9naW5Db21wb25lbnQsIFJlZ2lzdGVyQ29tcG9uZW50LCBUZW5hbnRCb3hDb21wb25lbnRdLFxuICBpbXBvcnRzOiBbQ29yZU1vZHVsZSwgQWNjb3VudFJvdXRpbmdNb2R1bGUsIFRoZW1lU2hhcmVkTW9kdWxlLCBUYWJsZU1vZHVsZSwgTmdiRHJvcGRvd25Nb2R1bGUsIE5neFZhbGlkYXRlQ29yZU1vZHVsZV0sXG4gIGV4cG9ydHM6IFtdLFxufSlcbmV4cG9ydCBjbGFzcyBBY2NvdW50TW9kdWxlIHt9XG5cbmV4cG9ydCBmdW5jdGlvbiBBY2NvdW50UHJvdmlkZXJzKG9wdGlvbnMgPSB7fSBhcyBPcHRpb25zKTogUHJvdmlkZXJbXSB7XG4gIHJldHVybiBbXG4gICAgeyBwcm92aWRlOiBBQ0NPVU5UX09QVElPTlMsIHVzZVZhbHVlOiBvcHRpb25zIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogJ0FDQ09VTlRfT1BUSU9OUycsXG4gICAgICB1c2VGYWN0b3J5OiBvcHRpb25zRmFjdG9yeSxcbiAgICAgIGRlcHM6IFtBQ0NPVU5UX09QVElPTlNdLFxuICAgIH0sXG4gIF07XG59XG4iXX0=

@ -1,29 +0,0 @@
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { NgModule } from '@angular/core';
import { ACCOUNT_OPTIONS, optionsFactory } from './tokens/options.token';
export class RootAccountModule {
/**
* @param {?=} options
* @return {?}
*/
static forRoot(options = (/** @type {?} */ ({}))) {
return {
ngModule: RootAccountModule,
providers: [
{ provide: ACCOUNT_OPTIONS, useValue: options },
{
provide: 'ACCOUNT_OPTIONS',
useFactory: optionsFactory,
deps: [ACCOUNT_OPTIONS],
},
],
};
}
}
RootAccountModule.decorators = [
{ type: NgModule, args: [{},] }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm9vdC1hY2NvdW50Lm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BhYnAvbmcuYWNjb3VudC8iLCJzb3VyY2VzIjpbImxpYi9yb290LWFjY291bnQubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQXVCLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU5RCxPQUFPLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR3pFLE1BQU0sT0FBTyxpQkFBaUI7Ozs7O0lBQzVCLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxHQUFHLG1CQUFBLEVBQUUsRUFBVztRQUNwQyxPQUFPO1lBQ0wsUUFBUSxFQUFFLGlCQUFpQjtZQUMzQixTQUFTLEVBQUU7Z0JBQ1QsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUU7Z0JBQy9DO29CQUNFLE9BQU8sRUFBRSxpQkFBaUI7b0JBQzFCLFVBQVUsRUFBRSxjQUFjO29CQUMxQixJQUFJLEVBQUUsQ0FBQyxlQUFlLENBQUM7aUJBQ3hCO2FBQ0Y7U0FDRixDQUFDO0lBQ0osQ0FBQzs7O1lBZEYsUUFBUSxTQUFDLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzLCBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT3B0aW9ucyB9IGZyb20gJy4vbW9kZWxzL29wdGlvbnMnO1xuaW1wb3J0IHsgQUNDT1VOVF9PUFRJT05TLCBvcHRpb25zRmFjdG9yeSB9IGZyb20gJy4vdG9rZW5zL29wdGlvbnMudG9rZW4nO1xuXG5ATmdNb2R1bGUoe30pXG5leHBvcnQgY2xhc3MgUm9vdEFjY291bnRNb2R1bGUge1xuICBzdGF0aWMgZm9yUm9vdChvcHRpb25zID0ge30gYXMgT3B0aW9ucyk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xuICAgIHJldHVybiB7XG4gICAgICBuZ01vZHVsZTogUm9vdEFjY291bnRNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgeyBwcm92aWRlOiBBQ0NPVU5UX09QVElPTlMsIHVzZVZhbHVlOiBvcHRpb25zIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwcm92aWRlOiAnQUNDT1VOVF9PUFRJT05TJyxcbiAgICAgICAgICB1c2VGYWN0b3J5OiBvcHRpb25zRmFjdG9yeSxcbiAgICAgICAgICBkZXBzOiBbQUNDT1VOVF9PUFRJT05TXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxufVxuIl19

@ -2,10 +2,9 @@
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { RootAccountModule } from './lib/root-account.module';
export { AccountModule } from './lib/account.module';
export { AccountProviders, AccountModule } from './lib/account.module';
export { LoginComponent, RegisterComponent } from './lib/components';
export { ACCOUNT_ROUTES } from './lib/constants/routes';
export { optionsFactory, ACCOUNT_OPTIONS } from './lib/tokens';
export {} from './lib/models';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BhYnAvbmcuYWNjb3VudC8iLCJzb3VyY2VzIjpbInB1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLGtDQUFjLDJCQUEyQixDQUFDO0FBQzFDLDhCQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGtEQUFjLGtCQUFrQixDQUFDO0FBQ2pDLCtCQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGdEQUFjLGNBQWMsQ0FBQztBQUM3QixlQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vbGliL3Jvb3QtYWNjb3VudC5tb2R1bGUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvYWNjb3VudC5tb2R1bGUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29tcG9uZW50cyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jb25zdGFudHMvcm91dGVzJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3Rva2Vucyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9tb2RlbHMnO1xuIl19
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BhYnAvbmcuYWNjb3VudC8iLCJzb3VyY2VzIjpbInB1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLGdEQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGtEQUFjLGtCQUFrQixDQUFDO0FBQ2pDLCtCQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGdEQUFjLGNBQWMsQ0FBQztBQUM3QixlQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vbGliL2FjY291bnQubW9kdWxlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NvbXBvbmVudHMnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY29uc3RhbnRzL3JvdXRlcyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi90b2tlbnMnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWxzJztcbiJdfQ==

@ -5,11 +5,11 @@
/**
* Generated bundle index. Do not edit.
*/
export { RootAccountModule, AccountModule, LoginComponent, RegisterComponent, ACCOUNT_ROUTES, optionsFactory, ACCOUNT_OPTIONS } from './public-api';
export { AccountRoutingModule as ɵh } from './lib/account-routing.module';
export { LoginComponent as ɵc } from './lib/components/login/login.component';
export { RegisterComponent as ɵe } from './lib/components/register/register.component';
export { TenantBoxComponent as ɵg } from './lib/components/tenant-box/tenant-box.component';
export { AccountService as ɵf } from './lib/services/account.service';
export { ACCOUNT_OPTIONS as ɵb, optionsFactory as ɵa } from './lib/tokens/options.token';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJwLW5nLmFjY291bnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AYWJwL25nLmFjY291bnQvIiwic291cmNlcyI6WyJhYnAtbmcuYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBSUEscUlBQWMsY0FBYyxDQUFDO0FBRTdCLE9BQU8sRUFBQyxvQkFBb0IsSUFBSSxFQUFFLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RSxPQUFPLEVBQUMsY0FBYyxJQUFJLEVBQUUsRUFBQyxNQUFNLHdDQUF3QyxDQUFDO0FBQzVFLE9BQU8sRUFBQyxpQkFBaUIsSUFBSSxFQUFFLEVBQUMsTUFBTSw4Q0FBOEMsQ0FBQztBQUNyRixPQUFPLEVBQUMsa0JBQWtCLElBQUksRUFBRSxFQUFDLE1BQU0sa0RBQWtELENBQUM7QUFFMUYsT0FBTyxFQUFDLGNBQWMsSUFBSSxFQUFFLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEVBQUMsZUFBZSxJQUFJLEVBQUUsRUFBQyxjQUFjLElBQUksRUFBRSxFQUFDLE1BQU0sNEJBQTRCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG5cbmV4cG9ydCB7QWNjb3VudFJvdXRpbmdNb2R1bGUgYXMgybVofSBmcm9tICcuL2xpYi9hY2NvdW50LXJvdXRpbmcubW9kdWxlJztcbmV4cG9ydCB7TG9naW5Db21wb25lbnQgYXMgybVjfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL2xvZ2luL2xvZ2luLmNvbXBvbmVudCc7XG5leHBvcnQge1JlZ2lzdGVyQ29tcG9uZW50IGFzIMm1ZX0gZnJvbSAnLi9saWIvY29tcG9uZW50cy9yZWdpc3Rlci9yZWdpc3Rlci5jb21wb25lbnQnO1xuZXhwb3J0IHtUZW5hbnRCb3hDb21wb25lbnQgYXMgybVnfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3RlbmFudC1ib3gvdGVuYW50LWJveC5jb21wb25lbnQnO1xuZXhwb3J0IHtPcHRpb25zIGFzIMm1ZH0gZnJvbSAnLi9saWIvbW9kZWxzL29wdGlvbnMnO1xuZXhwb3J0IHtBY2NvdW50U2VydmljZSBhcyDJtWZ9IGZyb20gJy4vbGliL3NlcnZpY2VzL2FjY291bnQuc2VydmljZSc7XG5leHBvcnQge0FDQ09VTlRfT1BUSU9OUyBhcyDJtWIsb3B0aW9uc0ZhY3RvcnkgYXMgybVhfSBmcm9tICcuL2xpYi90b2tlbnMvb3B0aW9ucy50b2tlbic7Il19
export { AccountProviders, AccountModule, LoginComponent, RegisterComponent, ACCOUNT_ROUTES, optionsFactory, ACCOUNT_OPTIONS } from './public-api';
export { AccountRoutingModule as ɵf } from './lib/account-routing.module';
export { LoginComponent as ɵa } from './lib/components/login/login.component';
export { RegisterComponent as ɵc } from './lib/components/register/register.component';
export { TenantBoxComponent as ɵe } from './lib/components/tenant-box/tenant-box.component';
export { AccountService as ɵd } from './lib/services/account.service';
export { ACCOUNT_OPTIONS as ɵh, optionsFactory as ɵg } from './lib/tokens/options.token';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJwLW5nLmFjY291bnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AYWJwL25nLmFjY291bnQvIiwic291cmNlcyI6WyJhYnAtbmcuYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBSUEsb0lBQWMsY0FBYyxDQUFDO0FBRTdCLE9BQU8sRUFBQyxvQkFBb0IsSUFBSSxFQUFFLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RSxPQUFPLEVBQUMsY0FBYyxJQUFJLEVBQUUsRUFBQyxNQUFNLHdDQUF3QyxDQUFDO0FBQzVFLE9BQU8sRUFBQyxpQkFBaUIsSUFBSSxFQUFFLEVBQUMsTUFBTSw4Q0FBOEMsQ0FBQztBQUNyRixPQUFPLEVBQUMsa0JBQWtCLElBQUksRUFBRSxFQUFDLE1BQU0sa0RBQWtELENBQUM7QUFFMUYsT0FBTyxFQUFDLGNBQWMsSUFBSSxFQUFFLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEVBQUMsZUFBZSxJQUFJLEVBQUUsRUFBQyxjQUFjLElBQUksRUFBRSxFQUFDLE1BQU0sNEJBQTRCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vcHVibGljLWFwaSc7XG5cbmV4cG9ydCB7QWNjb3VudFJvdXRpbmdNb2R1bGUgYXMgybVmfSBmcm9tICcuL2xpYi9hY2NvdW50LXJvdXRpbmcubW9kdWxlJztcbmV4cG9ydCB7TG9naW5Db21wb25lbnQgYXMgybVhfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL2xvZ2luL2xvZ2luLmNvbXBvbmVudCc7XG5leHBvcnQge1JlZ2lzdGVyQ29tcG9uZW50IGFzIMm1Y30gZnJvbSAnLi9saWIvY29tcG9uZW50cy9yZWdpc3Rlci9yZWdpc3Rlci5jb21wb25lbnQnO1xuZXhwb3J0IHtUZW5hbnRCb3hDb21wb25lbnQgYXMgybVlfSBmcm9tICcuL2xpYi9jb21wb25lbnRzL3RlbmFudC1ib3gvdGVuYW50LWJveC5jb21wb25lbnQnO1xuZXhwb3J0IHtPcHRpb25zIGFzIMm1Yn0gZnJvbSAnLi9saWIvbW9kZWxzL29wdGlvbnMnO1xuZXhwb3J0IHtBY2NvdW50U2VydmljZSBhcyDJtWR9IGZyb20gJy4vbGliL3NlcnZpY2VzL2FjY291bnQuc2VydmljZSc7XG5leHBvcnQge0FDQ09VTlRfT1BUSU9OUyBhcyDJtWgsb3B0aW9uc0ZhY3RvcnkgYXMgybVnfSBmcm9tICcuL2xpYi90b2tlbnMvb3B0aW9ucy50b2tlbic7Il19

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save