diff --git a/Docs/Tutorials/BookClub_walkthrough/08_Using_custom_widgets_and_data_types_in_the_model.md b/Docs/Tutorials/BookClub_walkthrough/08_Using_custom_widgets_and_data_types_in_the_model.md
index 5ee1923d7..4c601eb51 100644
--- a/Docs/Tutorials/BookClub_walkthrough/08_Using_custom_widgets_and_data_types_in_the_model.md
+++ b/Docs/Tutorials/BookClub_walkthrough/08_Using_custom_widgets_and_data_types_in_the_model.md
@@ -1,3 +1,7 @@
# Using custom widget and data types in the model
+TODO
+
+[Click here to get to the second PowerUI Tutorial 'Stock Overview'](../Stock_Overview/english/index.md)
+
[
BookClub tutorial
](index.md) [
< Previous
](07_CRUD_UIs_for_complex_objects.md) [
Next >
](07_CRUD_UIs_for_complex_objects.md)
\ No newline at end of file
diff --git a/Docs/Tutorials/Stock_Overview/Images/02_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/02_Image_1.png
new file mode 100644
index 000000000..90756657b
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/02_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/03_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/03_Image_1.png
new file mode 100644
index 000000000..aec8e7d7f
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/03_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/03_Image_2.png b/Docs/Tutorials/Stock_Overview/Images/03_Image_2.png
new file mode 100644
index 000000000..58f241970
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/03_Image_2.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/03_Image_3.png b/Docs/Tutorials/Stock_Overview/Images/03_Image_3.png
new file mode 100644
index 000000000..88eb98f66
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/03_Image_3.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/03_Image_4.png b/Docs/Tutorials/Stock_Overview/Images/03_Image_4.png
new file mode 100644
index 000000000..25ee48b71
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/03_Image_4.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/03_Image_5.png b/Docs/Tutorials/Stock_Overview/Images/03_Image_5.png
new file mode 100644
index 000000000..412ede437
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/03_Image_5.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/03_Image_6.png b/Docs/Tutorials/Stock_Overview/Images/03_Image_6.png
new file mode 100644
index 000000000..11527bf66
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/03_Image_6.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/03_Image_7.png b/Docs/Tutorials/Stock_Overview/Images/03_Image_7.png
new file mode 100644
index 000000000..d9484d9a1
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/03_Image_7.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/04_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/04_Image_1.png
new file mode 100644
index 000000000..d0fc1096f
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/04_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/04_Image_2.png b/Docs/Tutorials/Stock_Overview/Images/04_Image_2.png
new file mode 100644
index 000000000..48288c376
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/04_Image_2.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/04_Image_3.png b/Docs/Tutorials/Stock_Overview/Images/04_Image_3.png
new file mode 100644
index 000000000..6d2740429
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/04_Image_3.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/04_Image_4.png b/Docs/Tutorials/Stock_Overview/Images/04_Image_4.png
new file mode 100644
index 000000000..c851b9961
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/04_Image_4.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/04_Image_5.png b/Docs/Tutorials/Stock_Overview/Images/04_Image_5.png
new file mode 100644
index 000000000..87c711065
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/04_Image_5.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/04_Image_6.png b/Docs/Tutorials/Stock_Overview/Images/04_Image_6.png
new file mode 100644
index 000000000..7904f5fc3
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/04_Image_6.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/04_Image_7.png b/Docs/Tutorials/Stock_Overview/Images/04_Image_7.png
new file mode 100644
index 000000000..9dc324b36
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/04_Image_7.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/05_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/05_Image_1.png
new file mode 100644
index 000000000..e72788a0a
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/05_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/05_Image_2.png b/Docs/Tutorials/Stock_Overview/Images/05_Image_2.png
new file mode 100644
index 000000000..eb452533a
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/05_Image_2.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/05_Image_3.png b/Docs/Tutorials/Stock_Overview/Images/05_Image_3.png
new file mode 100644
index 000000000..e137fd4e8
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/05_Image_3.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/05_Image_4.png b/Docs/Tutorials/Stock_Overview/Images/05_Image_4.png
new file mode 100644
index 000000000..507244357
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/05_Image_4.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/05_Image_5.png b/Docs/Tutorials/Stock_Overview/Images/05_Image_5.png
new file mode 100644
index 000000000..8c404fe5d
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/05_Image_5.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/05_Image_6.png b/Docs/Tutorials/Stock_Overview/Images/05_Image_6.png
new file mode 100644
index 000000000..829e7a556
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/05_Image_6.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_1.png
new file mode 100644
index 000000000..0938b8905
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_10.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_10.png
new file mode 100644
index 000000000..6e13e49d1
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_10.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_11.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_11.png
new file mode 100644
index 000000000..c7de83ccc
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_11.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_12.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_12.png
new file mode 100644
index 000000000..847ea1b2b
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_12.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_13.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_13.png
new file mode 100644
index 000000000..7608b9018
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_13.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_14.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_14.png
new file mode 100644
index 000000000..77613fec4
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_14.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_15.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_15.png
new file mode 100644
index 000000000..ea3a5297f
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_15.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_16.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_16.png
new file mode 100644
index 000000000..a60f1815a
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_16.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_17.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_17.png
new file mode 100644
index 000000000..30e76a548
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_17.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_18.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_18.png
new file mode 100644
index 000000000..90756657b
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_18.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_19.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_19.png
new file mode 100644
index 000000000..dc01d65e0
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_19.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_2.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_2.png
new file mode 100644
index 000000000..138901619
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_2.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_20.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_20.png
new file mode 100644
index 000000000..1e20b1165
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_20.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_3.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_3.png
new file mode 100644
index 000000000..159ac5950
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_3.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_4.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_4.png
new file mode 100644
index 000000000..231f6e46a
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_4.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_5.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_5.png
new file mode 100644
index 000000000..0c01b8a5d
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_5.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_6.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_6.png
new file mode 100644
index 000000000..deef726f6
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_6.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_7.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_7.png
new file mode 100644
index 000000000..873f152b7
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_7.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_8.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_8.png
new file mode 100644
index 000000000..5bf53e91d
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_8.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/06_Image_9.png b/Docs/Tutorials/Stock_Overview/Images/06_Image_9.png
new file mode 100644
index 000000000..d047b7f3b
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/06_Image_9.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_1.png
new file mode 100644
index 000000000..5d645b2ac
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_10.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_10.png
new file mode 100644
index 000000000..02ad204c3
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_10.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_11.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_11.png
new file mode 100644
index 000000000..1648a854a
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_11.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_2.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_2.png
new file mode 100644
index 000000000..b833d1683
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_2.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_3.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_3.png
new file mode 100644
index 000000000..498525d2c
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_3.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_4.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_4.png
new file mode 100644
index 000000000..ece880081
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_4.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_5.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_5.png
new file mode 100644
index 000000000..08e0fe3fe
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_5.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_6.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_6.png
new file mode 100644
index 000000000..0df2041f1
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_6.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_7.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_7.png
new file mode 100644
index 000000000..1d4f74017
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_7.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_8.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_8.png
new file mode 100644
index 000000000..ecbe6c4ab
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_8.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/07_Image_9.png b/Docs/Tutorials/Stock_Overview/Images/07_Image_9.png
new file mode 100644
index 000000000..3e6a12191
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/07_Image_9.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/08_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/08_Image_1.png
new file mode 100644
index 000000000..dff8424fa
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/08_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/08_Image_2.png b/Docs/Tutorials/Stock_Overview/Images/08_Image_2.png
new file mode 100644
index 000000000..e6d8bca5e
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/08_Image_2.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/08_Image_3.png b/Docs/Tutorials/Stock_Overview/Images/08_Image_3.png
new file mode 100644
index 000000000..c97b7e08a
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/08_Image_3.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/08_Image_4.png b/Docs/Tutorials/Stock_Overview/Images/08_Image_4.png
new file mode 100644
index 000000000..e003101d3
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/08_Image_4.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/08_Image_5.png b/Docs/Tutorials/Stock_Overview/Images/08_Image_5.png
new file mode 100644
index 000000000..b30118697
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/08_Image_5.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/09_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/09_Image_1.png
new file mode 100644
index 000000000..8bed4da71
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/09_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/09_Image_2.png b/Docs/Tutorials/Stock_Overview/Images/09_Image_2.png
new file mode 100644
index 000000000..1911d939c
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/09_Image_2.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/09_Image_3.png b/Docs/Tutorials/Stock_Overview/Images/09_Image_3.png
new file mode 100644
index 000000000..1686cdafe
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/09_Image_3.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/10_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/10_Image_1.png
new file mode 100644
index 000000000..15794d8b9
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/10_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/10_Image_2.png b/Docs/Tutorials/Stock_Overview/Images/10_Image_2.png
new file mode 100644
index 000000000..fe57fd444
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/10_Image_2.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/10_Image_3.png b/Docs/Tutorials/Stock_Overview/Images/10_Image_3.png
new file mode 100644
index 000000000..2f71a92bc
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/10_Image_3.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/11_Image_1.png b/Docs/Tutorials/Stock_Overview/Images/11_Image_1.png
new file mode 100644
index 000000000..330be6156
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/11_Image_1.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/11_Image_2.png b/Docs/Tutorials/Stock_Overview/Images/11_Image_2.png
new file mode 100644
index 000000000..36253faa9
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/11_Image_2.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/11_Image_3.png b/Docs/Tutorials/Stock_Overview/Images/11_Image_3.png
new file mode 100644
index 000000000..26268ce76
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/11_Image_3.png differ
diff --git a/Docs/Tutorials/Stock_Overview/Images/11_Image_4.png b/Docs/Tutorials/Stock_Overview/Images/11_Image_4.png
new file mode 100644
index 000000000..9e027a966
Binary files /dev/null and b/Docs/Tutorials/Stock_Overview/Images/11_Image_4.png differ
diff --git a/Docs/Tutorials/Stock_Overview/english/01_What_to_expect_from_this_tutorial.md b/Docs/Tutorials/Stock_Overview/english/01_What_to_expect_from_this_tutorial.md
new file mode 100644
index 000000000..4d4264153
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/01_What_to_expect_from_this_tutorial.md
@@ -0,0 +1,45 @@
+## What to expect from this tutorial
+
+[
Stock Overview
](index.md)
< Previous
[
Next >
](02_Understanding_the_data_tables_we_will_work_with.md)
+
+
+In this tutorial, you will learn some fundamental basics for the elements PowerUI offers GUI designers. It’s recommended to read the theoretical information pages and the documentation in the 4D1 Wiki. This tutorial requires access to the PowerUI Spielwiese: [Home](https://sdrexf2.salt-solutions.de/powerui-spielwiese/)
+
+**This tutorial will not:**
+- Explain every aspect in great detail; that’s what the Wiki pages are for.
+- Show you how PowerUI is programmed, we will not cover the core devs tasks (PHP etc.).
+- Teach you knowledge of databases, how they work, or train you in SQL.
+
+**What this tutorial will do:**
+- Show you a few more PowerUI elements than the BookClub Tutorial did.
+- Explain in a bit more detail how these elements are connected.
+- Give you practical exercises to create or adjust a page.
+- Will ask you questions here and there to activate your own thought process.
+
+The goal is to train your transfer knowledge and to show you a few more functionalities so you can recreate them, no matter what the actual input for your task is.
+
+---
+
+### Things to do before starting the PowerUI Tutorial: Stock Overview
+
+Before starting the PowerUI Tutorial: Stock Overview, make sure you have successfully finished the BookClub Tutorial. The two tutorials aren’t based on the same database, but the BookClub Tutorial establishes the basic information for data sources and data connections. Additionally, in the BookClub tutorial you will have handled some SQL – while this tutorial already has a database you won’t modify, you will need some basic SELECT statements to understand the relations between several tables.
+
+You need to have downloaded SQL Server Management Studio and have a functional connection to swusqllogbase.salt-solutions.de.
+
+The goal is to get to know more functions for PowerUI – hence, this tutorial will introduce more elements for building a graphic user interface.
+
+Mainly the following:
+- Create a page
+- Create and edit buttons (actions)
+- Table relations: Attributes and columns
+- Table relations: Filters
+- Sorters
+- Rinse & Repeat: Relations, attributes, columns and filters
+- Interacting tables
+- Behaviors
+
+---
+
+What’s the goal for the page you will create? It’s to practice implementing some more PowerUI elements and understand how they all work together. It’s advised to read these pages [Grundlegende Begriffe - 4D1 Projektwikis - Confluence](https://asgixpo.atlassian.net/wiki/spaces/4d1prjwikis/pages/966164529/Grundlegende+Begriffe) if you don’t know what to do in this tutorial at any step. The info-pages were created alongside the tutorial, so they should cover all necessary explanations to follow through with the tutorial's instructions.
+
+[
Stock Overview
](index.md)
< Previous
[
Next >
](02_Understanding_the_data_tables_we_will_work_with.md)
\ No newline at end of file
diff --git a/Docs/Tutorials/Stock_Overview/english/02_Understanding_the_data_tables_we_will_work_with.md b/Docs/Tutorials/Stock_Overview/english/02_Understanding_the_data_tables_we_will_work_with.md
new file mode 100644
index 000000000..61523259b
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/02_Understanding_the_data_tables_we_will_work_with.md
@@ -0,0 +1,67 @@
+## Understanding the data tables we’ll work with
+
+[
Stock Overview
](index.md) [
< Previous
](01_What_to_expect_from_this_tutorial.md) [
Next >
](03_create_a_page.md)
+
+We’ll be working with several tables in this tutorial. Tables that already exist in a database. It’s not necessary to know all the tables and their attributes to follow the tutorial but if you want to understand better why the following tables were chosen, you can view them under:
+
+1. `Administration > Metamodel > Connections > Select “PowerUI_SQL_Spielewiese auf swusqllogbase” > Click SQL admin and log in.`
+
+2. Or: Open your **SQL Server Management Studio** and log onto the `swusqllogbase.salt-solutions.de` server. Find the table **PowerUI_SQL_spielewiese**.
+
+Here you can see **ALL** the tables in the database. This database is a copy of the Logbase Mahle project as a playground for this tutorial.
+
+We will use the following tables and their attributes:
+
+- Quant
+- StorageBin
+- StorageArea
+- MaterialMaster
+- WarehousePosting
+
+Understanding the actual data in this tutorial will help you to understand why we’re connecting which tables. Knowing the concepts of primary and foreign keys is important – so if you have never heard of it, or feel like you need a touch up on the concepts, you can read up on them here:
+[Difference between Primary Key and Foreign Key - GeeksforGeeks](https://www.geeksforgeeks.org/difference-between-primary-key-and-foreign-key/)
+
+---
+
+For your first task, you’ll have to create a visual for the 5 tables above. Ideally, you can use Visual Studio or any other software to create a diagram with – or use a pen and paper to sketch out the relations. You will:
+
+> Create a database schema diagram for a Warehouse Management System with the following components. You'll need to identify entities, attributes, primary keys, foreign keys, and relationships between tables.
+
+### Task
+
+1. Open, as mentioned above, either the **SQL Adminer** or your **SQL Server Management Studio** and find the database.
+2. Design a database schema with the following entities:
+ - Quant
+ - StorageBin
+ - StorageArea
+ - MaterialMaster
+ - WarehousePosting
+3. For each entity, determine:
+ - Appropriate attributes
+ - Primary key(s)
+ - Foreign key(s) where applicable
+ - Relationships between entities (one‑to‑many, many‑to‑many, etc.)
+
+Your schema should address the following business rules:
+
+- Materials are stored in storage bins
+- Storage bins belong to storage areas
+- Quantities of materials (quants) are tracked in specific storage bins
+- Warehouse postings record movements between storage bins
+
+**Hint for the structure:**
+
+- Identify primary keys (denoted with **PK**)
+- Identify foreign keys (denoted with **FK**)
+- Draw relationships between tables using appropriate notation
+- Consider cardinality in your relationships (1:1, 1:N, N:M)
+
+---
+
+### Solution
+
+
+
+If your solution is a lot bigger and contains a lot more attributes than the picture above shows – you’ve done it correctly. The goal for this exercise was for you to look at the data tables more closely – which tables have which attributes? We’ll be needing only the ones in the picture above for the rest of this particular tutorial, we will circle back in other tutorials later on.
+
+[
Stock Overview
](index.md) [
< Previous
](01_What_to_expect_from_this_tutorial.md) [
Next >
](03_create_a_page.md)
\ No newline at end of file
diff --git a/Docs/Tutorials/Stock_Overview/english/03_create_a_page.md b/Docs/Tutorials/Stock_Overview/english/03_create_a_page.md
new file mode 100644
index 000000000..c21942cac
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/03_create_a_page.md
@@ -0,0 +1,75 @@
+## Create a page
+
+[
Stock Overview
](index.md) [
< Previous
](02_Understanding_the_data_tables_we_will_work_with.md) [
Next >
](04_create_and_edit_buttons_actions.md)
+
+You will not create a new App or data base. You will work with the ones already set up for the tutorial. You will create pages the same way you did in the BookClub Tutorial.
+
+### Task
+
+Navigate to `Administration > Pages` > Click on **Home** and look for the page named **„LogBase PUI Tutorial“**.
+
+
+
+That’s the main page for this tutorial. It holds the navigation tiles (click **Open Page** to see them). Underneath you’ll find several pages:
+
+1. Stock Overview Blueprint, Warehouse Order Blueprint and Material Master Blueprint. These are the example pages which showcase the end of a tutorial – once you’ve followed all the steps, your page should look like them. **This tutorial will only cover the Stock Overview Blueprint page.**
+2. Tutorial Trial Pages: If you ever want to try something without it impacting your tutorial progress, you can try that here. There’s no “undo” button in the PowerUI editors, so changing something should be done consciously.
+
+All additional pages for this tutorial go under this one. It doesn’t matter what you name your page, just make sure you’re able to identify which one is yours. You can use your SALT abbreviation.
+
+
+
+---
+
+### Task
+
+1. **Click** the **„New“** button. Either click on **“PUI Tutorial: Stock Overview Blueprint”** and then **“New”** to assign it as the new page’s parent page, or choose your parent page manually in the **Page Properties**.
+2. Give your tutorial page a name: **LogBase PUI Tutorial **
+3. Check that the **Template** is set to **SAP Fiori 3**. SAP Fiori 3 is a certain design developed by SAP. We will use it for this tutorial but there are different designs as well.
+4. Check that **„Is part of app“** is set to **LogBase Demo (Mahle)**. In this tutorial, the app we work with is **LogBase Demo (Mahle)** and we’ll only be using this. Generally, though, you’ll use different apps for different projects or modules.
+5. Check that **„In menu“** is checked, while **„Published“** is *not*. This sets your page as part of the pages menu structure but doesn’t publish it to access it outside of Administration. You can publish it once you’ve finished this tutorial.
+
+
+
+
+6. Switch to the „Widget“ tab
+7. Press the **„Use a preset for a quick start“** magic wand. We will choose a basic preset to give our page a basic structure, just like you’ve done in the BookClub Tutorial.
+
+
+
+8. Search **„Master data“** and select the preset. On the bottom‑right you can see the PowerUI (UXON) structure already as a preview. Click **„Replace“**.
+
+> **Fun Fact:** You can’t do anything wrong in this step. You’re just choosing your preset and you’re replacing what’s written in your page editor with the button **“Replace”**.
+
+
+
+
+
+---
+
+Now you have a basic page structure in your widget editor. The highest level of the pages hierarchy is Content. It contains the basic widget type for your page, in this case a data table because a table is what we want to showcase, and the object_alias.
+
+The **object_alias** is the reference to an object, hence to a data table that’s located in our data base. Basically, the **object_alias** tells PowerUI: „There’s a table with columns and rows, and data, and its name is and here’s an alias so you can reference it and know which app it belongs to.“ Without an object_alias PowerUI can’t build your page as it simply doesn’t know what you want.
+
+For more information on a general structure of a page, look here: [Struktur einer Page - 4D1 Projektwikis - Confluence](https://asgixpo.atlassian.net/wiki/spaces/4d1prjwikis/pages/968261637/Struktur+einer+Page)
+
+To assign an `object_alias` you always need to know:
+
+- **Which app** does the object I want to use for my page belong to? In this tutorial it’s always **logbase.DemoM** (the alias of the app).
+- **Which object** do I want to use? Since the objects are the tables in our database, you always want to know your data before building a page.
+- **What’s the object’s alias?** As you need to know how to reference the object you want. To check an object’s name, alias, attributes or app, you can view them under `Administration > Metamodel > Objects`.
+
+As we’re working with the widget **DataTable** to show a data table on our page, we have to set the values for the other properties that such a table has – namely, **columns** and **buttons**, as you can see in the preset. For more details on buttons, click [here](https://asgixpo.atlassian.net/wiki/spaces/4d1prjwikis/pages/971964422/Actions+Events+Behaviors).
+
+Otherwise, let’s move on to the buttons you will create and edit. So, for now: your `object_alias` for the main widget of this page follows the **AppAlias.ObjectAlias** format:
+
+**Logbase.DemoM.Quant:** Quant is the name of the table we’ll be working with first.
+
+9. Set the value of your object_alias to logbase.DemoM.Quant.
+10. Click save and open your page via the Open Page button.
+
+It should look like this:
+
+
+
+[
Stock Overview
](index.md) [
< Previous
](02_Understanding_the_data_tables_we_will_work_with.md) [
Next >
](04_create_and_edit_buttons_actions.md)
\ No newline at end of file
diff --git a/Docs/Tutorials/Stock_Overview/english/04_create_and_edit_buttons_actions.md b/Docs/Tutorials/Stock_Overview/english/04_create_and_edit_buttons_actions.md
new file mode 100644
index 000000000..e83e62b0b
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/04_create_and_edit_buttons_actions.md
@@ -0,0 +1,115 @@
+## Create and edit buttons (actions)
+
+[
Stock Overview
](index.md) [
< Previous
](03_create_a_page.md) [
Next >
](05_input_mappers.md)
+
+A button always executes an action upon clicking on it. For more information on how actions work, click **[here](https://asgixpo.atlassian.net/wiki/spaces/4d1prjwikis/pages/971964422/Actions+Events+Behaviors)**.
+An executed action can do many things, prototyped or customized. All action prototypes can be found **[here](https://sdrexf2.salt-solutions.de/powerui-spielwiese/exface.core.docs-action-prototypes.html)**.
+They work with any buttons in any apps. Customized actions on the other hand are called **Object Actions** and only work with the app the object belongs to.
+
+Since every button calls an action, and an action is built and defined through PowerUI, you need an `action_alias` to call it.
+For this tutorial, if you use an **Action Prototype**, use `exface.Core` as the app alias, followed by the name of the action.
+For every custom-made action, use the name of the tutorial app, `logbase.DemoM`, and the name of the action.
+
+The following 4 basic buttons are **Action Prototypes** and part of the preset we chose. They are often used for all sorts of pages:
+
+- **ShowObjectCreateDialog**: Displays the „New“ button & creates a dialog window to add new data to your table.
+- **ShowObjectEditDialog**: Displays the „Edit“ button & creates a dialog in which you can edit existing data.
+- **ShowObjectCopyDialog**: Displays the „Copy“ button & creates a copy dialog of your data (you can edit it or not and then save it as a new entry to your table).
+- **DeleteObject**: Displays the „Delete“ button – **Notice:** Always be careful to press this one, you will **NOT** be asked if you’re sure you want to delete data; it will directly do so. Because of this, the Delete button is hidden by default in the three-points menu.
+
+
+
+---
+
+### Task
+
+Open your page to look at how the buttons are positioned. Their design, color, spacing etc. come from the SAP Fiori 3 design of the page.
+A button can have a **visibility**: *normal*, *promoted*, *optional* and *hidden*. *Normal* shows you the same button without a visibility set.
+
+1. **Set the visibility for a button to promoted and save. What does the button do?**
+ a. Sits higher up in the header
+ b. Has a blue-colored background to be more visible
+
+2. **Why can’t you see the Delete button even though it’s defined in PowerUI?**
+ a. Because the value is set to *optional* which moves the button into the drop-down menu.
+ b. Because the button has no explicit visibility parameter defined, which means it inherits the *hidden* default value from the core configuration.
+
+3. **Set the visibility of the button to optional and save. What does the button do?**
+ a. Is grey and can no longer be clicked
+ b. Is hidden under the three-dots drop-down menu
+
+
+
+Using preset buttons is convenient. The buttons themselves should always work and create a dialog to either create a new set of data or edit or delete an old one.
+It gets interesting when you start customizing your buttons. Before you continue in this tutorial, be sure to read the following page:
+*[Actions / Events / Behaviors - 4D1 Projektwikis - Confluence](https://asgixpo.atlassian.net/wiki/spaces/4d1prjwikis/pages/971964422/Actions+Events+Behaviors)*
+
+We will build a button that upon clicking on it, will open a dialog to change the status of the column **Blocked Stocktaking** in our table **Stock Overview (Quant)**.
+As of now you should either see nothing in the column, or you can see a check mark. The check mark means the stock is blocked; no check mark means it can be used.
+
+
+
+Before you wonder: Yes, the option to change this already exists in the generic **Edit** button.
+For the sake of this tutorial, we will create another one though that looks different and just offers the option to change the **Blocked Stocktaking** values.
+
+To create a custom button, you always need to create an **object action**.
+**Notice:** This tutorial will be done by more than one person. Creating an action only has to be done once before you can continue to use it.
+This means that the same name and alias of an action cannot be used twice. Please choose a name and an alias freely in the following task so the action you create does not have the same name as another.
+
+---
+
+### Task
+
+1. Navigate to `Administration > Metamodel > Objects > Object Actions`
+2. Click **“New”**
+3. As you can see, you need a name (can be chosen freely), an alias (can be chosen freely, can’t contain spaces between words), an action prototype and an app.
+ - **Name:** choose freely (the name has no technical meaning and can have spaces)
+ - **Alias:** choose but don’t add spaces or underscores as this is what PowerUI needs to reference your action
+ - **Action prototype:** `ShowObjectEditDialog` (we want to show something from the object and be able to change it)
+ - **Is part of app:** **LogBase Demo (Mahle)** [`logbase.DemoM`]
+ - **Belongs to object:** **Quant** [`logbase.DemoM.Quant`]
+
+
+
+The functionality of a button is always defined in an action, and not in the page you want to use it with.
+You can define the button in the **Action configuration editor**.
+
+#### Task
+
+1. We want to set the minimum number of records that must be selected for this action to be executed. This prevents the action from being triggered if no data is selected. Append a `field : value` pair:
+ - `input_rows_min : 1`
+
+2. Then we want to set the maximum to limit the number of records that can be processed at a time. Append a `field : value` pair:
+ - `input_rows_max : 1`
+
+3. Lastly, we want to assign an icon to our button. There’s an icon library you can access freely **here** or use the one for our example: `sap-icon://accounting-document-verification`. Append a `field : value` pair:
+ - `icon : sap-icon://accounting-document-verification`
+
+Your first block of UXON should look like this:
+
+
+
+
+4. Next, we want to choose what sort of result and format we want when the action is executed, hence the button is pressed. Append an object underneath in the namespace. Assign `dialog` to it.
+
+
+
+5. Append six `field : value` pairs beneath:
+ - `height : auto`→ This is the default value for height. If you don’t add any specification for height, this is what PUI will use. You don’t even need to use height at all if the automatically calculated one suits your taste.
+ - `width : 1` → Sets the width of the dialog.
+ - `columns_in_grid : 1` → Tells the dialog how many columns we want shown.
+ - `maximized : false` → Minimizes the dialog.
+ - `caption : Check Blocked Stock` → Gives the dialog a name.
+
+6. In the namespace of the dialog, we want to define a widget. Append an array and name it `widgets`. Append an object space on the next line and append another three `field : value` pairs underneath.
+ - `widget_type : InputCheckBox`
+ - `attribute_alias : BlockedStocktaking`
+ - `caption : Stock`
+
+Your UXON should look like this:
+
+
+
+As a next step, we will build a button that triggers an action chain and uses an input mapper to update our data.
+
+[
Stock Overview
](index.md) [
< Previous
](03_create_a_page.md) [
Next >
](05_input_mappers.md)
diff --git a/Docs/Tutorials/Stock_Overview/english/05_input_mappers.md b/Docs/Tutorials/Stock_Overview/english/05_input_mappers.md
new file mode 100644
index 000000000..9eabcdcf3
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/05_input_mappers.md
@@ -0,0 +1,151 @@
+## Input Mappers
+
+[
Stock Overview
](index.md) [
< Previous
](04_create_and_edit_buttons_actions.md) [
Next >
](06_table_relations_attributes_and_columns.md)
+
+In PowerUI, buttons function as the main interface for users to initiate actions within the system. They are essential components that provide clear visual elements for users to click when they want to start an operation.
+Buttons act as containers for the actions that need to be executed upon interaction, while also carrying the context of which data should be affected by those actions.
+Additionally, they can display loading states or other visual feedback during action execution, giving users important information about the status of their requested operations.
+This makes buttons both functional triggers and informative elements within the PowerUI interface. In our example, the button is configured with three properties to make it stand out in the interface and position it appropriately.
+
+### Task
+
+1. Append an array on the same level underneath `widgets`. Name it `buttons`.
+2. Append an object and 3 `field : value` pairs:
+ - Promote the button’s visibility → Remember how you set the visibility of the other buttons earlier.
+ - Align the new button we’re building to the opposite → `align : opposite`
+ - Name the button “Save” → Give it a `caption` to do so.
+3. Append another object inside the prior object space and name it `action`.
+
+
+
+4. The appended object should already come with a `field : value` pair. We’ll assign it an `action_alias` but this time it is not done on one line as usual because the **ActionChain** function is more complex.
+ - `alias : exface.core.ActionChain`
+
+---
+
+#### What is an ActionChain?
+
+ActionChain is a feature in PowerUI that allows you to:
+
+1. **Sequence Multiple Actions:** Execute multiple actions in a specific order
+2. **Control Flow:** Add conditional logic to determine which actions should run
+3. **Data Passing:** Pass data between different actions in the chain
+4. **Reusability:** Create reusable sequences of operations
+
+The ActionChain in our example contains just one action (`UpdateData`), but in more complex scenarios, you could add multiple actions like:
+
+- Showing a confirmation dialog
+- Validating data
+- Updating multiple related data objects
+- Refreshing data after update
+- Navigating to another page
+
+ActionChains are particularly valuable when you need to perform a series of operations that depend on each other, all triggered by a single user interaction.
+
+---
+
+### Task
+
+1. Append a new array inside the `action` object space you just created.
+2. Assign it `actions`, append another object and two more `field : value` pairs.
+ - The first value pair is the name of the action `alias : exface.core.UpdateData`
+ - The second value pair is the `object_alias` we want to reference: `logbase.DemoM.Quant`
+
+
+
+---
+
+#### What is UpdateData?
+
+`UpdateData` is one of the core actions in PowerUI that enables data modification. It's responsible for:
+
+1. Database Interactions: It handles the actual updating of records in your database
+2. Data Validation: It often performs validation before committing changes
+3. Error Handling: It manages potential errors during the update process
+4. Transaction Management: It ensures data integrity through proper transaction handling
+
+The `UpdateData` action requires:
+
+- An `object_alias` to identify which data object to update
+- An `input_mapper` to determine how to map input data to the target object's fields
+
+This makes it perfect for operations like saving form data, changing status fields, or updating any database records. In this PowerUI example, we need an ActionChain and UpdateData to execute the **“BlockedStocktaking”** verification because the ActionChain provides the structural framework to sequence multiple potential operations, while the UpdateData action specifically handles the database interaction required to persist the BlockedStocktaking status change, ensuring the data is properly validated and committed to the database with precise control over which field is updated.
+
+---
+
+Input mappers are a feature in PowerUI that establish connections between different data objects in your application. They define how data should flow from one object to another, making it possible to:
+
+- Update multiple data sources simultaneously
+- Transform data as it moves between objects
+- Maintain data consistency across your application
+
+Think of Input Mappers as intelligent bridges that not only connect data objects but also know how to translate information between them.
+
+#### When to Use Input Mappers
+
+Input Mappers are particularly useful when:
+
+1. You need to update data in a database from form inputs
+2. You want to synchronize data between different parts of your application
+3. You need to transform data formats between systems
+4. You're building action chains that process and update information
+
+Our input mapper consists of the following key components:
+
+1. `from_object_alias`: The source object that provides the data (in our example, `logbase.DemoM.Quant`)
+2. `to_object_alias`: The destination object that receives the data (also `logbase.DemoM.Quant` in our example)
+3. `inherit_columns`: Defines which columns to include in the mapping
+ - `own_attributes` means to include only columns that belong directly to the object
+4. `column_to_column_mappings`: Specific field mappings between source and destination
+ - Each mapping defines which field from the source maps to which field in the destination
+
+As you might have noticed: Our source and destination are the very same object **Quant**. In this particular case, the Input Mapper is being used for a very specific purpose.
+
+Here's why the input mapper is necessary:
+
+1. **Targeted Update Scope:** Even though the source (`from_object_alias`) and destination (`to_object_alias`) are the same object (`logbase.DemoM.Quant`), the Input Mapper is explicitly defining which field should be updated – only the **BlockedStocktaking** field. This prevents unintended updates to other fields in the object.
+2. **Data Transformation Control:** By using `inherit_columns : own_attributes` and specifically mapping only the **BlockedStocktaking** field, it’s ensured that:
+ - Only fields that directly belong to the object are considered
+ - Only the **BlockedStocktaking** field will actually be updated
+3. **User Interface to Data Connection:** Our input mapper takes the current value of **BlockedStocktaking** from the UI (where a user might have changed it) and ensures that a specific value gets saved back to the database.
+4. **Validation and Processing:** The input mapper also provides a hook where validation or transformation of the data can occur before it's committed to the database.
+
+Without the input mapper, an `UpdateData` action might try to update all fields from the UI to the database, which in this case, we don’t want. So even in this seemingly simple case where we're mapping a field to itself on the same object, the input mapper allows for control over exactly what gets updated and how the data flows between the UI and the database.
+
+---
+
+### Task
+
+1. Inside the `actions` array object, append another object and name it `input_mapper`. You’ll need 3 `field : value` pairs underneath.
+ - `from_object_alias : logbase.DemoM.Quant`
+ - `to_object_alias : logbase.DemoM.Quant`
+ - `inherit_columns : own_attributes`
+2. Inside the object space, append an array and call it `column_to_column_mappings`. Append an object and give it 2 more `field : value` pairs.
+ - `from : BlockedStocktaking`
+ - `to : BlockedStocktaking`
+3. Click **Save**.
+
+
+
+4. Navigate back to `Administration > Pages > Your page` and inside the `buttons` array space, append another object and one `field : value` pair (the pair should appear automatically). Name the object `action_alias` and assign it the action you just created. You’ll need your action’s alias for that.
+5. Give it a `caption : `.
+6. Click **Save**.
+
+**Note:** In this screenshot, obviously the action you’ve just created doesn’t show up.
+
+
+
+---
+
+As you can see below, you now have a **Button**.
+
+
+
+### Task
+
+1. Test your button! Select a data row and click your button.
+2. The following dialog should open. Change the stock, click **Save** and check if your stock status indeed changed in your data table.
+
+
+
+[
Stock Overview
](index.md) [
< Previous
](04_create_and_edit_buttons_actions.md) [
Next >
](06_table_relations_attributes_and_columns.md)
diff --git a/Docs/Tutorials/Stock_Overview/english/06_table_relations_attributes_and_columns.md b/Docs/Tutorials/Stock_Overview/english/06_table_relations_attributes_and_columns.md
new file mode 100644
index 000000000..892e78cd4
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/06_table_relations_attributes_and_columns.md
@@ -0,0 +1,182 @@
+##Table relations: Attributes and columns
+
+[
Stock Overview
](index.md) [
< Previous
](05_input_mappers.md) [
Next >
](07_table_relations_filters.md)
+
+The goal for our page is not just to show one single table – we want two tables on one page, that have a relation with one another. Relations between tables and their attributes are some of the most important concepts to handle PowerUI efficiently. To show two tables on one page we need mainly two things:
+
+1. Another table to show, in our case the name of the table is WarehousePosting. Don’t forget: A table in our database refers to the object we need in PowerUI.
+2. A new widget_type.
+ a. Task: Go to Administration > Documentation > Widgets. In the field Name you can search for names or key words of widgets.
+ b. Find a widget that will split our page and align our tables vertically (one on top, one on the bottom. Try searching the words “split” or “vertical”).
+
+The highest level of a page always needs an object for reference. So, the structure of widget_type und object_alias stays the same as before but we’ll change DataTable to the new widget_type: SplitVertical. We do need to let the page know again though that we’re working with a data table, and we’ll do that by introducing panels. They’re containers that help us group widgets.
+
+###Task:
+
+1. Go back to your page. Change “DataTable” to “SplitVertical”
+2. On the line “columns” insert an Array. Name it panel.
+3. Append an object inside the panels array, then append (without choosing a type) inside the object.
+
+
+
+4. The field name is height and its value is 50%.
+5. Append another array under height and chose “widgets”. Append another object and append several field : value pairs. Remember that we still want to show a DataTable based on our object Quant. Fill them as follows:
+ a. Caption: let’s call the table Stock Overview on our page.
+ b. Widget type > Which one did we use before to show a table?
+ c. Object alias > Which table to we want?
+ d. The ability to hide the header of the page.
+ e. Save your page.
+
+**Solution:**
+
+
+
+**Notice:** You don’t need to add the numbers inside the braces. Those are automatic counts for the number of elements.
+
+###Task:
+
+As you’ve probably noticed, PowerUI follows a hierarchical structure: Everything under object_alias > panels > widgets applies to the referenced object above.
+
+1. Move columns and buttons inside the widgets space of the panels.
+2. Click Save.
+
+**Notice:** Only some hierarchy levels show the name of your arrays – you need to find a level that displays them: Align them with hide_header. Do so by hovering over the 6 squares and drag everything to the right.
+
+
+
+
+
+1. Table heights:
+ a. Set height to 20 %: What happens to the table?
+ i. The table Quant takes up 20 % of the pages space.
+ ii. So far nothing happens as the page only shows one table.
+2. Hide header:
+ a. Set hide header to true (check the box): What happens on the page?
+ i. The header appears on the bottom.
+ ii. The header on top disappears.
+3. Before moving on, set height back to 50% and hide_header to false.
+
+Height tells the referenced table how much space of the page it can occupy. Hide header hides the header on top of the page, including for example filters. These two functionalities are self-explanatory as they simply do exactly as their names suggest.
+
+As you can see, we follow the same logic as before: We need a **widget_type** and an **object_alias**. The line “caption” defines a name for our table – before, PowerUI simply used the name of the data table (Quant). That’s what PowerUI does for everything: You can assign a caption to buttons, filters, tables etc. and if you don’t, the default name of the object is used. It’s up to you to decide what’s user-friendly in your user interface.
+
+To work with the SplitVertical widget we need to leave the hierarchy again. To work with relations between several objects we established a page that so far shows one table – but we want two. The second table we want to use is called **WarehousePosting**. As the second table we want to introduce is also supposed to be part of the panels, it needs to go inside their name space.
+
+###Task:
+
+1. Klick “append” on the square left to “panels” to add another field : value pair and align it until it looks as follows. You can click on the arrows to close the drop-down view for better readability.
+
+
+
+2. Type “widgets” into field and click on it in the drop-down menu when it opens or use the tab key on your keyboard. Notice that the following structure opens automatically.
+
+
+
+As we want to reference a second table (WarehousePosting), we again need to tell PowerUI. To do so, we need two things.
+
+1. How do we reference an object/table? [object_alias : logbase.DemoM.WarehousePosting]
+2. How do we tell the page and PowerUI what kind of widget we want for our table? [widget_type : DataTable]
+3. Additionally, for this specific table we also want to name it something. How? [caption : Warehouse Posting]
+
+To demonstrate what else we need when working with two tables, check again that you have the following lines. Notice: We disabled the line hide header with the two backslashes in front. If you ever want to disable a line being executed in your page without removing it, you can use //.
+
+
+
+4. Click save and open your page. What do you see? What error message is shown? Click on “Details”.
+
+
+
+
+This is shown as we haven’t specified what of the second table we want to see. As you might have noticed, in the widget space for our first table we specified to show the attribute_group_alias as ~VISIBLE, but we haven’t specified any attributes for our second table yet.
+
+###Task:
+
+1. Go back to your page. Duplicate the columns section (click on the square menu left and click Duplicate) and drag the duplicate down inside the second widget space.
+2. Be sure to remove the (copy) text before clicking save again.
+3. Open your page again: What happens now? You get an error message that the SQL query failed. Since we’re working with MySQL, the column “User” causes troubles because USER is a reserved keyword in MySQL.
+
+
+
+To fix this, we will now change the shown attributes of the objects, hence the columns of the tables. We don’t really just want to show all the columns of the two tables – we want them specifically sorted and we don’t really need to see all of them anyway.
+
+###Task:
+
+1. Go back to your page. Remove **attribute_group_alias** in the columns section of the table Quant and replace it with **attribute_alias**. We no longer want to group anything. Chose the names of the attributes we want to show:
+
+
+
+
+2. Click save and see how your table changes. Now only the columns we want are displayed.
+3. Scroll to the second table WarehousePosting and do the same:
+
+
+
+4. Click save and open your page. You’ll notice that the error message no longer pops up.
+
+
+
+As we want to understand how exactly relations between tables work in favor for building GUIs with PowerUI, and those few columns per table look a bit lonely, we’ll add some more but not just generic ones. We want to show the additional column “name” from the table StorageArea, which looks like this (you can check in SSMS or the SQL Adminer):
+
+
+
+But no, we won’t be introducing another third, full table to do so.
+
+**Notice:** If you try to map the attribute “name” directly, PowerUI won’t know what you want because so far, the tables we’ve introduced in our widgets are called Quant and WarehousePosting, and neither have an attribute “name”. As you can see in the screenshot below, simply adding another attribute won’t do. This is where mapping the relations of the tables comes into play.
+
+
+
+
+To generally do the following, you need to understand the underlying data base you work with. In our case that’s the data base PowerUI_SQL_Spielewiese. Start your SSMS and select the tables Quant, StorageBin and StorageArea.
+
+USE **PowerUI_SQL_Spielewiese**
+SELECT * FROM Quant
+SELECT * FROM StorageBin
+SELECT * FROM StorageArea
+
+**Or open the SQL Admin as mentioned above.**
+
+Since we want an attribute of a table our main underlying table Quant has no access to, we’ll get there by mapping the connections between Quant and StorageBin, and StorageBin and StorageArea. As you can see in the tables, Quant has a StorageBinId – which is the same as the Id column in the table StorageBin. And StorageBin has another column called StorageAreaId, which is the same as the Id column in the table StorageArea.
+
+
+
+And lastly, we follow the usual logic of an attribute_alias and call the name of the attribute we want (in this case, also Name). PowerUI can follow this “path” of connections as follows:
+
+
+
+As you can see, there’s two underscores between everything we want to connect, quite like a visual path. Your main table is already referenced above in the object_alias, which is why you don’t have to mention it every time again in a relation path that’s inside its hierarchy level.
+
+###Task:
+
+1. Go to your page. Add another object in columns and assign it the attribute alias **StorageBin__StorageArea__Name** and give it a caption.
+2. Save.
+
+Next, we want to add two more columns to our table (Quant) that also come from a different source table. We’ll again be using their relation paths to showcase them in our UI:
+
+2. The column should be captioned “Material”.
+ a. You need to map over the table: MaterialMaster (select it in SSMS or SQL Admin to take a look at its attributes and understand their Primary and Foreign Keys)
+ b. You need the attribute: Name
+3. The column should be named: “Material Number”
+ a. You need the table: MaterialMaster
+ b. Which attribute would you use to showcase the material number?
+**Hint:** Check the above UML to see how the tables are related.
+
+
+
+After having added these two attributes to your table, the columns we want to see are completed. You should have eight columns visible, though it doesn’t matter in which order they appear. As you might have noticed, their order changes depending on the place you wrote them in: If your first attribute_alias is Stock Quantity in UXON, then the first column you see on your page is Stock Quantity.
+
+###Task:
+
+To restructure the column order based on content, arrange them as follows:
+
+1. Storage Area
+2. Storage Bin
+3. Material
+4. Material Number
+5. Stock Quantity
+6. Availability
+7. Stock Separator Value
+8. Blocked Stocktaking
+
+Don’t forget to save your page. Before we move on to add the relations of the second table, and finally a relation between these two specific tables, we’ll add filters and sorters.
+
+[
Stock Overview
](index.md) [
< Previous
](05_input_mappers.md) [
Next >
](07_table_relations_filters.md)
diff --git a/Docs/Tutorials/Stock_Overview/english/07_table_relations_filters.md b/Docs/Tutorials/Stock_Overview/english/07_table_relations_filters.md
new file mode 100644
index 000000000..c11226eb6
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/07_table_relations_filters.md
@@ -0,0 +1,86 @@
+##Table relations: Filters
+
+[
Stock Overview
](index.md) [
< Previous
](06_table_relations_attributes_and_columns.md) [
Next >
](08_sorters.md)
+
+They’re one of the basic features our chosen preset didn’t automatically have. If you look at other presets though, you notice they’re present in a lot of them. Filters go on the same hierarchy level as buttons and columns do and belong to the same data table they go underneath of. PowerUI offers several forms of filters, most often used: A pop-up dialog one where you can choose a set of data from a table (called InputComboTable), a free-text field or a drop-down menu (called InputSelect).
+
+**Best practice:** To PowerUI, it doesn’t matter if you first define your columns, then filters and lastly your buttons. But it’s a best practice to follow the graphical user interface design and the preset recommendation: Filters go above buttons and the columns; buttons go above the columns; columns come last.
+
+Filters are elements that filter your table by a specified value. For the table Stock Overview we want five filters.
+
+1. Append an Array from your columns element and type “filters” into the field.
+
+
+
+
+
+2. On the line that currently says (empty array), append an object. Now the line underneath shows (empty array) – on that line, simply click append.
+
+
+
+Basic filters follow the same syntax as columns and buttons do: They belong to the table last referenced a higher level above, need an attribute_alias and can be given a caption.
+
+**Remember:** The attribute_alias is the name of the object you want the filter to work with. The attribute_alias logic follows the same relations we used for our columns. Let’s build the following five filters:
+
+1. Storage Bin
+2. Availability
+3. Storage Area: Remember that we weren’t able to map directly to the object StorageArea before in the columns. We still won’t be able to here. For this filter though we don’t want a specific attribute.
+4. Material Number: We don’t want the entire table MaterialMaster in this filter. We just want to filter for the column “number”.
+5. Material Name: We don’t want the entire table MaterialMaster in this filter. We just want to filter for the column “name”.
+
+
+
+**Notice:** Also, if you followed the tutorial line by line, you need to remove the back slashes in front of hide_header or else your filters won’t show up. Click save after adding the filters and removing the back spaces.
+
+PowerUI offers several formats for filters, so far you can see two on your page: An InputComboTable and a free-text filter. Depending on the usage, these are the ones you want but there’s a third option suitable for a different usability.
+
+The filter Availability has exactly two values: R (Reserved) and F (Free), so an entire table simply to choose one of two values would be a waste of space. And a free text filter might not be intuitive for users who don’t know what forms of available stock exists.
+
+For situations like that, you can use a drop-down filter. Depending on the data in your table, PowerUI might build your filter as a drop-down already. If not, but you want one, you can change the widget to InputSelect and work with that. Now let’s change our Availability filter to a drop-down menu. There’re several ways in PowerUI to do so, but here, we’ll use the version where we look at the data type of the attribute we want to filter as this offers the possibility to implement as many drop-down menu options as you want. First, we need to create a new Data Type we will then assign to our attribute (Availability).
+
+###Task:
+
+1. Go to Administration > Metamodel > Data Types
+2. Click “New”
+3. Choose LogBase Demo (Mahle) [logbase.DemoM] as “Is part of app” so PowerUI knows your new Data Type is for this specific App.
+4. Give your Data Type a name: Availability
+5. Give your Data Type an alias: Availability -> Don’t add any spaces between words.
+6. Choose “StringEnumDataType.php” as your Prototype. This is important as it already sets boundaries for what your Data Type can or can’t do. A String Enum is a set list of text values we will later define. String means its text, and Enum is a set list.
+7. Under Configuration, append a field : value pair: show_values : false, because we don’t want to show the values that are saved in our data table in our drop-down menu. For other use cases that might be different, but for this one, we will assign text to our values, and we want that text displayed. This is because our data table only holds “R” und “F” – and again, a person new to the project might not know what those letters stand for.
+8. Append an object on the next line and name it value. Add two more field : value pairs underneath. This is where we assign the text to our data table values. Assign “Reserved” to R and “Free” to F.
+
+
+
+9. Click save. Your new Data Type should now appear at the top of the Data Types list.
+
+
+
+10. Availability is an attribute of the object Quant. So next, we want to assign the new Data Type to Availability. Go to Administration > Metamodel > Objects > And search for Quant.
+
+
+
+11. Open it and go to its attributes tab. Open the attribute Availability.
+
+
+
+**IMPORTANT!**
+
+**Notice:** The Data Type of Availability is already set to Availability. Which is the Data Type I created when writing this tutorial. Now replace it with YOUR Availability Data Type that you created (Availability) and click save.
+
+
+
+**These 12 steps are responsible for the text you see in your column Visibility in the table quant. If not for this, the column would simply show the letters R and F, as that’s how it’s saved in your data table.** Check the table in your SSMS or the SQL Adminer if you want to see it.
+
+12. This was all in preparation to build a drop-down menu for your filter Availability. With the new data type that has very clear text values assigned, now the only thing we need to do is to tell PowerUI to show it as drop-down menu. Open your page again and navigate to your filter’s namespace.
+13. Append an object underneath the attribute_alias : Availability. Declare it as an input_widget.
+14. Append two more field : value fields underneath and specify:
+ a. widget_type : InputSelect
+ b. multi_select: true
+
+
+
+15. Click save. Now your Availability filter should look like this:
+
+
+
+[
Stock Overview
](index.md) [
< Previous
](06_table_relations_attributes_and_columns.md) [
Next >
](08_sorters.md)
\ No newline at end of file
diff --git a/Docs/Tutorials/Stock_Overview/english/08_sorters.md b/Docs/Tutorials/Stock_Overview/english/08_sorters.md
new file mode 100644
index 000000000..7887e89ec
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/08_sorters.md
@@ -0,0 +1,34 @@
+##Sorters
+
+[
Stock Overview
](index.md) [
< Previous
](07_table_relations_filters.md) [
Next >
](09_rinse_repeat_relations_attributes_columns_and_filters.md)
+
+Next, we’ll add sorters to our two tables. There are basically two kinds: The first are sorters that are automatically implemented in every table and can be opened upon clicking any column. They offer the ability to sort a column descending, ascending or by value.
+
+
+
+
+
+The second kind can be added specifically to sort a set of data by default whenever the site is open. So instead of looking like this:
+
+
+
+Your table will look like this:
+
+
+
+They’re an easy feature in PowerUI to sort values in a column however you want. In UXON, they’re on the same hierarchical level as buttons, filters and columns are. We want to add this second kind specifically to sort our columns Storage Area.
+
+##Task:
+
+1. Inside the widgets space of your Quant object, append another array and call it sorters.
+2. As all the other elements, sorters also need to be told which column they belong to. They need an attribute_alias to know what to sort. Append an object space inside the array.
+3. Append two field : value fields underneath.
+4. As mentioned above we want to sort the column Storage Area – a column not directly available in Quant. As you might remember, we used path mapping to get to it. This too, is no different for sorters.
+ a. Attribute_alias : StorageBin__StorageArea
+ b. Direction : asc
+
+**Solution:**
+
+
+
+[
Stock Overview
](index.md) [
< Previous
](07_table_relations_filters.md) [
Next >
](09_rinse_repeat_relations_attributes_columns_and_filters.md)
\ No newline at end of file
diff --git a/Docs/Tutorials/Stock_Overview/english/09_rinse_repeat_relations_attributes_columns_and_filters.md b/Docs/Tutorials/Stock_Overview/english/09_rinse_repeat_relations_attributes_columns_and_filters.md
new file mode 100644
index 000000000..3173fafbb
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/09_rinse_repeat_relations_attributes_columns_and_filters.md
@@ -0,0 +1,33 @@
+##Rinse & Repeat: Relations, attributes, columns and filters
+
+[
Stock Overview
](index.md) [
< Previous
](08_sorters.md) [
Next >
](10_interacting_tables.md)
+
+Now we’ll be adding more columns to the second table (Warehouse Posting) in the lower half of the page. So far, we have three columns: Warehouse Posting Type, From Storage Bin Name and To Storage Bin Name. We’ll be adding four more columns
+
+###Task:
+
+1. **Id:** No relation path required, but we do need to hide this column. This column is needed for the next task.
+2. **Material Number:** We want to map from the table MaterialMaster again and use its attribute number.
+3. **Material:** We want to map from the table MaterialMaster again and use its attribute name.
+4. **Lastly**, sort the material columns as the very first to show in your table.
+
+Try to add these columns by yourself before checking the answer/picture below. You’ve been shown the syntax and structure of everything before.
+
+
+
+So far, the Warehouse Posting table still looks very unorganized. We will fix that by implementing a functionality we have already learned about: Sorters.
+
+
+
+###Task:
+
+1. Go to your page and the widgets space of your object WarehousePosting.
+2. Append an array and inside an object, just like you’ve done for the other sorter. Name the array sorter and again, assign it:
+ a. Attribute_alias : [We want to sort the column Number. As before, this too is a column that does not exist in WarehousePosting and we used relation mapping to get it. Go back to Table relations: Attributes and columns and figure out how we mapped Number.]
+ b. Direction : desc
+
+
+
+5. Save your page. Now your columns are sorted by default. As you can see, this feature isn’t the most complex one while delivering a result that looks more organized and structured.
+
+[
Stock Overview
](index.md) [
< Previous
](08_sorters.md) [
Next >
](10_interacting_tables.md)
diff --git a/Docs/Tutorials/Stock_Overview/english/10_interacting_tables.md b/Docs/Tutorials/Stock_Overview/english/10_interacting_tables.md
new file mode 100644
index 000000000..5db656d6a
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/10_interacting_tables.md
@@ -0,0 +1,40 @@
+##Interacting tables
+
+[
Stock Overview
](index.md) [
< Previous
](09_rinse_repeat_relations_attributes_columns_and_filters.md) [
Next >
](11_behaviors.md)
+
+We will implement a new filter that’s imbedded in the connection of the two tables, thus causing Warehouse Posting to be **sorted accordingly to whichever data has been chosen/clicked** on in the table Stock Overview. Meaning: When a row is selected in the master table (captioned Stock Overview, actual table: Quant), the detail table (Warehouse Posting) will automatically filter to show only related records.
+
+The first thing we must do is to give the first table an id. Similarly to data inside a table, this is to unmistakenly be able to identify and reference the ENTIRE table. An id for a table is part of its properties and should be placed in the table’s widget space, as seen in the next picture:
+
+
+
+Id: SO -> When naming an id, you can be as creative as you want. You might remember having set an id column in the prior step and having set it to hidden. That was in preparation for this task. This hidden column in the table contains the id (id : SO) that will be used by the filter in the second table.
+
+###Task:
+
+1. Add a “filters” Array inside the widget space for WarehousePosting.
+2. Add an Object space underneath and map the two tables we want to connect: MaterialMaster and Quant. We don’t just want the tables themselves, we want to use the Id column we just created, so add the attribute Id at the end of your attribute_alias path.
+
+
+
+3. Add another field : value pair beneath and use the following syntax:
+ a. Value : =SO!Id -> value is the field and =SO!Id is the value.
+ i. = indicates a dynamic reference
+ ii. SO is the Id name of the first table
+ iii. ! is a separator
+ iv. Id is the attribute from the first table being referenced.
+4. Add apply_on_change : true, so the interaction between the tables happens automatically.
+5. Add hidden : true, as we don’t want to see the filter in our GUI.
+
+
+
+**Check that you have:**
+
+1. The id : SO pair in the widget space for the object Quant.
+2. The Id column in WarehousePosting, and have it set to hidden.
+3. Referenced the Id in the attribute_alias for the hidden filter in the object WarehousePosting.
+4. Given the hidden filter in your object WarehousePosting the value : =SO!Id.
+
+Once you have all those four, save your page and open it. Now click on a set of data in your top table and watch how the bottom table automatically sorts itself by the value “Material”. And that’s it, the two tables are now connected and react to each other’s values.
+
+[
Stock Overview
](index.md) [
< Previous
](09_rinse_repeat_relations_attributes_columns_and_filters.md) [
Next >
](11_behaviors.md)
\ No newline at end of file
diff --git a/Docs/Tutorials/Stock_Overview/english/11_behaviors.md b/Docs/Tutorials/Stock_Overview/english/11_behaviors.md
new file mode 100644
index 000000000..a0381a672
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/11_behaviors.md
@@ -0,0 +1,62 @@
+##Behaviors
+
+[
Stock Overview
](index.md) [
< Previous
](10_interacting_tables.md)
+
+To understand the theory behind behaviors, you can read the following Wiki page: [Actions / Events / Behaviors - 4D1 Projektwikis - Confluence](https://asgixpo.atlassian.net/wiki/spaces/4d1prjwikis/pages/971964422/Actions+Events+Behaviors)
+
+This will be the last step for this tutorial: We will create a behavior for our UXON so a certain action is prohibited: Duplicating a set of data. To view all existing behaviors, go to Administration > Metamodel > Objects > Objects behaviors. In that regard, behaviors are like actions: They have Behavior Prototypes (which you can find here [Behavior Prototypes](https://sdrexf2.salt-solutions.de/powerui-spielwiese/exface.core.docs-behavior-prototypes.html?&prefill=%7b%22meta_object_id%22:%220x11e86314af5caf7f971b0205857feb80%22,%22rows%22:%20%5b%5d%7d)) and Object Behaviors, that are specific to an object.
+
+• For every object specific behavior, you need to pick a prototype.
+• You need to name your behavior.
+• You need to choose an object for your behavior.
+• You need to decide which app the behavior belongs to.
+
+
+
+**IMPORTANT!**
+
+A behavior only has to be written once and saved, and it will always apply to the object you assign it to. So, in order to check if your behavior works, make sure to give your behavior a distinctive name. In creating this tutorial, the behavior “Prevent Duplicate Material in Bin” was already created by me – to check yours:
+
+• Give it a distinctive name.
+• Write an original error message.
+• Disable my behavior & save.
+
+###Task:
+
+1. Find the behavior “Prevent Duplicate Material in Bin”
+2. Check the Disabled field
+
+
+
+
+3. Save and close.
+4. Click “New” and as mentioned above, name your behavior.
+5. Assign it the object it belongs to: Quant
+6. Assign it to the app it belongs to: LogBase Demo (Mahle)
+7. Assign the behavior prototype: PreventDuplicatesBehavior
+
+What this behavior will do, is check if a specific material (identified by MaterialMaster) already exists in a specific storage location (StorageBin). If the system finds that this combination already exists when someone tries to create or move it, it will prevent the action and display the error message.
+
+Task:
+
+1. Append an array inside the Configuration space and name it compare_attributes, which is what we’ll need to implement the logic.
+2. Append two field : value pairs inside the array space.
+ a. 0 : StorageBin - The first attribute to compare is the “StorageBin” field
+ b. 1 : MaterialMaster – The second attribute to compare is the “MaterialMaster” field.
+3. Lastly, we’ll have to implement an error message to be shown and assign it some text:
+ a. Insert another field : value pair and drag it under 1 : MaterialMaster so it’s on the same hierarchical level as compare_attributes.
+ b. Assign it an error message: This material already exists in this storage bin! or any creative
+
+
+
+4. Press save. Open your page, choose one set of data in the first table and click “Copy”.
+5. Without changing anything, click “Save”.
+6. The error message you put in should now pop-up (in the picture below you can see mine).
+
+
+
+**Lastly:** Please make sure to go back to your behavior and disable it. If you don’t, the next person doing the tutorial won’t be able to check if their own behavior works!
+
+And that’s it! For now, that’s the end of this tutorial. Well done!
+
+[
Stock Overview
](index.md) [
< Previous
](10_interacting_tables.md)
\ No newline at end of file
diff --git a/Docs/Tutorials/Stock_Overview/english/index.md b/Docs/Tutorials/Stock_Overview/english/index.md
new file mode 100644
index 000000000..0d9b1478a
--- /dev/null
+++ b/Docs/Tutorials/Stock_Overview/english/index.md
@@ -0,0 +1,13 @@
+# Stock Overview
+
+1. [What to expect from this tutorial](01_What_to_expect_from_this_tutorial.md)
+2. [Understanding the data tables we’ll work with](02_Understanding_the_data_tables_we_will_work_with.md)
+3. [Create a page](03_create_a_page.md)
+4. [Create and edit buttons (actions)](04_create_and_edit_buttons_actions.md)
+5. [Input Mappers](05_input_mappers.md)
+6. [Table relations: Attributes and columns](06_table_relations_attributes_and_columns.md)
+7. [Table relations: Filters](07_table_relations_filters.md)
+8. [Sorters](08_sorters.md)
+9. [Rinse & Repeat: Relations, attributes, columns and filters](09_rinse_repeat_relations_attributes_columns_and_filters.md)
+10. [Interacting tables](10_interacting_tables.md)
+11. [Behaviors](11_behaviors.md)
\ No newline at end of file
diff --git a/Docs/index.md b/Docs/index.md
index e00082e2f..dce312612 100644
--- a/Docs/index.md
+++ b/Docs/index.md
@@ -1,16 +1,17 @@
# Documentation
1. [Introduction & installation](Getting_started/index.md)
-2. [Walkthrough Tutorial](Tutorials/BookClub_walkthrough/index.md)
-3. [Cookbook](Cookbook/index.md) - best recipes for common tasks
-4. [UXON syntax](UXON/index.md) - our "User eXpericnce Object Notation"
-5. [Understanding the meta model](understanding_the_metamodel/index.md)
-6. [Creating your own models](creating_metamodels/index.md)
-7. [Creating UIs](Creating_UIs/index.md)
-8. [Administration & configuration of the workbench](Administration/index.md)
-9. [Security, permissions, user roles, etc.](Security/index.md)
-10. [Installing third-party apps](installing_apps/index.md)
-11. [Publishing/deploying apps](publishing_apps/index.md)
-12. [Documenting your apps](documentation/index.md)
-13. [Developer's docs](developer_docs/index.md)
-14. [Troubleshooting](Cookbook/Troubleshooting.md)
\ No newline at end of file
+2. [First PowerUI Tutorial: BookClub Walkthrough Tutorial](Tutorials/BookClub_walkthrough/index.md)
+3. [Second PowerUI Tutorial: Stock Overview Tutorial](Tutorials/Stock_Overview/english/index.md)
+4. [Cookbook](Cookbook/index.md) - best recipes for common tasks
+5. [UXON syntax](UXON/index.md) - our "User eXpericnce Object Notation"
+6. [Understanding the meta model](understanding_the_metamodel/index.md)
+7. [Creating your own models](creating_metamodels/index.md)
+8. [Creating UIs](Creating_UIs/index.md)
+9. [Administration & configuration of the workbench](Administration/index.md)
+10. [Security, permissions, user roles, etc.](Security/index.md)
+11. [Installing third-party apps](installing_apps/index.md)
+12. [Publishing/deploying apps](publishing_apps/index.md)
+13. [Documenting your apps](documentation/index.md)
+14. [Developer's docs](developer_docs/index.md)
+15. [Troubleshooting](Cookbook/Troubleshooting.md)
\ No newline at end of file
diff --git a/Install/Sql/MsSQL/Migrations/1.26/20250318_1509_01_NEW_user_employee_id.sql b/Install/Sql/MsSQL/Migrations/1.26/20250318_1509_01_NEW_user_employee_id.sql
new file mode 100644
index 000000000..4ed3da424
--- /dev/null
+++ b/Install/Sql/MsSQL/Migrations/1.26/20250318_1509_01_NEW_user_employee_id.sql
@@ -0,0 +1,7 @@
+-- UP
+IF COL_LENGTH('dbo.exf_user','employee_id') IS NULL
+ALTER TABLE [dbo].[exf_user] ADD [employee_id] nvarchar(50) NULL;
+
+-- DOWN
+IF COL_LENGTH('dbo.exf_user','employee_id') IS NOT NULL
+ALTER TABLE [dbo].[exf_user] DROP COLUMN [employee_id];
\ No newline at end of file
diff --git a/Install/Sql/MsSQL/Migrations/1.26/20250320_0936_01_NEW_rp_role_attribute.sql b/Install/Sql/MsSQL/Migrations/1.26/20250320_0936_01_NEW_rp_role_attribute.sql
new file mode 100644
index 000000000..893d1928c
--- /dev/null
+++ b/Install/Sql/MsSQL/Migrations/1.26/20250320_0936_01_NEW_rp_role_attribute.sql
@@ -0,0 +1,21 @@
+-- UP
+
+CREATE TABLE dbo.rp_role_attribute (
+ oid BINARY(16) NOT NULL,
+ created_on DATETIME NOT NULL,
+ modified_on DATETIME NOT NULL,
+ created_by_user_oid BINARY(16) NOT NULL,
+ modified_by_user_oid BINARY(16) NOT NULL,
+ name NVARCHAR(50) COLLATE Latin1_General_CI_AI NOT NULL,
+ hint NVARCHAR(200) COLLATE Latin1_General_CI_AI NULL,
+ type NVARCHAR(50) COLLATE Latin1_General_CI_AI NOT NULL,
+ json_property NVARCHAR(50) COLLATE Latin1_General_CI_AI NOT NULL,
+ app_oid BINARY(16) NULL,
+ required tinyint NOT NULL,
+ display_order tinyint NOT NULL,
+ CONSTRAINT PK_rp_role_attribute PRIMARY KEY (oid)
+);
+
+-- DOWN
+
+-- DO NOT drop tables with potential content!
\ No newline at end of file
diff --git a/Install/Sql/MsSQL/Migrations/1.26/20252003_0912_01_NEW_rp_role.sql b/Install/Sql/MsSQL/Migrations/1.26/20252003_0912_01_NEW_rp_role.sql
new file mode 100644
index 000000000..19187f453
--- /dev/null
+++ b/Install/Sql/MsSQL/Migrations/1.26/20252003_0912_01_NEW_rp_role.sql
@@ -0,0 +1,28 @@
+-- UP
+
+CREATE TABLE dbo.rp_role (
+ oid BINARY(16) NOT NULL,
+ created_on DATETIME NOT NULL,
+ modified_on DATETIME NOT NULL,
+ created_by_user_oid BINARY(16) NOT NULL,
+ modified_by_user_oid BINARY(16) NOT NULL,
+ user_role_oid BINARY(16) NULL,
+ name NVARCHAR(50) COLLATE Latin1_General_CI_AI NOT NULL,
+ description NVARCHAR(400) COLLATE Latin1_General_CI_AI NULL,
+ external_role_alias NVARCHAR(50) COLLATE Latin1_General_CI_AI NULL,
+ external_role_name NVARCHAR(50) COLLATE Latin1_General_CI_AI NULL,
+ permissions_read NVARCHAR(max) COLLATE Latin1_General_CI_AI NULL,
+ permissions_write NVARCHAR(max) COLLATE Latin1_General_CI_AI NULL,
+ notifications NVARCHAR(max) COLLATE Latin1_General_CI_AI NULL,
+ comments NVARCHAR(max) COLLATE Latin1_General_CI_AI NULL,
+ status tinyint NOT NULL,
+ custom_attributes NVARCHAR(max) COLLATE Latin1_General_CI_AI NULL,
+ external_role_mapped_flag bit NULL,
+ external_role_sync_flag bit NULL,
+ app_oid BINARY(16) NULL,
+ CONSTRAINT PK_rp_role PRIMARY KEY (oid)
+);
+
+-- DOWN
+
+-- DO NOT drop tables with potential content!
\ No newline at end of file
diff --git a/Install/Sql/MySQL/Migrations/1.26/20250318_1509_01_NEW_user_employee_id.sql b/Install/Sql/MySQL/Migrations/1.26/20250318_1509_01_NEW_user_employee_id.sql
new file mode 100644
index 000000000..19f44518a
--- /dev/null
+++ b/Install/Sql/MySQL/Migrations/1.26/20250318_1509_01_NEW_user_employee_id.sql
@@ -0,0 +1,5 @@
+-- UP
+CALL execute_sql_on_missing_column('exf_user', 'employee_id', 'ALTER TABLE exf_user ADD COLUMN employee_id varchar(50) NULL');
+
+-- DOWN
+CALL execute_sql_on_existing_column('exf_user', 'employee_id', 'ALTER TABLE exf_user DROP COLUMN employee_id');
\ No newline at end of file
diff --git a/Install/Sql/MySQL/Migrations/1.26/20250320_0931_01_NEW_rp_role_attribute.sql b/Install/Sql/MySQL/Migrations/1.26/20250320_0931_01_NEW_rp_role_attribute.sql
new file mode 100644
index 000000000..fd7c3dc2b
--- /dev/null
+++ b/Install/Sql/MySQL/Migrations/1.26/20250320_0931_01_NEW_rp_role_attribute.sql
@@ -0,0 +1,21 @@
+-- UP
+
+CREATE TABLE IF NOT EXISTS `rp_role_attribute` (
+ `oid` binary(16) NOT NULL,
+ `created_on` datetime NOT NULL,
+ `modified_on` datetime NOT NULL,
+ `created_by_user_oid` binary(16) NOT NULL,
+ `modified_by_user_oid` binary(16) NOT NULL,
+ `name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+ `hint` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
+ `type` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+ `json_property` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+ `app_oid` binary(16) DEFAULT NULL,
+ `required` tinyint NOT NULL,
+ `display_order` tinyint DEFAULT NULL,
+ PRIMARY KEY (`oid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC;
+
+-- DOWN
+
+-- DO NOT drop tables with potential content!
\ No newline at end of file
diff --git a/Install/Sql/MySQL/Migrations/1.26/20250320_921_01_NEW_rp_roles.sql b/Install/Sql/MySQL/Migrations/1.26/20250320_921_01_NEW_rp_roles.sql
new file mode 100644
index 000000000..61cf7a817
--- /dev/null
+++ b/Install/Sql/MySQL/Migrations/1.26/20250320_921_01_NEW_rp_roles.sql
@@ -0,0 +1,28 @@
+-- UP
+
+CREATE TABLE IF NOT EXISTS `rp_role` (
+ `oid` binary(16) NOT NULL,
+ `created_on` datetime NOT NULL,
+ `modified_on` datetime NOT NULL,
+ `created_by_user_oid` binary(16) NOT NULL,
+ `modified_by_user_oid` binary(16) NOT NULL,
+ `user_role_oid` binary(16) DEFAULT NULL,
+ `name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
+ `description` varchar(400) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
+ `external_role_alias` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
+ `external_role_name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
+ `permissions_read` varchar(max) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
+ `permissions_write` varchar(max) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
+ `notifications` varchar(max) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
+ `comments` varchar(max) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
+ `status` tinyint NOT NULL,
+ `custom_attributes` varchar(max) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
+ `external_role_mapped_flag` bit DEFAULT NULL,
+ `external_role_sync_flag` bit DEFAULT NULL,
+ `app_oid` binary(16) DEFAULT NULL,
+ PRIMARY KEY (`oid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC;
+
+-- DOWN
+
+-- DO NOT drop tables with potential content!
\ No newline at end of file
diff --git a/Model/exface.Core.USER/02_OBJECT.json b/Model/exface.Core.USER/02_OBJECT.json
index 47cfb5a3f..d9366ac31 100644
--- a/Model/exface.Core.USER/02_OBJECT.json
+++ b/Model/exface.Core.USER/02_OBJECT.json
@@ -87,9 +87,9 @@
{
"_EXPORT_SUMMARY": "User [exface.Core.USER]",
"CREATED_ON": "2007-01-01 00:00:00",
- "MODIFIED_ON": "2025-01-15 18:19:53",
+ "MODIFIED_ON": "2025-03-18 14:23:15",
"CREATED_BY_USER": "0x31000000000000000000000000000000",
- "MODIFIED_BY_USER": "0x11e8fe1c902c8ebea23ee4b318306b9a",
+ "MODIFIED_BY_USER": "0x11efb9a9e2f873d6b9a9025041000001",
"UID": "0x31343400000000000000000000000000",
"READABLE_FLAG": 1,
"WRITABLE_FLAG": 1,
@@ -156,6 +156,9 @@
},
{
"attribute_alias": "POSITION"
+ },
+ {
+ "attribute_alias": "EMPLOYEE_ID"
}
]
},
diff --git a/Model/exface.Core.USER/04_ATTRIBUTE.json b/Model/exface.Core.USER/04_ATTRIBUTE.json
index 23a47c182..f705b4da4 100644
--- a/Model/exface.Core.USER/04_ATTRIBUTE.json
+++ b/Model/exface.Core.USER/04_ATTRIBUTE.json
@@ -811,6 +811,53 @@
"DEFAULT_VALUE": "",
"FIXED_VALUE": "",
"CUSTOM_DATA_TYPE": null
+ },
+ {
+ "_EXPORT_SUMMARY": "Employee ID [EMPLOYEE_ID]",
+ "CREATED_ON": "2025-03-18 14:22:30",
+ "MODIFIED_ON": "2025-03-18 14:23:01",
+ "CREATED_BY_USER": "0x11efb9a9e2f873d6b9a9025041000001",
+ "MODIFIED_BY_USER": "0x11efb9a9e2f873d6b9a9025041000001",
+ "UID": "0x11f0bb870b2069e2bb87025041000001",
+ "SORTABLEFLAG": 1,
+ "FILTERABLEFLAG": 1,
+ "AGGREGATABLEFLAG": 1,
+ "DEFAULT_AGGREGATE_FUNCTION": "",
+ "VALUE_LIST_DELIMITER": ",",
+ "READABLEFLAG": 1,
+ "WRITABLEFLAG": 1,
+ "SYSTEMFLAG": 0,
+ "DEFAULT_EDITOR_UXON": null,
+ "COPY_WITH_RELATED_OBJECT": 0,
+ "DELETE_WITH_RELATED_OBJECT": 0,
+ "DEFAULT_DISPLAY_UXON": null,
+ "COMMENTS": "",
+ "NAME": "Employee ID",
+ "RELATION_CARDINALITY": "",
+ "TYPE": "D",
+ "COPYABLEFLAG": 1,
+ "ALIAS": "EMPLOYEE_ID",
+ "DATATYPE": "0x30000000000000000000000000000000",
+ "DATA_ADDRESS": "employee_id",
+ "OBJECT": "0x31343400000000000000000000000000",
+ "FORMATTER": "",
+ "DISPLAYORDER": null,
+ "LABELFLAG": 0,
+ "UIDFLAG": 0,
+ "HIDDENFLAG": 0,
+ "EDITABLEFLAG": 1,
+ "REQUIREDFLAG": 0,
+ "RELATED_OBJ": null,
+ "SORTERPOS": null,
+ "SORTERDIR": "",
+ "RELATED_OBJ_ATTR": null,
+ "SHORT_DESCRIPTION": "",
+ "DATA_ADDRESS_PROPS": null,
+ "DEFAULT_VALUE": "",
+ "FIXED_VALUE": "",
+ "CUSTOM_DATA_TYPE": {
+ "length_max": 50
+ }
}
],
"totals_rows": [],