diff --git a/docfx/articles/data/AxoDataExchange.md b/docfx/articles/data/AxoDataExchange.md new file mode 100644 index 000000000..bc1a40906 --- /dev/null +++ b/docfx/articles/data/AxoDataExchange.md @@ -0,0 +1,126 @@ +# AxoDataExchange + +## Getting started + +### Data exchange manager + +For the data exchange to work, we must create a class extending the `AxoDataExchange`. + +[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataDocuExample.st?name=ProcessDataMangerDeclaration)] + +### Data exchange object + +We will also need to add our data entity variable, which contains the data that we want to exchange between PLC and the repository. This variable must be annotated with `AxoDataEntityAttribute` and `#ix-generic:TOnline` and `#ix-generic:TPlain as POCO` attributes that provide type information for the data exchange. + +> [!NOTE] +> `AxoDataEntityAttribute`, `#ix-generic:TOnline` and `#ix-generic:TPlain as POCO` must be attributed to only one member `AxoDataExchange` object and is used to locate data object that contains data to be exchanged between PLC and the target repository. +An exception is thrown when `DataEntityAttribute` is missing or multiple members have the annotation. + + +> [!NOTE] +> The 'Data' variable must be of a type that extends `AxoDataEntity`. + +[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataDocuExample.st?name=ProcessDataDeclaration)] + +### Data exchange initialization in PLC + +As mentioned earlier, we use remote calls to execute the CRUD operations. These calls are a variant of `AxoTask`, which allows for invoking a C# code. We will now need to create an instance of `AxoProcessDataManager` in a context object (`AxoContext`) (or as a member of another class that derives from `AxoObject`). We will also need to call `DataManager` in the Main method of appropriate context. + +[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataDocuExample.st?name=ContextDeclaration)] + +Instantiate context in a configuration +~~~ +CONFIGURATION MyConfiguration + VAR_GLOBAL + _myContext : Context; + END_VAR +END_CONFIGURATION +~~~ + +Execute the context in a program +~~~ +PROGRAM MAIN +VAR_EXTERNAL + _myContext : Context; +END_VAR + +_myContext.Run(); + +~~~ + +### Data exchange initialization in .NET + +At this point, we have everything ready in the PLC. + +We must now tell the `DataManager` what repository we will use. We will work with data stored in files in JSON format. + +Let's create a configuration for the repository and initialize remote data exchange: + + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Program.cs?name=AxoDataExampleDocuIntialization)] + + +> [!NOTE] +> `MyData` should be of type from `Pocos`. + + +### Usage + +Now we can freely shuffle the data between PLC and the local folder. + +[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataDocuExample.st?name=UseManager)] + +## Data visualization + +### Automated rendering using `RenderableContentControl` + +With `Command` presentation type, options exist for adding, editing, and deleting records. + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataDocuExamples.razor?name=CommandView)] + +![Command](~/images/Command.png) + +If you use `Status` presentation type, data will be only displayed and cannot be manipulated. + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataDocuExamples.razor?name=DisplayView)] + +![Status](~/images/Status.png) + +### Custom columns + +There is a possibility to add custom columns if it is needed. You must add `AXOpen.Data.ColumnData` view as a child in `DataView`. The `BindingValue` must be set in `ColumnData` and contains a string representing the attribute name of custom columns. If you want to add a custom header name, you can set the name in `HeaderName` attribute. Also, there is an attribute to make the column not clickable, which is clickable by default. The example using all attributes: + + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataDocuExamples.razor?name=CustomColumns)] + +When adding data view manually, you will need to create ViewModel: + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataDocuExamples.razor?name=CustomColumnsCode)] + + +![Custom columns](~/images/CustomColumns.png) + + + +### Modal detail view + +The Detail View is default shown like modal view. That means if you click on some record, the modal window with a detail view will be shown. If necessary, this option can be changed with `ModalDetailView` attribute. This change will show a detail view under the record table. Example with `ModalDetailView` attribute: + +~~~ + +~~~ + +![Not Modal detail view](~/images/NotModalDetailView.png) diff --git a/docfx/articles/data/AxoDataFragmentExchange.md b/docfx/articles/data/AxoDataFragmentExchange.md new file mode 100644 index 000000000..d1ae1f61c --- /dev/null +++ b/docfx/articles/data/AxoDataFragmentExchange.md @@ -0,0 +1,107 @@ +# AxoDataFragmentExchange + +Fragment data exchange allows to group of multiple data managers into a single object and perform repository operations jointly on all nested repositories. + +### Data fragment exchange manager + +We must create a class extending the `AxoDataFragmentExchange` for the data fragment exchange to work. + +[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataFragmentExchangeDocu.st?name=ProcessDataMangerDeclaration)] + +**Nesting AxoDataExchanger(s)** + +AxoDataFragmenExchange can group several data managers where each can point to a different repository. Nested data managers must be set up as explained [here](AxoDataExchange.md#data-exchange-manager). + +> [!NOTE] +> Note that each data manager must be annotated with `AXOpen.Data.AxoDataFragmentAttribute` that will provide information to the parent manager that the member takes part in data operations. + +> [!IMPORTANT] +> First data manager declared as a fragment is considered a master fragment. The overview and list of existing data are retrieved only from the master fragment. + +### Initialization and handling in the controller + +We will now need to create an instance of `AxoDataFragmentExchange` in a context object (`AxoContext`) (or as a member of another class that derives from `AxoObject`). We will also need to call `AxoDataFragmentExchangeContext` in the Main method of appropriate context. + +[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataFragmentExchangeDocu.st?name=ContextDeclaration)] + +Instantiate context in a configuration +~~~ +CONFIGURATION MyConfiguration + VAR_GLOBAL + _myContext : AxoDataFragmentExchangeContext; + END_VAR +END_CONFIGURATION +~~~ + +Execute the context in a program. +~~~ +PROGRAM MAIN +VAR_EXTERNAL + _myContext : AxoDataFragmentExchangeContext; +END_VAR + +_myContext.Run(); + +~~~ + +### Data exchange initialization in .NET + +At this point, we have everything ready in the PLC. + +If the nested data exchange object does not have the repository set previously, we will need to tell the to fragment manager wich repositories we be used by in data exchange. We will work with data stored in files in JSON format. + + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Program.cs?name=AxoDataFragmentedExampleDocuIntialization)] + +> [!NOTE] +> `MyData` should be of type from `Pocos`. + + +### Usage + +Now we can freely shuffle the data between PLC and the local folder. + +[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataFragmentExchangeDocu.st?name=UseManager)] + +## Data visualization + +### Automated rendering using `RenderableContentControl` + +With `Command` presentation type, options exist for adding, editing, and deleting records. + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataFragmetsDocuExamples.razor?name=CommandView)] + +![Command](~/images/Command.png) + +If you use `Status` presentation type, data will be only displayed and cannot be manipulated. + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataFragmetsDocuExamples.razor?name=DisplayView)] + +![Status](~/images/Status.png) + +### Custom columns + +There is a possibility to add custom columns if it is needed. You must add `AXOpen.Data.ColumnData` view as a child in `DataView`. The `BindingValue` must be set in `ColumnData` and contains a string representing the attribute name of custom columns. If you want to add a custom header name, you can set the name in `HeaderName` attribute. Also, there is an attribute to make the column not clickable, which is clickable by default. The example using all attributes: + + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataFragmetsDocuExamples.razor?name=CustomColumns)] + +When adding data view manually, you will need to create ViewModel: + +[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataFragmetsDocuExamples.razor?name=CustomColumnsCode)] + + +![Custom columns](~/images/CustomColumns.png) + +> [!NOTE] +> Custom columns can only added from master fragment (first declared repository). + +### Modal detail view + +The Detail View is default shown like modal view. That means if you click on some record, the modal window with a detail view will be shown. If necessary, this option can be changed with `ModalDetailView` attribute. This change will show a detail view under the record table. Example with `ModalDetailView` attribute: + +~~~ + +~~~ + +![Not Modal detail view](~/images/NotModalDetailView.png) diff --git a/docfx/articles/data/README.md b/docfx/articles/data/README.md index 85166e439..a2875eab3 100644 --- a/docfx/articles/data/README.md +++ b/docfx/articles/data/README.md @@ -1,4 +1,6 @@ -# AxoData +# **AXOpen.Data** + +**AXOpen.Data** provides data exchange between the controller and an arbitrary repository. `AXOpen.Data` library provides a simple yet powerful data exchange between PLC and an arbitrary data repository. It includes the implementation of a series of repository operations known as CRUD (Create Read Update Delete), accessible directly from the PLC. @@ -21,127 +23,6 @@ At this point, AXOpen supports these repositories directly: - MongoDB - RavenDB -## Getting started - -### Data exchange manager - -For the data exchange to work, we must create a class extending the `AxoDataExchange`. - -[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataDocuExample.st?name=ProcessDataMangerDeclaration)] - -### Data exchange object - -We will also need to add our data entity variable, which contains the data that we want to exchange between PLC and the repository. This variable must be annotated with `AxoDataEntityAttribute` and `#ix-generic:TOnline` and `#ix-generic:TPlain as POCO` attributes that provide type information for the data exchange. - -> [!IMPORTANT] -> `AxoDataEntityAttribute`, `#ix-generic:TOnline` and `#ix-generic:TPlain as POCO` must be attributed to only one member `AxoDataExchange` object and is used to locate data object that contains data to be exchanged between PLC and the target repository. -An exception is thrown when `DataEntityAttribute` is missing or multiple members have the annotation. - - -> [!IMPORTANT] -> The 'Data' variable must be of a type that extends `AxoDataEntity`. - -[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataDocuExample.st?name=ProcessDataDeclaration)] - -### Data exchange initialization in PLC - -As mentioned earlier, we use remote calls to execute the CRUD operations. These calls are a variant of `AxoTask`, which allows for invoking a C# code. We will now need to create an instance of `AxoProcessDataManager` in a context object (`AxoContext`) (or as a member of another class that derives from `AxoObject`). We will also need to call `DataManager` in the Main method of appropriate context. - -[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataDocuExample.st?name=ContextDeclaration)] - -Instantiate context in a configuration -~~~ -CONFIGURATION MyConfiguration - VAR_GLOBAL - _myContext : Context; - END_VAR -END_CONFIGURATION -~~~ - -Execute the context in a program -~~~ -PROGRAM MAIN -VAR_EXTERNAL - _myContext : Context; -END_VAR - -_myContext.Run(); - -~~~ - -### Data exchange initialization in .NET - -At this point, we have everything ready in the PLC. - -We must now tell the `DataManager` what repository we will use. We will work with data stored in files in JSON format. - -Let's create a configuration for the repository and initialize remote data exchange: - - -[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Program.cs?name=AxoDataExampleDocuIntialization)] - - -> [!IMPORTANT] -> `MyData` should be of type from `Pocos`. - - -### Usage - -Now we can freely shuffle the data between PLC and the local folder. - -[!code-smalltalk[](../../../src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataDocuExample.st?name=UseManager)] - -## Data visualization - -### Automated rendering using `RenderableContentControl` - -With `Command` presentation type, options exist for adding, editing, and deleting records. - -[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataDocuExamples.razor?name=CommandView)] - -![Command](~/images/Command.png) - -If you use `Status` presentation type, data will be only displayed and cannot be manipulated. - -[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataDocuExamples.razor?name=DisplayView)] - -![Status](~/images/Status.png) - -### Custom columns - -There is a possibility to add custom columns if it is needed. You must add `AXOpen.Data.AxoColumnData` view as a child in `AxoDataView`. The `BindingValue` must be set in `ColumnData` and contains a string representing the attribute name of custom columns. If you want to add a custom header name, you can set the name in `HeaderName` attribute. Also, there is an attribute to make the column not clickable, which is clickable by default. The example using all attributes: - - -[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataDocuExamples.razor?name=CustomColumns)] - -When adding data view manually, you will need to create ViewModel: - -[!code-csharp[](../../../src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataDocuExamples.razor?name=CustomColumnsCode)] - - -![Custom columns](~/images/CustomColumns.png) - -### Export/Import - -If you want to be able to export data, you must add `CanExport` attribute with `true` value. Like this: - -~~~ - -~~~ - -With this option, buttons for export and import data will appear. After clicking on the export button, the `csv` file will be created, which contains all existing records. If you want to import data, you must upload `csv` file with an equal data structure as we get in the export file. - -![Export](~/images/Export.png) - -> [!IMPORTANT] -> Export and import function will create high load on the application. Don't use with large datasets. These function can be used only on a limited number (100 or less) documents. Typical used would be for recipes and settings, but not for large collections of production or event data. - -### Modal detail view - -The Detail View is default shown like modal view. That means if you click on some record, the modal window with a detail view will be shown. If necessary, this option can be changed with `ModalDetailView` attribute. This change will show a detail view under the record table. Example with `ModalDetailView` attribute: - -~~~ - -~~~ -![Not Modal detail view](~/images/NotModalDetailView.png) +[!INCLUDE [AxoDataExchange](AxoDataExchange.md)] +[!INCLUDE [AxoDataFragmentExchange](AxoDataFragmentExchange.md)] diff --git a/docfx/articles/toc.yml b/docfx/articles/toc.yml index bddcf2207..f209a7472 100644 --- a/docfx/articles/toc.yml +++ b/docfx/articles/toc.yml @@ -25,6 +25,11 @@ href: ~/articles/core/AXOCOMPONENT.md - name: AXOpen.Data href: ~/articles/data/README.md + items: + - name: Data exchange + href: ~/articles/data/AxoDataExchange.md + - name: Data fragmets exchange + href: ~/articles/data/AxoDataFragmentExchange.md - name: AXOpen.Messaging href: ~/articles/messaging/README.md items: diff --git a/src/core/ctrl/src/AxoTask/AxoTask.st b/src/core/ctrl/src/AxoTask/AxoTask.st index a5e63e564..60ec3e041 100644 --- a/src/core/ctrl/src/AxoTask/AxoTask.st +++ b/src/core/ctrl/src/AxoTask/AxoTask.st @@ -189,6 +189,7 @@ NAMESPACE AXOpen.Core IF _isNullContext THEN Status := eAxoTaskState#Error; + ErrorDetails := 'NULL CONTEXT'; END_IF; THIS.UpdateState(); diff --git a/src/data/ctrl/src/AxoDataCrudTask.st b/src/data/ctrl/src/AxoDataCrudTask.st index e90b8c794..911ec1f0b 100644 --- a/src/data/ctrl/src/AxoDataCrudTask.st +++ b/src/data/ctrl/src/AxoDataCrudTask.st @@ -2,12 +2,25 @@ USING AXOpen.Core; NAMESPACE AXOpen.Data + /// + /// Provides remote execution for CRUD operations. + /// > [!NOTE] + /// > This is an extension of task see the documentatio for details about implementation in .NET. + /// CLASS AxoDataCrudTask EXTENDS AxoDataExchangeTask VAR PUBLIC + /// + /// Gets or sets the type of CRUD operation to be perfomed. + /// CrudOperation : eCrudOperation; END_VAR + /// + /// Invokes this task. + /// + /// Data entity identifier + /// Operation to perfom. METHOD PUBLIC Invoke : IAxoTaskState VAR_INPUT identifier : STRING[254]; diff --git a/src/data/ctrl/src/AxoDataEntity.st b/src/data/ctrl/src/AxoDataEntity.st index 616df8daf..7b5f4dca5 100644 --- a/src/data/ctrl/src/AxoDataEntity.st +++ b/src/data/ctrl/src/AxoDataEntity.st @@ -1,6 +1,12 @@ NAMESPACE AXOpen.Data + /// + /// Base class for any exchangable data in . + /// CLASS AxoDataEntity IMPLEMENTS IAxoDataEntity VAR PUBLIC + /// + /// Gets or sets data entity identifier. + /// {#ix-attr:[RenderIgnore()]} DataEntityId : STRING[254]; END_VAR diff --git a/src/data/ctrl/src/AxoDataExchange.st b/src/data/ctrl/src/AxoDataExchange.st index e713b452e..30121d088 100644 --- a/src/data/ctrl/src/AxoDataExchange.st +++ b/src/data/ctrl/src/AxoDataExchange.st @@ -1,6 +1,10 @@ USING AXOpen.Core; -NAMESPACE AXOpen.Data +NAMESPACE AXOpen.Data + /// + /// Provides base class for any data exchange with an arbitrary remote repository. + /// **For configuration and set up see [here](~/articles/data/AxoDataExchange.md)** + /// {#ix-generic:} CLASS AxoDataExchange EXTENDS AxoDataExchangeBase IMPLEMENTS IAxoDataExchange VAR PUBLIC @@ -26,50 +30,77 @@ NAMESPACE AXOpen.Data DeleteTask.Execute(); END_METHOD + /// + /// Runs intialization and cyclical handling of this AxoDataExchange. + /// + /// Parent of this object METHOD PUBLIC Run VAR_INPUT - Parent : IAxoObject; + parent : IAxoObject; END_VAR - THIS.Initialize(Parent); + THIS.Initialize(parent); THIS.Run(); END_METHOD + /// + /// Runs intialization and cyclical handling of this AxoDataExchange. + /// + /// Root context of this object METHOD PUBLIC Run - VAR_INPUT - Context : IAxoContext; + VAR_INPUT + context : IAxoContext; END_VAR - THIS.Initialize(Context); + THIS.Initialize(context); THIS.Run(); END_METHOD + /// + /// Creates new entry into the remote repository from data entity of this AxoDataExchange. + /// + /// Data identifier. METHOD PUBLIC Create : IAxoTaskState VAR_INPUT - Identifier : STRING[254]; + identifier : STRING[254]; END_VAR - Create := CreateTask.Invoke(Identifier); + Create := CreateTask.Invoke(identifier); END_METHOD + /// + /// Reads data from remote repository and copies them into data entity of this AxoDataExchange. + /// + /// Data identifier. METHOD PUBLIC Read : IAxoTaskState VAR_INPUT - Identifier : STRING[254]; + identifier : STRING[254]; END_VAR - Read := ReadTask.Invoke(Identifier); + Read := ReadTask.Invoke(identifier); END_METHOD + /// + /// Updates data in remote repository from data entiry of this AxoDataExchange. + /// + /// Data identifier. METHOD PUBLIC Update : IAxoTaskState VAR_INPUT - Identifier : STRING[254]; + identifier : STRING[254]; END_VAR - Update := UpdateTask.Invoke(Identifier); + Update := UpdateTask.Invoke(identifier); END_METHOD + /// + /// Deletes data entry with given ID from remote repository. + /// + /// Data identifier. METHOD PUBLIC Delete : IAxoTaskState VAR_INPUT - Identifier : STRING[254]; + identifier : STRING[254]; END_VAR - Delete := DeleteTask.Invoke(Identifier); + Delete := DeleteTask.Invoke(identifier); END_METHOD + /// + /// Restores all tasks associated with this object. + /// METHOD PUBLIC Restore CreateTask.Restore(); ReadTask.Restore(); diff --git a/src/data/ctrl/src/AxoDataExchangeBase.st b/src/data/ctrl/src/AxoDataExchangeBase.st index b4d271118..cb8fbabed 100644 --- a/src/data/ctrl/src/AxoDataExchangeBase.st +++ b/src/data/ctrl/src/AxoDataExchangeBase.st @@ -1,7 +1,10 @@ USING AXOpen.Core; NAMESPACE AXOpen.Data - CLASS AxoDataExchangeBase EXTENDS AXOpen.Core.AxoObject - + /// + /// Represents base class of data exchange. + /// This class is used to provide abstract information about the type that can be used in rcc. + /// + CLASS PUBLIC AxoDataExchangeBase EXTENDS AXOpen.Core.AxoObject END_CLASS END_NAMESPACE \ No newline at end of file diff --git a/src/data/ctrl/src/AxoDataExchangeTask.st b/src/data/ctrl/src/AxoDataExchangeTask.st index 88f26a306..9be8bf0fd 100644 --- a/src/data/ctrl/src/AxoDataExchangeTask.st +++ b/src/data/ctrl/src/AxoDataExchangeTask.st @@ -1,7 +1,9 @@ USING AXOpen.Core; NAMESPACE AXOpen.Data - + /// + /// Extends AxoRemoteTask for data operation within AxoData + /// CLASS AxoDataExchangeTask EXTENDS AXOpen.Core.AxoRemoteTask VAR PUBLIC diff --git a/src/data/ctrl/src/AxoDataFragmentExchange.st b/src/data/ctrl/src/AxoDataFragmentExchange.st index bde5e8bca..0fc7531a2 100644 --- a/src/data/ctrl/src/AxoDataFragmentExchange.st +++ b/src/data/ctrl/src/AxoDataFragmentExchange.st @@ -1,11 +1,21 @@ USING AXOpen.Core; +USING AXOpen.Core; +USING AXOpen.Core; -NAMESPACE AXOpen.Data +NAMESPACE AXOpen.Data + /// + /// Provides base class for any composite/fragmetes data exchange combining one or more AxoDataExchange object. + /// **For configuration and set up see [here](~/articles/data/AxoDataFragmentExchange.md)** + /// CLASS PUBLIC AxoDataFragmentExchange EXTENDS AxoDataExchangeBase IMPLEMENTS IAxoDataExchange VAR PUBLIC Operation : AxoDataCrudTask; END_VAR - + + /// + /// Creates new entry into each associated remote repository from respective data entity. + /// + /// Data identifier. METHOD PUBLIC Create : IAxoTaskState VAR_INPUT Identifier : STRING[254]; @@ -13,6 +23,10 @@ NAMESPACE AXOpen.Data Create := Operation.Invoke(Identifier, eCrudOperation#Create); END_METHOD + /// + /// Reads data from each associated remote repository and copies it into respective data entities. + /// + /// Data identifier. METHOD PUBLIC Read : IAxoTaskState VAR_INPUT Identifier : STRING[254]; @@ -20,22 +34,57 @@ NAMESPACE AXOpen.Data Read := Operation.Invoke(Identifier, eCrudOperation#Read); END_METHOD + /// + /// Updates data in each associated remote repository from respective data entities. + /// + /// Data identifier. METHOD PUBLIC Update : IAxoTaskState VAR_INPUT Identifier : STRING[254]; END_VAR - Update := Operation.Invoke(Identifier, eCrudOperation#Read); + Update := Operation.Invoke(Identifier, eCrudOperation#Update); END_METHOD + /// + /// Deletes data entry from each associated remote repository with given ID. + /// + /// Data identifier. METHOD PUBLIC Delete : IAxoTaskState VAR_INPUT Identifier : STRING[254]; END_VAR - Delete := Operation.Invoke(Identifier, eCrudOperation#Read); + Delete := Operation.Invoke(Identifier, eCrudOperation#Delete); END_METHOD METHOD PUBLIC Restore Operation.Restore(); - END_METHOD + END_METHOD + + /// + /// Runs intialization and cyclical handling of this AxoDataExchange. + /// + /// Root context of this object + METHOD PUBLIC Run + VAR_INPUT + context : IAxoContext; + END_VAR + THIS.Initialize(context); + Operation.Initialize(THIS); + Operation.Execute(); + END_METHOD + + /// + /// Runs intialization and cyclical handling of this AxoDataExchange. + /// + /// Parent of this object + METHOD PUBLIC Run + VAR_INPUT + parent : IAxoObject; + END_VAR + THIS.Initialize(parent); + Operation.Initialize(THIS); + Operation.Execute(); + END_METHOD + END_CLASS END_NAMESPACE diff --git a/src/data/ctrl/src/IAxoDataEntity.st b/src/data/ctrl/src/IAxoDataEntity.st index 3ed226259..0c4b3e9d2 100644 --- a/src/data/ctrl/src/IAxoDataEntity.st +++ b/src/data/ctrl/src/IAxoDataEntity.st @@ -1,5 +1,4 @@ NAMESPACE AXOpen.Data - INTERFACE IAxoDataEntity - + INTERFACE IAxoDataEntity END_INTERFACE END_NAMESPACE \ No newline at end of file diff --git a/src/data/ctrl/src/IAxoDataExchange.st b/src/data/ctrl/src/IAxoDataExchange.st index 09f839fc3..380d98c6d 100644 --- a/src/data/ctrl/src/IAxoDataExchange.st +++ b/src/data/ctrl/src/IAxoDataExchange.st @@ -1,7 +1,10 @@ USING AXOpen.Core; -NAMESPACE AXOpen.Data - INTERFACE IAxoDataExchange +NAMESPACE AXOpen.Data + /// + /// Provides abastaction for data exchange. + /// + INTERFACE IAxoDataExchange METHOD Create : IAxoTaskState VAR_INPUT Identifier : STRING[254]; @@ -27,6 +30,19 @@ NAMESPACE AXOpen.Data END_METHOD METHOD Restore - END_METHOD + END_METHOD + + METHOD Run + VAR_INPUT + context : IAxoContext; + END_VAR + + END_METHOD + + METHOD Run + VAR_INPUT + parent : IAxoObject; + END_VAR + END_METHOD END_INTERFACE END_NAMESPACE \ No newline at end of file diff --git a/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeViewModel.cs b/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeViewModel.cs index 9bd048423..11ddcc6db 100644 --- a/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeViewModel.cs +++ b/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeViewModel.cs @@ -144,6 +144,14 @@ public async Task CreateNew() { try { + if (string.IsNullOrEmpty(CreateItemId)) + { + WeakReferenceMessenger.Default.Send(new ToastMessage(new Toast("Danger", "Cannot create!", + "New entry name cannot be empty. Please provide an ID", 10))); + + return; + } + await DataExchange.CreateNewAsync(CreateItemId); WeakReferenceMessenger.Default.Send(new ToastMessage(new Toast("Success", "Created!", "Item was successfully created!", 10))); diff --git a/src/data/src/AXOpen.Data/DataFragmentExchange/AxoDataFragmentExchange.cs b/src/data/src/AXOpen.Data/DataFragmentExchange/AxoDataFragmentExchange.cs index d57bfb3a1..f775de2ce 100644 --- a/src/data/src/AXOpen.Data/DataFragmentExchange/AxoDataFragmentExchange.cs +++ b/src/data/src/AXOpen.Data/DataFragmentExchange/AxoDataFragmentExchange.cs @@ -16,14 +16,32 @@ public partial class AxoDataFragmentExchange { protected IAxoDataExchange[] DataFragments { get; private set; } - public T? Builder() where T : AxoDataFragmentExchange + public T? CreateBuilder() where T : AxoDataFragmentExchange + { + return CreateBuilder() as T; + } + + public object CreateBuilder() { DataFragments = GetDataSetProperty().ToArray(); - Operation.InitializeExclusively(Handle); - Operation.WriteAsync().Wait(); RefUIData = new AxoFragmentedDataCompound(this, DataFragments.Select(p => p.RefUIData).Cast().ToList()); Repository = new AxoCompoundRepository(DataFragments); - return this as T; + return this; + } + + /// + /// Initializes data exchange between remote controller and this + /// + public void InitializeRemoteDataExchange() + { + Operation.InitializeExclusively(Handle); + this.WriteAsync().Wait(); + } + + public void DeInitializeRemoteDataExchange() + { + Operation.DeInitialize(); + this.WriteAsync().Wait(); } private void Handle() @@ -163,7 +181,7 @@ public bool RemoteDelete(string identifier) public IEnumerable GetRecords(string identifier, int limit, int skip, eSearchMode searchMode) { - return ((dynamic)Repository).GetRecords(identifier, limit, skip, searchMode); + return ((dynamic)Repository)?.GetRecords(identifier, limit, skip, searchMode); } public IEnumerable GetRecords(string identifier) diff --git a/src/data/src/repositories/Json/Json/JsonRepository.cs b/src/data/src/repositories/Json/Json/JsonRepository.cs index 16eb85df7..296741547 100644 --- a/src/data/src/repositories/Json/Json/JsonRepository.cs +++ b/src/data/src/repositories/Json/Json/JsonRepository.cs @@ -172,6 +172,7 @@ protected override long FilteredCountNvi(string id, eSearchMode searchMode) private bool RecordExists(string identifier) { + if (string.IsNullOrEmpty(identifier)) return false; return File.Exists(Path.Combine(this.Location, identifier)); } diff --git a/src/data/src/repositories/MongoDb/Mongo/MongoDbRepositorySettings.cs b/src/data/src/repositories/MongoDb/Mongo/MongoDbRepositorySettings.cs index ee692d53a..b780398d1 100644 --- a/src/data/src/repositories/MongoDb/Mongo/MongoDbRepositorySettings.cs +++ b/src/data/src/repositories/MongoDb/Mongo/MongoDbRepositorySettings.cs @@ -48,7 +48,8 @@ public MongoDbRepositorySettings(string connectionString, string databaseName, s public MongoDbRepositorySettings(string connectionString, string databaseName, string collectionName, MongoDbCredentials credentials) { SetupSerialisationAndMapping(); - Client = GetClient(connectionString, credentials); + //Client = GetClient(connectionString, credentials); + Client = GetClient(connectionString); Database = GetDatabase(databaseName); Collection = GetCollection(collectionName); } diff --git a/src/data/tests/AXOpen.Data.Tests/DataExchangeFragments/AxoDataFragmentExchange.cs b/src/data/tests/AXOpen.Data.Tests/DataExchangeFragments/AxoDataFragmentExchange.cs index c9a8648b4..d628ccfeb 100644 --- a/src/data/tests/AXOpen.Data.Tests/DataExchangeFragments/AxoDataFragmentExchange.cs +++ b/src/data/tests/AXOpen.Data.Tests/DataExchangeFragments/AxoDataFragmentExchange.cs @@ -46,7 +46,7 @@ public async void RemoteCreate_ShouldCreateRecordsInEachRepository() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); s.Set.SetRepository(new InMemoryRepository()); s.Manip.SetRepository(new InMemoryRepository()); @@ -69,7 +69,7 @@ public async void RemoteRead_ShouldReadRecordsFromEachRepository() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); var sharedRepo = new InMemoryRepository(); var manipRepo = new InMemoryRepository(); s.Set.SetRepository(sharedRepo); @@ -94,7 +94,7 @@ public async void RemoteUpdate_ShouldUpdateRecordsInEachRepository() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); s.Set.SetRepository(new InMemoryRepository()); s.Manip.SetRepository(new InMemoryRepository()); @@ -124,7 +124,7 @@ public async void RemoteDelete_ShouldDeleteRecordsFromEachRepository() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); s.Set.SetRepository(new InMemoryRepository()); s.Manip.SetRepository(new InMemoryRepository()); @@ -150,7 +150,7 @@ public async void FromRepositoryToShadows_ShouldSetDataInShadowsFromPlainPocoObj var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); var sharedRepo = new InMemoryRepository(); var manipRepo = new InMemoryRepository(); s.Set.SetRepository(sharedRepo); @@ -176,7 +176,7 @@ public async void FromRepositoryToController_ShouldSetDataFromShadowsToControlle var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); var sharedRepo = new InMemoryRepository(); var manipRepo = new InMemoryRepository(); s.Set.SetRepository(sharedRepo); @@ -202,7 +202,7 @@ public async void GetRecords_Filtered_ShouldReturnRecordsFromRepository() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); s.Set.SetRepository(new InMemoryRepository()); s.Manip.SetRepository(new InMemoryRepository()); @@ -222,7 +222,7 @@ public async void GetRecords_ShouldReturnRecordsFromRepository() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); s.Set.SetRepository(new InMemoryRepository()); s.Manip.SetRepository(new InMemoryRepository()); @@ -242,7 +242,7 @@ public async void Delete_ShouldDeleteRecordsFromEachRepository() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); s.Set.SetRepository(new InMemoryRepository()); s.Manip.SetRepository(new InMemoryRepository()); @@ -268,7 +268,7 @@ public async void UpdateFromShadows_ShouldUpdateRecordsInEachRepository() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); s.Set.SetRepository(new InMemoryRepository()); s.Manip.SetRepository(new InMemoryRepository()); @@ -300,7 +300,7 @@ public async void LoadFromController_ShouldLoadExistingDataSetToEachShadow() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); s.Set.SetRepository(new InMemoryRepository()); s.Manip.SetRepository(new InMemoryRepository()); @@ -327,7 +327,7 @@ public async void CreateCopy_ShouldCreateInAllRepositoriesFromExisting() var parent = NSubstitute.Substitute.For(); parent.GetConnector().Returns(AXSharp.Connector.ConnectorAdapterBuilder.Build().CreateDummy().GetConnector(null)); var sut = new ProcessData(parent, "a", "b"); - var s = sut.Builder(); + var s = sut.CreateBuilder(); s.Set.SetRepository(new InMemoryRepository()); s.Manip.SetRepository(new InMemoryRepository()); diff --git a/src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataFragmentExchangeDocu.st b/src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataFragmentExchangeDocu.st new file mode 100644 index 000000000..4f899172b --- /dev/null +++ b/src/integrations/ctrl/src/Examples/AXOpen.AxoData/AxoDataFragmentExchangeDocu.st @@ -0,0 +1,117 @@ +USING AXOpen.Core; +USING AXOpen.Data; +USING AXOpen.Probers; + +NAMESPACE AxoDataFramentsExchangeDocuExample + + // + CLASS AxoDataFragmentExchangeContext EXTENDS AXOpen.Core.AxoContext + VAR PUBLIC + ProcessData : ProcessDataManager; + END_VAR + + METHOD PROTECTED OVERRIDE Main + // This is required to run cyclically. Method provides handling of data exchange tasks. + ProcessData.Run(THIS); + END_METHOD + END_CLASS + // + + // + CLASS ProcessDataManager EXTENDS AXOpen.Data.AxoDataFragmentExchange + VAR PUBLIC + {#ix-attr:[AXOpen.Data.AxoDataFragmentAttribute]} + SharedHeader : SharedDataHeaderManger; + {#ix-attr:[AXOpen.Data.AxoDataFragmentAttribute]} + Station_1 : Station_1_ProcessDataManger; + END_VAR + END_CLASS + // + + // + CLASS UseManager + VAR + _create : BOOL; + _read : BOOL; + _update : BOOL; + _delete : BOOL; + _id : STRING; + END_VAR + + METHOD Use + VAR_IN_OUT + DataFragmentManager : ProcessDataManager; + END_VAR + IF(_create) THEN + IF(DataFragmentManager.Create(_id).IsDone()) THEN + _create := FALSE; + END_IF; + END_IF; + + IF(_read) THEN + IF(DataFragmentManager.Read(_id).IsDone()) THEN + _read := FALSE; + END_IF; + END_IF; + + IF(_update) THEN + IF(DataFragmentManager.Update(_id).IsDone()) THEN + _update := FALSE; + END_IF; + END_IF; + + IF(_delete) THEN + IF(DataFragmentManager.Delete(_id).IsDone()) THEN + _delete := FALSE; + END_IF; + END_IF; + END_METHOD + END_CLASS + // + + CLASS SharedDataHeaderData EXTENDS AXOpen.Data.AxoDataEntity + VAR PUBLIC + {#ix-set:AttributeName = "Some string data"} + SomeData : STRING; + {#ix-set:AttributeName = "Some number"} + SomeNumber : INT; + {#ix-set:AttributeName = "Some boolean"} + SomeBool : BOOL; + END_VAR + END_CLASS + + CLASS SharedDataHeaderManger EXTENDS AXOpen.Data.AxoDataExchange + VAR PUBLIC + {#ix-generic:TOnline} + {#ix-generic:TPlain as POCO} + {#ix-attr:[AXOpen.Data.AxoDataEntityAttribute]} + {#ix-attr:[Container(Layout.Stack)]} + {#ix-set:AttributeName = "Shared Header"} + Set : SharedDataHeaderData; + END_VAR + END_CLASS + + CLASS Station_1_ProcessDataManger + EXTENDS AXOpen.Data.AxoDataExchange + VAR PUBLIC + {#ix-generic:TOnline} + {#ix-generic:TPlain as POCO} + {#ix-attr:[AXOpen.Data.AxoDataEntityAttribute]} + {#ix-attr:[Container(Layout.Stack)]} + {#ix-set:AttributeName = "Station 1"} + Set : Station_1_Data; + END_VAR + END_CLASS + + CLASS Station_1_Data + EXTENDS AXOpen.Data.AxoDataEntity + VAR PUBLIC + {#ix-set:AttributeName = "Some string data"} + SomeData : STRING; + {#ix-set:AttributeName = "Some number"} + SomeNumber : INT; + {#ix-set:AttributeName = "Some boolean"} + SomeBool : BOOL; + END_VAR + END_CLASS +END_NAMESPACE \ No newline at end of file diff --git a/src/integrations/ctrl/src/IntegrationTests/data/AxoDataFragmentExchange.st b/src/integrations/ctrl/src/IntegrationTests/data/AxoDataFragmentExchange.st new file mode 100644 index 000000000..ef8b5e3a0 --- /dev/null +++ b/src/integrations/ctrl/src/IntegrationTests/data/AxoDataFragmentExchange.st @@ -0,0 +1,203 @@ +USING AXOpen.Core; +USING AXOpen.Data; +USING AXOpen.Probers; + +NAMESPACE IntegrationAxoDataFramentsExchange + + CLASS AxoDataFragmentExchangeContext EXTENDS AXOpen.Core.AxoContext + VAR PUBLIC + PD : ProcessData; + CreateTest : DataCreateTest; + ReadTest : DataReadTest; + UpdateTest : DataUpdateTest; + DeleteTest : DataDeleteTest; + END_VAR + + + METHOD PROTECTED OVERRIDE Main + + PD.Run(THIS); + + CreateTest.InjectManger(PD); + CreateTest.Run(THIS); + + ReadTest.InjectManger(PD); + ReadTest.Run(THIS); + + DeleteTest.InjectManger(PD); + DeleteTest.Run(THIS); + + UpdateTest.InjectManger(PD); + UpdateTest.Run(THIS); + END_METHOD + + END_CLASS + + CLASS ProcessData EXTENDS AXOpen.Data.AxoDataFragmentExchange + VAR PUBLIC + {#ix-attr:[AXOpen.Data.AxoDataFragmentAttribute]} + Set : SharedProductionDataManager; + {#ix-attr:[AXOpen.Data.AxoDataFragmentAttribute]} + Manip : FragmentProcessDataManger; + END_VAR + END_CLASS + + CLASS SharedProductionData EXTENDS AXOpen.Data.AxoDataEntity + VAR PUBLIC + ComesFrom : INT; + GoesTo : INT; + END_VAR + END_CLASS + + CLASS SharedProductionDataManager EXTENDS AXOpen.Data.AxoDataExchange + VAR PUBLIC + {#ix-generic:TOnline} + {#ix-generic:TPlain as POCO} + {#ix-attr:[AXOpen.Data.AxoDataEntityAttribute]} + {#ix-attr:[Container(Layout.Stack)]} + Set : SharedProductionData; + END_VAR + END_CLASS + + CLASS FragmentProcessDataManger + EXTENDS AXOpen.Data.AxoDataExchange + VAR PUBLIC + {#ix-generic:TOnline} + {#ix-generic:TPlain as POCO} + {#ix-attr:[AXOpen.Data.AxoDataEntityAttribute]} + {#ix-attr:[Container(Layout.Stack)]} + Set : FragmentProcessData; + END_VAR + END_CLASS + + CLASS FragmentProcessData + EXTENDS AXOpen.Data.AxoDataEntity + VAR PUBLIC + CounterDelay : ULINT; + END_VAR + END_CLASS + + CLASS DataCreateTest EXTENDS AxoProberWithCompletedCondition + VAR PUBLIC + Manager : IAxoDataExchange; + Identifier : STRING[254]; + END_VAR + METHOD PROTECTED OVERRIDE Test : BOOL + VAR + _taskState : IAxoTaskState; + END_VAR + IF(Manager <> NULL) THEN + _taskState := Manager.Create(Identifier); + THIS.ThrowWhen(_taskState.HasError(), _taskState.GetErrorDetails()); + Test := _taskState.IsDone(); + END_IF; + END_METHOD + + METHOD OVERRIDE OnRestore + SUPER.OnRestore(); + IF(Manager <> NULL) THEN + Manager.Restore(); + END_IF; + END_METHOD + + METHOD PUBLIC InjectManger + VAR_INPUT + Injectee : IAxoDataExchange; + END_VAR + Manager := Injectee; + END_METHOD + END_CLASS + + CLASS DataReadTest EXTENDS AxoProberWithCompletedCondition + VAR PUBLIC + Manager : IAxoDataExchange; + Identifier : STRING[254]; + END_VAR + METHOD PROTECTED OVERRIDE Test : BOOL + VAR + _taskState : IAxoTaskState; + END_VAR + IF(Manager <> NULL) THEN + _taskState := Manager.Read(Identifier); + THIS.ThrowWhen(_taskState.HasError(), _taskState.GetErrorDetails()); + Test := _taskState.IsDone(); + END_IF; + END_METHOD + + METHOD OVERRIDE OnRestore + SUPER.OnRestore(); + IF(Manager <> NULL) THEN + Manager.Restore(); + END_IF; + END_METHOD + + METHOD PUBLIC InjectManger + VAR_INPUT + Injectee : IAxoDataExchange; + END_VAR + Manager := Injectee; + END_METHOD + END_CLASS + + CLASS DataUpdateTest EXTENDS AxoProberWithCompletedCondition + VAR PUBLIC + Manager : IAxoDataExchange; + Identifier : STRING[254]; + END_VAR + METHOD PROTECTED OVERRIDE Test : BOOL + VAR + _taskState : IAxoTaskState; + END_VAR + IF(Manager <> NULL) THEN + _taskState := Manager.Update(Identifier); + THIS.ThrowWhen(_taskState.HasError(), _taskState.GetErrorDetails()); + Test := _taskState.IsDone(); + END_IF; + END_METHOD + + METHOD OVERRIDE OnRestore + SUPER.OnRestore(); + IF(Manager <> NULL) THEN + Manager.Restore(); + END_IF; + END_METHOD + + METHOD PUBLIC InjectManger + VAR_INPUT + Injectee : IAxoDataExchange; + END_VAR + Manager := Injectee; + END_METHOD + END_CLASS + + CLASS DataDeleteTest EXTENDS AxoProberWithCompletedCondition + VAR PUBLIC + Manager : IAxoDataExchange; + Identifier : STRING[254]; + END_VAR + METHOD PROTECTED OVERRIDE Test : BOOL + VAR + _taskState : IAxoTaskState; + END_VAR + IF(Manager <> NULL) THEN + _taskState := Manager.Delete(Identifier); + THIS.ThrowWhen(_taskState.HasError(), _taskState.GetErrorDetails()); + Test := _taskState.IsDone(); + END_IF; + END_METHOD + + METHOD OVERRIDE OnRestore + SUPER.OnRestore(); + IF(Manager <> NULL) THEN + Manager.Restore(); + END_IF; + END_METHOD + + METHOD PUBLIC InjectManger + VAR_INPUT + Injectee : IAxoDataExchange; + END_VAR + Manager := Injectee; + END_METHOD + END_CLASS +END_NAMESPACE \ No newline at end of file diff --git a/src/integrations/ctrl/src/IntegrationTests/integrationtests.st b/src/integrations/ctrl/src/IntegrationTests/integrationtests.st index 27eee9f0d..36d7b6351 100644 --- a/src/integrations/ctrl/src/IntegrationTests/integrationtests.st +++ b/src/integrations/ctrl/src/IntegrationTests/integrationtests.st @@ -3,6 +3,7 @@ NAMESPACE IntegrationTests VAR PUBLIC Probers : ProbersTestContext; DataExchangeLightTestsContext : IntegrationLightDirect.DataExchangeLightTestsContext; + DataFragmentContext : IntegrationAxoDataFramentsExchange.AxoDataFragmentExchangeContext; DM : IntegrationLightDirect.DataManager; END_VAR @@ -11,6 +12,7 @@ NAMESPACE IntegrationTests DM.Run(DataExchangeLightTestsContext); DataExchangeLightTestsContext.InjectDM(DM); DataExchangeLightTestsContext.Run(); + DataFragmentContext.Run(); END_METHOD END_CLASS END_NAMESPACE \ No newline at end of file diff --git a/src/integrations/ctrl/src/configuration.st b/src/integrations/ctrl/src/configuration.st index c417446e5..1be2fdbd7 100644 --- a/src/integrations/ctrl/src/configuration.st +++ b/src/integrations/ctrl/src/configuration.st @@ -24,7 +24,7 @@ CONFIGURATION MyConfiguration AxoMessengers : AxoStaticMessengerExample.Messengers; AxoMessengersDocu : AxoStaticMessengerDocuExample.Messengers; AxoRtc : AxoRtc.AxoS71500Rtc; - + AxoDataFragmentExchangeContext : AxoDataFramentsExchangeDocuExample.AxoDataFragmentExchangeContext; process_data_manager: AxoDataExamples.AxoProcessDataManager; test_data_manager: AxoDataExamples.AxoTestDataManager; diff --git a/src/integrations/ctrl/src/program.st b/src/integrations/ctrl/src/program.st index 8e024564f..cb9f6950e 100644 --- a/src/integrations/ctrl/src/program.st +++ b/src/integrations/ctrl/src/program.st @@ -21,6 +21,8 @@ PROGRAM MyProgram AxoMessengers : AxoStaticMessengerExample.Messengers; AxoMessengersDocu : AxoStaticMessengerDocuExample.Messengers; + AxoDataFragmentExchangeContext : AxoDataFramentsExchangeDocuExample.AxoDataFragmentExchangeContext; + // Integration test Integrations : IntegrationTests.Integrations; AxoRtc : AxoRtc.AxoS71500Rtc; @@ -45,7 +47,7 @@ PROGRAM MyProgram AxoMessengers.InjectRtc(AxoRtc); AxoMessengersDocu.Run(); AxoMessengersDocu.InjectRtc(AxoRtc); - + AxoDataFragmentExchangeContext.Run(); // Integration tests Integrations.Run(); diff --git a/src/integrations/src/AXOpen.Integrations.Blazor/Pages/AxoData/AxoDataFragmentsRemote.razor b/src/integrations/src/AXOpen.Integrations.Blazor/Pages/AxoData/AxoDataFragmentsRemote.razor new file mode 100644 index 000000000..3ae12730a --- /dev/null +++ b/src/integrations/src/AXOpen.Integrations.Blazor/Pages/AxoData/AxoDataFragmentsRemote.razor @@ -0,0 +1,28 @@ +@page "/AxoDataFragmentsRemote" +@using AXOpen.Data +

