From d0724adeda718ad2b6433e0dad317b0be8808bea Mon Sep 17 00:00:00 2001 From: Xeevis Date: Mon, 22 Jul 2019 14:33:16 +0200 Subject: [PATCH 1/8] Update docs-nav.json --- docs/cs/docs-nav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/cs/docs-nav.json b/docs/cs/docs-nav.json index 6f41d127e8..2d6b8f7ef8 100644 --- a/docs/cs/docs-nav.json +++ b/docs/cs/docs-nav.json @@ -220,6 +220,10 @@ "text": "Tag pomocníci", "path": "AspNetCore/Tag-Helpers/Index.md" }, + { + "text": "Widgety", + "path": "AspNetCore/Widgets.md" + }, { "text": "Motivy", "path": "AspNetCore/Theming.md" From a6a4038b4f253d70346c5b7d157af0d4ddc487a4 Mon Sep 17 00:00:00 2001 From: Xeevis Date: Mon, 22 Jul 2019 14:35:41 +0200 Subject: [PATCH 2/8] Copy Widgets.md for translation --- docs/cs/AspNetCore/Widgets.md | 274 ++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 docs/cs/AspNetCore/Widgets.md diff --git a/docs/cs/AspNetCore/Widgets.md b/docs/cs/AspNetCore/Widgets.md new file mode 100644 index 0000000000..2cd62ba1d7 --- /dev/null +++ b/docs/cs/AspNetCore/Widgets.md @@ -0,0 +1,274 @@ +# Widgets + +ABP provides a model and infrastructure to create **reusable widgets**. Widget system is an extension to [ASP.NET Core's ViewComponents](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components). Widgets are especially useful when you want to; + +* Define widgets in reusable **[modules](../Module-Development-Basics.md)**. +* Have **scripts & styles** dependencies for your widget. +* Create **[dashboards](Dashboards.md)** with widgets used inside. +* Co-operate widgets with **[authorization](../Authorization.md)** and **[bundling](Bundling-Minification.md)** systems. + +## Basic Widget Definition + +### Create a View Component + +As the first step, create a new regular ASP.NET Core View Component: + +![widget-basic-files](../images/widget-basic-files.png) + +**MySimpleWidgetViewComponent.cs**: + +````csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +Inheriting from `AbpViewComponent` is not required. You could inherit from ASP.NET Core's standard `ViewComponent`. `AbpViewComponent` only defines some base useful properties. + +**Default.cshtml**: + +```xml +
+

My Simple Widget

+

This is a simple widget!

+
+``` + +### Define the Widget + +Add a `Widget` attribute to the `MySimpleWidgetViewComponent` class to mark this view component as a widget: + +````csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +## Rendering a Widget + +Rendering a widget is pretty standard. Use the `Component.InvokeAsync` method in a razor view/page as you do for any view component. Examples: + +````xml +@await Component.InvokeAsync("MySimpleWidget") +@await Component.InvokeAsync(typeof(MySimpleWidgetViewComponent)) +```` + +First approach uses the widget name while second approach uses the view component type. + +## Widget Name + +Default name of the view components are calculated based on the name of the view component type. If your view component type is `MySimpleWidgetViewComponent` then the widget name will be `MySimpleWidget` (removes `ViewComponent` postfix). This is how ASP.NET Core calculates a view component's name. + +To customize widget's name, just use the standard `ViewComponent` attribute of ASP.NET Core: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget] + [ViewComponent(Name = "MyCustomNamedWidget")] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View("~/Pages/Components/MySimpleWidget/Default.cshtml"); + } + } +} +``` + +ABP will respect to the custom name by handling the widget. + +> If the view component name and the folder name of the view component don't match, you may need to manually write the view path as done in this example. + +### Display Name + +You can also define a human-readable, localizable display name for the widget. This display name then can be used on the UI when needed. Display name is optional and can be defined using properties of the `Widget` attribute: + +````csharp +using DashboardDemo.Localization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget( + DisplayName = "MySimpleWidgetDisplayName", //Localization key + DisplayNameResource = typeof(DashboardDemoResource) //localization resource + )] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +See [the localization document](../Localization.md) to learn about localization resources and keys. + +## Style & Script Dependencies + +There are some challenges when your widget has script and style files; + +* Any page uses the widget should also include the **its script & styles** files into the page. +* The page should also care about **depended libraries/files** of the widget. + +ABP solves these issues when you properly relate the resources with the widget. You don't care about dependencies of the widget while using it. + +### Defining as Simple File Paths + +The example widget below adds a style and a script file: + +````csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget( + StyleFiles = new[] { "/Pages/Components/MySimpleWidget/Default.css" }, + ScriptFiles = new[] { "/Pages/Components/MySimpleWidget/Default.js" } + )] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +ABP takes account these dependencies and properly adds to the view/page when you use the widget. Style/script files can be **physical or virtual**. It is completely integrated to the [Virtual File System](../Virtual-File-System.md). + +### Defining Bundle Contributors + +All resources for used widgets in a page are added as a **bundle** (bundled & minified in production if you don't configure otherwise). In addition to adding a simple file, you can take full power of the bundle contributors. + +The sample code below does the same with the code above, but defines and uses bundle contributors: + +````csharp +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget( + StyleTypes = new []{ typeof(MySimpleWidgetStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(MySimpleWidgetScriptBundleContributor) } + )] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } + + public class MySimpleWidgetStyleBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files + .AddIfNotContains("/Pages/Components/MySimpleWidget/Default.css"); + } + } + + public class MySimpleWidgetScriptBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files + .AddIfNotContains("/Pages/Components/MySimpleWidget/Default.js"); + } + } +} + +```` + +Bundle contribution system is very powerful. If your widget uses a JavaScript library to render a chart, then you can declare it as a dependency, so the JavaScript library is automatically added to the page if it wasn't added before. In this way, the page using your widget doesn't care about the dependencies. + +See the [bundling & minification](Bundling-Minification.md) documentation for more information about that system. + +## Authorization + +Some widgets may need to be available only for authenticated or authorized users. In this case, use the following properties of the `Widget` attribute: + +* `RequiresAuthentication` (`bool`): Set to true to make this widget usable only for authentication users (user have logged in to the application). +* `RequiredPolicies` (`List`): A list of policy names to authorize the user. See [the authorization document](../Authorization.md) for more info about policies. + +Example: + +````csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget(RequiredPolicies = new[] { "MyPolicyName" })] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +## Widget Options + +As alternative to the `Widget` attribute, you can use the `WidgetOptions` to configure widgets: + +```csharp +Configure(options => +{ + options.Widgets.Add(); +}); +``` + +Write this into the `ConfigureServices` method of your [module](../Module-Development-Basics.md). All the configuration done with the `Widhet` attribute is also possible with the `WidgetOptions`. Example configuration that adds a style for the widget: + +````csharp +Configure(options => +{ + options.Widgets + .Add() + .WithStyles("/Pages/Components/MySimpleWidget/Default.css"); +}); +```` + +> Tip: `WidgetOptions` can also be used to get an existing widget and change its configuration. This is especially useful if you want to modify the configuration of a widget inside a module used by your application. Use `options.Widgets.Find` to get an existing `WidgetDefinition`. \ No newline at end of file From fef251da0e669ab735db4837537ea606f95cf285 Mon Sep 17 00:00:00 2001 From: Xeevis Date: Mon, 22 Jul 2019 20:33:58 +0200 Subject: [PATCH 3/8] Translate Widgets.md --- docs/cs/AspNetCore/Widgets.md | 94 +++++++++++++++++------------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/docs/cs/AspNetCore/Widgets.md b/docs/cs/AspNetCore/Widgets.md index 2cd62ba1d7..9dfcddfa6d 100644 --- a/docs/cs/AspNetCore/Widgets.md +++ b/docs/cs/AspNetCore/Widgets.md @@ -1,17 +1,17 @@ -# Widgets +# Widgety -ABP provides a model and infrastructure to create **reusable widgets**. Widget system is an extension to [ASP.NET Core's ViewComponents](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components). Widgets are especially useful when you want to; +ABP poskytuje model a infastrukturu k vytváření **znovu použitelných widgetů**. Systém widgetů je rozšíření pro [ASP.NET Core pohledové komponenty](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components). Widgety jsou zvláště užitečné, když chcete; -* Define widgets in reusable **[modules](../Module-Development-Basics.md)**. -* Have **scripts & styles** dependencies for your widget. -* Create **[dashboards](Dashboards.md)** with widgets used inside. -* Co-operate widgets with **[authorization](../Authorization.md)** and **[bundling](Bundling-Minification.md)** systems. +* Definovat widgety v znovu použitelných **[modulech](../Module-Development-Basics.md)**. +* Mít závislosti na **skriptech & stylech** ve vašem widgetu. +* Vytvářet **[řídící panely](Dashboards.md)** za použítí widgetů. +* Spolupráci widgetů s **[authorizačními](../Authorization.md)** a **[svazovacími](Bundling-Minification.md)** systémy. -## Basic Widget Definition +## Základní definice widgetu -### Create a View Component +### Tvorba pohledové komponenty -As the first step, create a new regular ASP.NET Core View Component: +Jako první krok, vytvoříme běžnou ASP.NET Core pohledovou komponentu: ![widget-basic-files](../images/widget-basic-files.png) @@ -33,7 +33,7 @@ namespace DashboardDemo.Web.Pages.Components.MySimpleWidget } ```` -Inheriting from `AbpViewComponent` is not required. You could inherit from ASP.NET Core's standard `ViewComponent`. `AbpViewComponent` only defines some base useful properties. +Dědění z `AbpViewComponent` není vyžadováno. Můžeme dědit ze standardního ASP.NET Core `ViewComponent`. `AbpViewComponent` pouze definuje pár základních a užitečných vlastnosti. **Default.cshtml**: @@ -44,9 +44,9 @@ Inheriting from `AbpViewComponent` is not required. You could inherit from ASP.N ``` -### Define the Widget +### Definice widgetu -Add a `Widget` attribute to the `MySimpleWidgetViewComponent` class to mark this view component as a widget: +Přidáme atribut `Widget` k třídě `MySimpleWidgetViewComponent` pro označení této pohledové komponenty jako widgetu: ````csharp using Microsoft.AspNetCore.Mvc; @@ -66,22 +66,22 @@ namespace DashboardDemo.Web.Pages.Components.MySimpleWidget } ```` -## Rendering a Widget +## Vykreslení widgetu -Rendering a widget is pretty standard. Use the `Component.InvokeAsync` method in a razor view/page as you do for any view component. Examples: +Vykreslení widgetu je vcelku standardní. Použijeme metodu `Component.InvokeAsync` v razor pohledu/stránce jako s kteroukoliv jinou pohledovou komponentou. Příklady: ````xml @await Component.InvokeAsync("MySimpleWidget") @await Component.InvokeAsync(typeof(MySimpleWidgetViewComponent)) ```` -First approach uses the widget name while second approach uses the view component type. +První přístup používá název widgetu, zatímco druhý používá typ pohledové komponenty. -## Widget Name +## Název widgetu -Default name of the view components are calculated based on the name of the view component type. If your view component type is `MySimpleWidgetViewComponent` then the widget name will be `MySimpleWidget` (removes `ViewComponent` postfix). This is how ASP.NET Core calculates a view component's name. +Výchozí název pohledových komponent je vypočítán na základě názvu typu pohledové komponenty. Pokud je typ pohledové komponenty `MySimpleWidgetViewComponent` potom název widgetu bude `MySimpleWidget` (odstraní se `ViewComponent` postfix). Takto ASP.NET Core vypočítává název pohledové komponenty. -To customize widget's name, just use the standard `ViewComponent` attribute of ASP.NET Core: +Chceme-li přizpůsobit název widgetu, stačí použít standardní atribut `ViewComponent` z ASP.NET Core: ```csharp using Microsoft.AspNetCore.Mvc; @@ -102,13 +102,13 @@ namespace DashboardDemo.Web.Pages.Components.MySimpleWidget } ``` -ABP will respect to the custom name by handling the widget. +ABP bude respektovat přizpůsobený název při zpracování widgetu. -> If the view component name and the folder name of the view component don't match, you may need to manually write the view path as done in this example. +> Pokud jsou názvy pohledové komponenty a složky, která pohledovou komponentu obsahuje rozdílné, pravděpodobně budete muset ručně uvést cestu pohledu tak jako je to provedeno v tomto příkladu. -### Display Name +### Zobrazovaný název -You can also define a human-readable, localizable display name for the widget. This display name then can be used on the UI when needed. Display name is optional and can be defined using properties of the `Widget` attribute: +Můžeme také definovat čitelný & lokalizovatelný zobrazovaný název pro widget. Tento zobrazovaný název může být využít na uživatelském rozhraní kdykoliv je to potřeba. Zobrazovaný název je nepovinný a lze ho definovat pomocí vlastností atributu `Widget`: ````csharp using DashboardDemo.Localization; @@ -119,8 +119,8 @@ using Volo.Abp.AspNetCore.Mvc.UI.Widgets; namespace DashboardDemo.Web.Pages.Components.MySimpleWidget { [Widget( - DisplayName = "MySimpleWidgetDisplayName", //Localization key - DisplayNameResource = typeof(DashboardDemoResource) //localization resource + DisplayName = "MySimpleWidgetDisplayName", // Lokalizační klíč + DisplayNameResource = typeof(DashboardDemoResource) // Lokalizační zdroj )] public class MySimpleWidgetViewComponent : AbpViewComponent { @@ -132,20 +132,20 @@ namespace DashboardDemo.Web.Pages.Components.MySimpleWidget } ```` -See [the localization document](../Localization.md) to learn about localization resources and keys. +Podívejte se na [dokument lokalizace](../Localization.md) pro více informací o lokalizačních zdrojích a klíčích. -## Style & Script Dependencies +## Závislosti na stylech & skriptech -There are some challenges when your widget has script and style files; +Problémy když má widget soubory skriptů a stylů; -* Any page uses the widget should also include the **its script & styles** files into the page. -* The page should also care about **depended libraries/files** of the widget. +* Každý stránka, která používá widget musí také přidat soubory **skriptů & stylů** tohoto widgetu. +* Stránka se také musí postarat o **závislé knihovny/soubory** widgetu. -ABP solves these issues when you properly relate the resources with the widget. You don't care about dependencies of the widget while using it. +ABP tyto problémy řeší, když správně propojíme zdroje s widgetem. O závislosti widgetu se při jeho používání nestaráme. -### Defining as Simple File Paths +### Definování jednoduchých cest souborů -The example widget below adds a style and a script file: +Níže uvedený příklad widgetu přidá stylové a skriptové soubory: ````csharp using Microsoft.AspNetCore.Mvc; @@ -168,13 +168,13 @@ namespace DashboardDemo.Web.Pages.Components.MySimpleWidget } ```` -ABP takes account these dependencies and properly adds to the view/page when you use the widget. Style/script files can be **physical or virtual**. It is completely integrated to the [Virtual File System](../Virtual-File-System.md). +ABP bere v úvahu tyto závislosti a správně je přidává do pohledu/stránky při použití widgetu. Stylové/skriptové soubory mohou být **fyzické nebo virtuální**. Plně integrováno do [virtuálního systému souborů](../Virtual-File-System.md). -### Defining Bundle Contributors +### Definování přispěvatelů balíku -All resources for used widgets in a page are added as a **bundle** (bundled & minified in production if you don't configure otherwise). In addition to adding a simple file, you can take full power of the bundle contributors. +Všechny zdroje použité ve widgetech na stránce jsou přidány jako **svazek** (svázány & minifikovány v produkci pokud nenastavíte jinak). Kromě přidání jednoduchého souboru můžete využít plnou funkčnost přispěvatelů balíčků. -The sample code below does the same with the code above, but defines and uses bundle contributors: +Níže uvedený ukázkový kód provádí totéž co výše uvedený kód, ale definuje a používá přispěvatele balíků: ````csharp using System.Collections.Generic; @@ -218,18 +218,18 @@ namespace DashboardDemo.Web.Pages.Components.MySimpleWidget ```` -Bundle contribution system is very powerful. If your widget uses a JavaScript library to render a chart, then you can declare it as a dependency, so the JavaScript library is automatically added to the page if it wasn't added before. In this way, the page using your widget doesn't care about the dependencies. +Systém přispěvatelů balíků je velmi schopný. Pokud váš widget používá k vykreslení grafu JavaScript knihovnu, můžete ji deklarovat jako závislost, díky tomu se knihovna pokud nebyla dříve přidána automaticky přidá na stránku Tímto způsobem se stránka využívající váš widget nestará o závislosti. -See the [bundling & minification](Bundling-Minification.md) documentation for more information about that system. +Podívejte se na dokumentaci [svazování & minifikace](Bundling-Minification.md) pro více informací o tomto systému. -## Authorization +## Autorizace -Some widgets may need to be available only for authenticated or authorized users. In this case, use the following properties of the `Widget` attribute: +Některé widgety budou pravděpodobně muset být dostupné pouze pro ověřené nebo autorizované uživatele. V tomto případě použijte následující vlastnosti atributu `Widget`: -* `RequiresAuthentication` (`bool`): Set to true to make this widget usable only for authentication users (user have logged in to the application). -* `RequiredPolicies` (`List`): A list of policy names to authorize the user. See [the authorization document](../Authorization.md) for more info about policies. +* `RequiresAuthentication` (`bool`): Nastavte na true, aby byl tento widget použitelný pouze pro ověřené uživatele (uživatel je přihlášen do aplikace). +* `RequiredPolicies` (`List`): Seznam názvů zásad k autorizaci uživatele. Další informace o zásadách naleznete v [dokumentu autorizace](../Authorization.md). -Example: +Příklad: ````csharp using Microsoft.AspNetCore.Mvc; @@ -249,9 +249,9 @@ namespace DashboardDemo.Web.Pages.Components.MySimpleWidget } ```` -## Widget Options +## Možnosti widgetu -As alternative to the `Widget` attribute, you can use the `WidgetOptions` to configure widgets: +Jako alternativu k atributu `Widget` můžete ke konfiguraci widgetů použít `WidgetOptions`: ```csharp Configure(options => @@ -260,7 +260,7 @@ Configure(options => }); ``` -Write this into the `ConfigureServices` method of your [module](../Module-Development-Basics.md). All the configuration done with the `Widhet` attribute is also possible with the `WidgetOptions`. Example configuration that adds a style for the widget: +Toto vepište do metody `ConfigureServices` vašeho [modulu](../Module-Development-Basics.md). Veškerá konfigurace udělaná přes atribut `Widget` je dostupná i za pomoci `WidgetOptions`. Příklad konfigurace, která přidává styl pro widget: ````csharp Configure(options => @@ -271,4 +271,4 @@ Configure(options => }); ```` -> Tip: `WidgetOptions` can also be used to get an existing widget and change its configuration. This is especially useful if you want to modify the configuration of a widget inside a module used by your application. Use `options.Widgets.Find` to get an existing `WidgetDefinition`. \ No newline at end of file +> Tip: `WidgetOptions` lze také použít k získání existujícího widgetu a ke změně jeho konfigurace. To je obzvláště užitečné, pokud chcete změnit konfiguraci widgetu uvnitř modulu používaného vaší aplikací. Použíjte `options.Widgets.Find` k získání existujícího `WidgetDefinition`. \ No newline at end of file From d02cd971b6d434387a1aa06320cd246ea411450e Mon Sep 17 00:00:00 2001 From: Xeevis Date: Mon, 22 Jul 2019 20:35:28 +0200 Subject: [PATCH 4/8] Fix typo --- docs/en/AspNetCore/Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/AspNetCore/Widgets.md b/docs/en/AspNetCore/Widgets.md index 2cd62ba1d7..00f0433e2e 100644 --- a/docs/en/AspNetCore/Widgets.md +++ b/docs/en/AspNetCore/Widgets.md @@ -260,7 +260,7 @@ Configure(options => }); ``` -Write this into the `ConfigureServices` method of your [module](../Module-Development-Basics.md). All the configuration done with the `Widhet` attribute is also possible with the `WidgetOptions`. Example configuration that adds a style for the widget: +Write this into the `ConfigureServices` method of your [module](../Module-Development-Basics.md). All the configuration done with the `Widget` attribute is also possible with the `WidgetOptions`. Example configuration that adds a style for the widget: ````csharp Configure(options => From 7678681d2ca726494f44eb9f07346ad27890eac6 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 23 Jul 2019 10:08:46 +0300 Subject: [PATCH 5/8] removed unused code --- .../AspNetCore/Mvc/UI/Dashboards/GlobalFilterDefinition.cs | 3 --- .../Abp/AspNetCore/Mvc/UI/Dashboards/IDashboardRenderer.cs | 5 +---- .../Mvc/UI/Widgets/AbpAspNetCoreMvcUiWidgetsModule.cs | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Dashboards/Volo/Abp/AspNetCore/Mvc/UI/Dashboards/GlobalFilterDefinition.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Dashboards/Volo/Abp/AspNetCore/Mvc/UI/Dashboards/GlobalFilterDefinition.cs index d7e52a604e..f599f0c797 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Dashboards/Volo/Abp/AspNetCore/Mvc/UI/Dashboards/GlobalFilterDefinition.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Dashboards/Volo/Abp/AspNetCore/Mvc/UI/Dashboards/GlobalFilterDefinition.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using JetBrains.Annotations; using Volo.Abp.Localization; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Dashboards/Volo/Abp/AspNetCore/Mvc/UI/Dashboards/IDashboardRenderer.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Dashboards/Volo/Abp/AspNetCore/Mvc/UI/Dashboards/IDashboardRenderer.cs index 64e149696f..7cfed80135 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Dashboards/Volo/Abp/AspNetCore/Mvc/UI/Dashboards/IDashboardRenderer.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Dashboards/Volo/Abp/AspNetCore/Mvc/UI/Dashboards/IDashboardRenderer.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Mvc; using Volo.Abp.DependencyInjection; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/AbpAspNetCoreMvcUiWidgetsModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/AbpAspNetCoreMvcUiWidgetsModule.cs index 1644fe342c..955bb868a8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/AbpAspNetCoreMvcUiWidgetsModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/AbpAspNetCoreMvcUiWidgetsModule.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ViewComponents; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; From 3a2c3097898c1cf303cae1077510a2b3f0d1b2dd Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 23 Jul 2019 10:56:23 +0300 Subject: [PATCH 6/8] Update Default.cshtml --- .../Pages/Components/NewUserStatisticWidget/Default.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/DashboardDemo/src/DashboardDemo.Web/Pages/Components/NewUserStatisticWidget/Default.cshtml b/samples/DashboardDemo/src/DashboardDemo.Web/Pages/Components/NewUserStatisticWidget/Default.cshtml index 82bcb11f02..6a2af5bb5d 100644 --- a/samples/DashboardDemo/src/DashboardDemo.Web/Pages/Components/NewUserStatisticWidget/Default.cshtml +++ b/samples/DashboardDemo/src/DashboardDemo.Web/Pages/Components/NewUserStatisticWidget/Default.cshtml @@ -11,7 +11,7 @@ -
From 839ffbef33599ef807ea9f6c4cab31df3e7cab7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=A3=AB=E4=BC=9F?= Date: Tue, 23 Jul 2019 21:08:29 +0800 Subject: [PATCH 7/8] Translate widget document --- docs/zh-Hans/AspNetCore/Widgets.md | 274 +++++++++++++++++++++ docs/zh-Hans/images/widget-basic-files.png | Bin 0 -> 10185 bytes 2 files changed, 274 insertions(+) create mode 100644 docs/zh-Hans/AspNetCore/Widgets.md create mode 100644 docs/zh-Hans/images/widget-basic-files.png diff --git a/docs/zh-Hans/AspNetCore/Widgets.md b/docs/zh-Hans/AspNetCore/Widgets.md new file mode 100644 index 0000000000..a10e7e462f --- /dev/null +++ b/docs/zh-Hans/AspNetCore/Widgets.md @@ -0,0 +1,274 @@ +# 小部件 + +ABP为创建**可重用的部件**提供了模型和基础设施. 部件系统是[ASP.NET Core ViewComponents](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components)的扩展. 在你有以下需求时,小部件会非常有用; + +* 在可复用的 **[模块](../Module-Development-Basics.md)** 中定义部件. +* 在部件中引用 **scripts & styles** 脚本. +* 使用部件创建 **[仪表盘](Dashboards.md)**. +* 支持 **[授权](../Authorization.md)** 与 **[捆绑`bundling`](Bundling-Minification.md)** 的部件 + +## 基本部件定义 + +### 创建一个视图组件 + +第一部,创建一个新的ASP.NET Core View Component: + +![widget-basic-files](../images/widget-basic-files.png) + +**MySimpleWidgetViewComponent.cs**: + +````csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +继承 `AbpViewComponent` 不是必需的. 你也可以继承ASP.NET Core的 `ViewComponent`. `AbpViewComponent` 只是定义了一些基本的实用属性. + +**Default.cshtml**: + +```xml +
+

My Simple Widget

+

This is a simple widget!

+
+``` + +### 定义部件 + +添加 `Widget` attribute 到 `MySimpleWidgetViewComponent` 类,将此视图组件标记为部件: + +````csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +## 渲染部件 + +渲染部件的用法是ASP.NET Core的标准用法. 在razor view/page中使用 `Component.InvokeAsync` 方法, 就像渲染一个View Component一样. 例如: + +````xml +@await Component.InvokeAsync("MySimpleWidget") +@await Component.InvokeAsync(typeof(MySimpleWidgetViewComponent)) +```` + +第一行代码使用名称渲染了部件,第二行代码使用type渲染了View Comonent. + +## 部件名称 + +默认下名称是根据View Conponent组件的名称计算的, 比如你的视图组件名是 `MySimpleWidgetViewComponent`, 那么部件的名称就是 `MySimpleWidget` (删除`ViewComponent`后缀). 这与ASP.NET Core的默认视图组件名称的方式一样. + +想要自定义组件名称,只需要使用ASP.NET Core的 `ViewComponent` attribute: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget] + [ViewComponent(Name = "MyCustomNamedWidget")] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View("~/Pages/Components/MySimpleWidget/Default.cshtml"); + } + } +} +``` + +ABP会通过自定义的名称去处理部件. + +> 如果视图组件名与视图组件的文件夹名称不匹配,那么需要像本例中那样去手动编写视图路径. + +### 显示名称 + +你还可以定义对于使用者友好的本地化显示名称. 需要时在UI中使用显示名称. 显示名称是可选的,在 `Widget` attribute 的`DisplayName`属性中定义: + +````csharp +using DashboardDemo.Localization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget( + DisplayName = "MySimpleWidgetDisplayName", //Localization key + DisplayNameResource = typeof(DashboardDemoResource) //localization resource + )] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +参阅 [本地化文档](../Localization.md) 学习关于本地化资源的更多内容. + +## 引用 Style & Script + +当部件含有样式和scirpt文件时,会存在一些挑战; + +* 使用部件的页面应该将 **script & styles** 文件引用到页面中. +* 页面还需要解析部件的 `依赖库/文件`. + +将资源与部件正确的关联在一起时,ABP会解决这些问题. 使用正确的方法,就不用担心部件的依赖关系. + +### 定义一个简单的文件路径 + +下面的示例中部件添加了样式和scirpt文件: + +````csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget( + StyleFiles = new[] { "/Pages/Components/MySimpleWidget/Default.css" }, + ScriptFiles = new[] { "/Pages/Components/MySimpleWidget/Default.js" } + )] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +ABP会考虑到这些依赖关系, 在view/page中使用正确的方法添加部件 . 样式和script可以是物理文件也可以是虚拟文件. 它于[虚拟文件系统](../Virtual-File-System.md)完全集成]. + +### 定义 Bundle + +页面中使用的组件的所有资源都做为捆绑包添加(如果没有其他配置,会在生产中合并和压缩). 除了简单的添加文件,你还可以充分的利用捆绑功能. + +下面的示例与上面的代码相同,但是在添加文件时文件路径替换成了 `BundleContributor`: + +````csharp +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget( + StyleTypes = new []{ typeof(MySimpleWidgetStyleBundleContributor) }, + ScriptTypes = new[]{ typeof(MySimpleWidgetScriptBundleContributor) } + )] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } + + public class MySimpleWidgetStyleBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files + .AddIfNotContains("/Pages/Components/MySimpleWidget/Default.css"); + } + } + + public class MySimpleWidgetScriptBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files + .AddIfNotContains("/Pages/Components/MySimpleWidget/Default.js"); + } + } +} + +```` + +捆绑系统非常强大,如果你的部件使用了JavaScript库来呈现图表, 你可以将它声明为依赖项, 如果之前未添加JavaScript库. 则会自动添加到页面中. 使用这种方式让页面使用部件时不用关心依赖项. + +参阅 [捆包&压缩 文档](Bundling-Minification.md) 了解更多内容. + +## 授权 + +某些组件可能只对通过身份验证或授权的用户可用,这时可以使用 `Widget` attribute 的以下属性: + +* `RequiresAuthentication` (`bool`): 设置为true,只有通过身份验证的用户(登录用户)可用. +* `RequiredPolicies` (`List`): 授权用户的策略名称列表. 有关策略的详细信息请参阅[授权文档](../Authorization.md). + +示例: + +````csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace DashboardDemo.Web.Pages.Components.MySimpleWidget +{ + [Widget(RequiredPolicies = new[] { "MyPolicyName" })] + public class MySimpleWidgetViewComponent : AbpViewComponent + { + public IViewComponentResult Invoke() + { + return View(); + } + } +} +```` + +## 部件选项 + +`WidgetOptions` 是 `Widget` attribute 替代, 你可以使用它去配置部件: + +```csharp +Configure(options => +{ + options.Widgets.Add(); +}); +``` + +将上面的代码写到[模块](../Module-Development-Basics.md)的 `ConfigureServices` 方法中. `Widgetoptions` 可以完成 `Widget` attribute 的所有功能. 比如为组件添加样式: + +````csharp +Configure(options => +{ + options.Widgets + .Add() + .WithStyles("/Pages/Components/MySimpleWidget/Default.css"); +}); +```` + +> 提示: `WidgetOptions` 还可以更改现有的部件配置. 如果要修改应用程序使用的模块内的组件配置,这会很有用. 使用 `options.Widgets.Find` 获取现有的 `WidgetDefinition`. \ No newline at end of file diff --git a/docs/zh-Hans/images/widget-basic-files.png b/docs/zh-Hans/images/widget-basic-files.png new file mode 100644 index 0000000000000000000000000000000000000000..bf5f122d42a2b86342d85017532f268e732cf5ec GIT binary patch literal 10185 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 CGo0!G literal 0 HcmV?d00001 From dea20ce4a0b3f7353781698e0f97c12a743db906 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 24 Jul 2019 08:05:24 +0800 Subject: [PATCH 8/8] Update docs-nav.json --- docs/zh-Hans/docs-nav.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index 1150545240..fb147ac0fe 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -222,7 +222,7 @@ }, { "text": "仪表板和小部件(Widget)系统", - "path": "AspNetCore/Tag-Helpers/DashboardWidgetSystem.md" + "path": "AspNetCore/Widgets.md" }, { "text": "主题化",