Browse Source

Merge branch 'dev' of https://github.com/volosoft/abp into dev

pull/1767/head
Alper Ebicoglu 7 years ago
parent
commit
d39c37d826
  1. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  2. 5
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
  3. 60
      docs/pt-BR/Contribution/Index.md
  4. 126
      docs/pt-BR/Getting-Started-Angular-Template.md
  5. 183
      docs/pt-BR/Getting-Started-AspNetCore-Application.md
  6. 102
      docs/pt-BR/Getting-Started-AspNetCore-MVC-Template.md
  7. 182
      docs/pt-BR/Getting-Started-Console-Application.md
  8. 31
      docs/pt-BR/Index.md
  9. 462
      docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-I.md
  10. 466
      docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-II.md
  11. 182
      docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-III.md
  12. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog-v2.png
  13. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-edit-dialog.png
  14. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page-v2.png
  15. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-appservice-tests.png
  16. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list-2.png
  17. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list.png
  18. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table-actions.png
  19. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table.png
  20. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog-2.png
  21. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog.png
  22. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-template.png
  23. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-homepage.png
  24. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file-v2.png
  25. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files-v2.png
  26. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-menu-items.png
  27. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-new-book-button.png
  28. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png
  29. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration.png
  30. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-swagger.png
  31. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist-network.png
  32. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist.png
  33. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects-v2.png
  34. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-user-management.png
  35. BIN
      docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v3.png
  36. BIN
      docs/pt-BR/images/MonthlyProfitWidgetFiles.png
  37. BIN
      docs/pt-BR/images/bookstore-apis.png
  38. BIN
      docs/pt-BR/images/bookstore-create-template.png
  39. BIN
      docs/pt-BR/images/bookstore-homepage.png
  40. BIN
      docs/pt-BR/images/bookstore-swagger-ui-host.png
  41. BIN
      docs/pt-BR/images/bookstore-user-management-v2.png
  42. BIN
      docs/pt-BR/images/bookstore-visual-studio-solution-for-spa.png
  43. BIN
      docs/pt-BR/images/bookstore-visual-studio-solution-tiered.png
  44. BIN
      docs/pt-BR/images/bookstore-visual-studio-solution-v3.png
  45. BIN
      docs/pt-BR/images/build-action-embedded-resource-sample.png
  46. BIN
      docs/pt-BR/images/create-new-aspnet-core-application.png
  47. BIN
      docs/pt-BR/images/create-new-net-core-console-application.png
  48. BIN
      docs/pt-BR/images/dashboard1.png
  49. BIN
      docs/pt-BR/images/db-migrator-app.png
  50. BIN
      docs/pt-BR/images/docs-create-project.jpg
  51. BIN
      docs/pt-BR/images/docs-module_download-new-abp-project.png
  52. BIN
      docs/pt-BR/images/docs-module_download-sample-navigation-menu.png
  53. BIN
      docs/pt-BR/images/docs-module_solution-explorer.png
  54. BIN
      docs/pt-BR/images/github-access-token-private-repo.jpg
  55. BIN
      docs/pt-BR/images/github-access-token-public-repo.jpg
  56. BIN
      docs/pt-BR/images/github-myusername.jpg
  57. BIN
      docs/pt-BR/images/issuemanagement-module-solution.png
  58. BIN
      docs/pt-BR/images/layered-project-dependencies-module.png
  59. BIN
      docs/pt-BR/images/layered-project-dependencies.png
  60. BIN
      docs/pt-BR/images/localization-resource-json-files.png
  61. BIN
      docs/pt-BR/images/microservice-sample-authserver-home.png
  62. BIN
      docs/pt-BR/images/microservice-sample-authserver-login.png
  63. BIN
      docs/pt-BR/images/microservice-sample-backend-ui-permissions.png
  64. BIN
      docs/pt-BR/images/microservice-sample-backend-ui.png
  65. BIN
      docs/pt-BR/images/microservice-sample-blogservice-permission-in-database.png
  66. BIN
      docs/pt-BR/images/microservice-sample-diagram-2.png
  67. BIN
      docs/pt-BR/images/microservice-sample-diagram.png
  68. BIN
      docs/pt-BR/images/microservice-sample-kibana-1.png
  69. BIN
      docs/pt-BR/images/microservice-sample-kibana-2.png
  70. BIN
      docs/pt-BR/images/microservice-sample-product-module-in-solution.png
  71. BIN
      docs/pt-BR/images/microservice-sample-public-product-list.png
  72. BIN
      docs/pt-BR/images/microservice-sample-solution.png
  73. BIN
      docs/pt-BR/images/microservice-sample-update-database-authserver.png
  74. BIN
      docs/pt-BR/images/microservice-sample-update-database-products.png
  75. BIN
      docs/pt-BR/images/module-layers-and-packages.jpg
  76. BIN
      docs/pt-BR/images/night-build-add-nuget-package.png
  77. BIN
      docs/pt-BR/images/night-build-add-nuget-source.png
  78. BIN
      docs/pt-BR/images/pcm-update-database-v2.png
  79. BIN
      docs/pt-BR/images/pcm-update-database.png
  80. BIN
      docs/pt-BR/images/select-empty-web-application.png
  81. BIN
      docs/pt-BR/images/set-as-startup-project.png
  82. BIN
      docs/pt-BR/images/tiered-solution-applications.png
  83. BIN
      docs/pt-BR/images/tiered-solution-servers.png
  84. BIN
      docs/pt-BR/images/volodocs-iis-add-website.png
  85. BIN
      docs/pt-BR/images/volodocs-iis-application-pool.png
  86. BIN
      docs/pt-BR/images/widget-basic-files.png
  87. 15
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Luxon/LuxonScriptContributor.cs
  88. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs
  89. 20
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs
  90. 14
      npm/ng-packs/dist/account/abp-ng.account.d.ts
  91. 2
      npm/ng-packs/dist/account/abp-ng.account.metadata.json
  92. 102
      npm/ng-packs/dist/account/bundles/abp-ng.account.umd.js
  93. 2
      npm/ng-packs/dist/account/bundles/abp-ng.account.umd.js.map
  94. 2
      npm/ng-packs/dist/account/bundles/abp-ng.account.umd.min.js
  95. 2
      npm/ng-packs/dist/account/bundles/abp-ng.account.umd.min.js.map
  96. 16
      npm/ng-packs/dist/account/esm2015/abp-ng.account.js
  97. 17
      npm/ng-packs/dist/account/esm2015/lib/account.module.js
  98. 29
      npm/ng-packs/dist/account/esm2015/lib/root-account.module.js
  99. 5
      npm/ng-packs/dist/account/esm2015/public-api.js
  100. 16
      npm/ng-packs/dist/account/esm5/abp-ng.account.js