AxoDataRemote

+ +@**@ + + + +@code { + private DataExchangeViewModel _vm = new DataExchangeViewModel { Model = Entry.Plc.Integrations.DataFragmentContext.PD }; +} diff --git a/src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataFragmetsDocuExamples.razor b/src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataFragmetsDocuExamples.razor new file mode 100644 index 000000000..bdf93f5e4 --- /dev/null +++ b/src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/AxoDataFragmetsDocuExamples.razor @@ -0,0 +1,27 @@ +@page "/DocuExamples/AxoDataFragmetsDocuExamples" +@using AXOpen.Data; + + +

Editable

+// + +// +

Readonly

+// + +// + +// + + + + + +// + +// +@code { + protected DataExchangeViewModel VM { get; } = new() { Model = Entry.Plc.AxoDataFragmentExchangeContext.ProcessData }; +} + +// diff --git a/src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/DocuExamples.razor b/src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/DocuExamples.razor index 88dad4faf..8863c73ff 100644 --- a/src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/DocuExamples.razor +++ b/src/integrations/src/AXOpen.Integrations.Blazor/Pages/DocuExamples/DocuExamples.razor @@ -29,5 +29,10 @@ AxoMessagingStaticDocu + diff --git a/src/integrations/src/AXOpen.Integrations.Blazor/Program.cs b/src/integrations/src/AXOpen.Integrations.Blazor/Program.cs index 959d75e53..cf2ffc5bb 100644 --- a/src/integrations/src/AXOpen.Integrations.Blazor/Program.cs +++ b/src/integrations/src/AXOpen.Integrations.Blazor/Program.cs @@ -2,9 +2,11 @@ using axopen_integrations; using AXSharp.Connector; using AXOpen.Core.blazor.Toaster; +using AXOpen.Data.Json; using AXSharp.Presentation.Blazor.Services; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; +using Pocos.IntegrationAxoDataFramentsExchange; using static System.Formats.Asn1.AsnWriter; namespace axopen_integrations_blazor @@ -48,6 +50,15 @@ public static void Main(string[] args) Repository.Factory (new AXOpen.Data.Json.JsonRepositorySettings(Path.Combine(Environment.CurrentDirectory, "data", "processdata1")))); + var pdfBuilder = + Entry.Plc.Integrations.DataFragmentContext.PD.CreateBuilder(); + + pdfBuilder.Set.SetRepository(new JsonRepository( + new AXOpen.Data.Json.JsonRepositorySettings(Path.Combine(Environment.CurrentDirectory, "bin", "data-framents", "set")))); + pdfBuilder.Manip.SetRepository( + new JsonRepository( new AXOpen.Data.Json.JsonRepositorySettings(Path.Combine(Environment.CurrentDirectory, "bin", "data-framents", "fm")))); + + // var exampleRepositorySettings = new AXOpen.Data.Json.JsonRepositorySettings( @@ -59,6 +70,20 @@ public static void Main(string[] args) Entry.Plc.AxoDataExamplesDocu.DataManager.InitializeRemoteDataExchange(exampleRepository); // + + // + + var scatteredDataBuilder = + Entry.Plc.AxoDataFragmentExchangeContext.ProcessData.CreateBuilder(); + + // Setting up repositories + scatteredDataBuilder.SharedHeader.SetRepository(new JsonRepository( + new AXOpen.Data.Json.JsonRepositorySettings(Path.Combine(Environment.CurrentDirectory, "bin", "data-framents-docu", "set")))); + scatteredDataBuilder.Station_1.SetRepository( + new JsonRepository( + new AXOpen.Data.Json.JsonRepositorySettings(Path.Combine(Environment.CurrentDirectory, "bin", "data-framents", "fm")))); + // + var app = builder.Build(); // Configure the HTTP request pipeline. diff --git a/src/integrations/src/AXOpen.Integrations.Blazor/Shared/NavMenu.razor b/src/integrations/src/AXOpen.Integrations.Blazor/Shared/NavMenu.razor index 89ee2b396..bc8f94335 100644 --- a/src/integrations/src/AXOpen.Integrations.Blazor/Shared/NavMenu.razor +++ b/src/integrations/src/AXOpen.Integrations.Blazor/Shared/NavMenu.razor @@ -73,6 +73,12 @@ AxoDataRemote + +