3
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json

@ -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"
}
}

5
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json

@ -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ı"
}
}

60
docs/pt-BR/Contribution/Index.md

@ -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) .

126
docs/pt-BR/Getting-Started-Angular-Template.md

@ -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)

183
docs/pt-BR/Getting-Started-AspNetCore-Application.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) .

102
docs/pt-BR/Getting-Started-AspNetCore-MVC-Template.md

@ -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)

182
docs/pt-BR/Getting-Started-Console-Application.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) .

31
docs/pt-BR/Index.md

@ -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.

462
docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-I.md

@ -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.

466
docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-II.md

@ -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.

182
docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-III.md

@ -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!

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-edit-dialog.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-appservice-tests.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table-actions.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-template.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-homepage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-menu-items.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-new-book-button.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-swagger.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist-network.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-user-management.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/pt-BR/images/MonthlyProfitWidgetFiles.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
docs/pt-BR/images/bookstore-apis.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/pt-BR/images/bookstore-create-template.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
docs/pt-BR/images/bookstore-homepage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/pt-BR/images/bookstore-swagger-ui-host.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
docs/pt-BR/images/bookstore-user-management-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/pt-BR/images/bookstore-visual-studio-solution-for-spa.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
docs/pt-BR/images/bookstore-visual-studio-solution-tiered.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/pt-BR/images/bookstore-visual-studio-solution-v3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/pt-BR/images/build-action-embedded-resource-sample.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
docs/pt-BR/images/create-new-aspnet-core-application.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
docs/pt-BR/images/create-new-net-core-console-application.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
docs/pt-BR/images/dashboard1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
docs/pt-BR/images/db-migrator-app.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/pt-BR/images/docs-create-project.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
docs/pt-BR/images/docs-module_download-new-abp-project.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/pt-BR/images/docs-module_download-sample-navigation-menu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/pt-BR/images/docs-module_solution-explorer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/pt-BR/images/github-access-token-private-repo.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
docs/pt-BR/images/github-access-token-public-repo.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
docs/pt-BR/images/github-myusername.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

BIN
docs/pt-BR/images/issuemanagement-module-solution.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
docs/pt-BR/images/layered-project-dependencies-module.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
docs/pt-BR/images/layered-project-dependencies.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
docs/pt-BR/images/localization-resource-json-files.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
docs/pt-BR/images/microservice-sample-authserver-home.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/pt-BR/images/microservice-sample-authserver-login.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/pt-BR/images/microservice-sample-backend-ui-permissions.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
docs/pt-BR/images/microservice-sample-backend-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
docs/pt-BR/images/microservice-sample-blogservice-permission-in-database.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
docs/pt-BR/images/microservice-sample-diagram-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
docs/pt-BR/images/microservice-sample-diagram.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
docs/pt-BR/images/microservice-sample-kibana-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
docs/pt-BR/images/microservice-sample-kibana-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
docs/pt-BR/images/microservice-sample-product-module-in-solution.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/pt-BR/images/microservice-sample-public-product-list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/pt-BR/images/microservice-sample-solution.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/pt-BR/images/microservice-sample-update-database-authserver.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
docs/pt-BR/images/microservice-sample-update-database-products.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
docs/pt-BR/images/module-layers-and-packages.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
docs/pt-BR/images/night-build-add-nuget-package.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/pt-BR/images/night-build-add-nuget-source.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
docs/pt-BR/images/pcm-update-database-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
docs/pt-BR/images/pcm-update-database.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
docs/pt-BR/images/select-empty-web-application.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
docs/pt-BR/images/set-as-startup-project.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
docs/pt-BR/images/tiered-solution-applications.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/pt-BR/images/tiered-solution-servers.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
docs/pt-BR/images/volodocs-iis-add-website.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/pt-BR/images/volodocs-iis-application-pool.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
docs/pt-BR/images/widget-basic-files.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

15
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Luxon/LuxonScriptContributor.cs

@ -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");
}
}
}

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs

@ -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

20
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs

@ -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
)
);

14
npm/ng-packs/dist/account/abp-ng.account.d.ts

@ -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';

2
npm/ng-packs/dist/account/abp-ng.account.metadata.json

File diff suppressed because one or more lines are too long

102
npm/ng-packs/dist/account/bundles/abp-ng.account.umd.js

@ -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 });

2
npm/ng-packs/dist/account/bundles/abp-ng.account.umd.js.map

File diff suppressed because one or more lines are too long

2
npm/ng-packs/dist/account/bundles/abp-ng.account.umd.min.js

File diff suppressed because one or more lines are too long

2
npm/ng-packs/dist/account/bundles/abp-ng.account.umd.min.js.map

File diff suppressed because one or more lines are too long

16
npm/ng-packs/dist/account/esm2015/abp-ng.account.js

@ -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

17
npm/ng-packs/dist/account/esm2015/lib/account.module.js

@ -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=

29
npm/ng-packs/dist/account/esm2015/lib/root-account.module.js

@ -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

5
npm/ng-packs/dist/account/esm2015/public-api.js

@ -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==

16
npm/ng-packs/dist/account/esm5/abp-ng.account.js

@ -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 changed in this diff

Loading…
Cancel
Save