diff --git a/dist/assets/images/delete.svg b/dist/assets/images/delete.svg
new file mode 100644
index 00000000..7cbf916d
--- /dev/null
+++ b/dist/assets/images/delete.svg
@@ -0,0 +1,11 @@
+
diff --git a/dist/assets/images/facebook.svg b/dist/assets/images/facebook.svg
new file mode 100644
index 00000000..041c273a
--- /dev/null
+++ b/dist/assets/images/facebook.svg
@@ -0,0 +1,10 @@
+
diff --git a/dist/assets/images/instagram.svg b/dist/assets/images/instagram.svg
new file mode 100644
index 00000000..e82bb907
--- /dev/null
+++ b/dist/assets/images/instagram.svg
@@ -0,0 +1,17 @@
+
diff --git a/dist/assets/images/logo.svg b/dist/assets/images/logo.svg
new file mode 100644
index 00000000..38292753
--- /dev/null
+++ b/dist/assets/images/logo.svg
@@ -0,0 +1,9 @@
+
diff --git a/dist/assets/images/twitter.svg b/dist/assets/images/twitter.svg
new file mode 100644
index 00000000..f8c3aee2
--- /dev/null
+++ b/dist/assets/images/twitter.svg
@@ -0,0 +1,3 @@
+
diff --git a/dist/assets/images/undo.svg b/dist/assets/images/undo.svg
new file mode 100644
index 00000000..37f43636
--- /dev/null
+++ b/dist/assets/images/undo.svg
@@ -0,0 +1,4 @@
+
diff --git a/dist/assets/images/youtube.svg b/dist/assets/images/youtube.svg
new file mode 100644
index 00000000..7b84e3ed
--- /dev/null
+++ b/dist/assets/images/youtube.svg
@@ -0,0 +1,4 @@
+
diff --git a/dist/framework/processing/python/worker.d.ts b/dist/framework/processing/python/worker.d.ts
index 1bdb56aa..f83e81b8 100644
--- a/dist/framework/processing/python/worker.d.ts
+++ b/dist/framework/processing/python/worker.d.ts
@@ -5,4 +5,4 @@ declare function initialise(): any;
declare function loadScript(script: any): void;
declare function pyWorker(): string;
declare let pyScript: any;
-declare const pyPortApi: "\nclass CommandUIRender:\n __slots__ = \"page\"\n def __init__(self, page):\n self.page = page\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"CommandUIRender\"\n dict[\"page\"] = self.page.toDict()\n return dict\n\nclass CommandSystemDonate:\n __slots__ = \"key\", \"json_string\"\n def __init__(self, key, json_string):\n self.key = key\n self.json_string = json_string\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"CommandSystemDonate\"\n dict[\"key\"] = self.key\n dict[\"json_string\"] = self.json_string\n return dict\n\n \nclass PropsUIHeader:\n __slots__ = \"title\"\n def __init__(self, title):\n self.title = title\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIHeader\"\n dict[\"title\"] = self.title.toDict()\n return dict\n\n\nclass PropsUIPromptConfirm:\n __slots__ = \"text\", \"ok\", \"cancel\"\n def __init__(self, text, ok, cancel):\n self.text = text\n self.ok = ok\n self.cancel = cancel\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConfirm\"\n dict[\"text\"] = self.text.toDict()\n dict[\"ok\"] = self.ok.toDict()\n dict[\"cancel\"] = self.cancel.toDict()\n return dict\n\n\nclass PropsUIPromptConsentForm:\n __slots__ = \"title\", \"description\", \"tables\", \"meta_tables\"\n def __init__(self, title, description, tables, meta_tables):\n self.title = title\n self.description = description \n self.tables = tables\n self.meta_tables = meta_tables\n def translate_tables(self):\n output = []\n for table in self.tables:\n output.append(table.toDict())\n return output\n def translate_meta_tables(self):\n output = []\n for table in self.meta_tables:\n output.append(table.toDict())\n return output\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConsentForm\"\n dict[\"title\"] = self.title.toDict()\n dict[\"description\"] = self.description.toDict()\n dict[\"tables\"] = self.translate_tables()\n dict[\"metaTables\"] = self.translate_meta_tables()\n return dict\n\n\nclass PropsUIPromptConsentFormTable:\n __slots__ = \"id\", \"title\", \"data_frame\"\n def __init__(self, id, title, data_frame):\n self.id = id\n self.title = title\n self.data_frame = data_frame\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConsentFormTable\"\n dict[\"id\"] = self.id\n dict[\"title\"] = self.title\n dict[\"data_frame\"] = self.data_frame.to_json()\n return dict\n\n\nclass PropsUIPromptFileInput:\n __slots__ = \"title\", \"description\", \"extensions\"\n def __init__(self, title, description, extensions):\n self.title = title\n self.description = description\n self.extensions = extensions\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptFileInput\"\n dict[\"title\"] = self.title.toDict()\n dict[\"description\"] = self.description.toDict()\n dict[\"extensions\"] = self.extensions\n return dict\n\n\nclass PropsUIPromptRadioInput:\n __slots__ = \"title\", \"description\", \"items\"\n def __init__(self, title, description, items):\n self.title = title\n self.description = description\n self.items = items\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptRadioInput\"\n dict[\"title\"] = self.title.toDict()\n dict[\"description\"] = self.description.toDict()\n dict[\"items\"] = self.items\n return dict\n\n\nclass PropsUIPageDonation:\n __slots__ = \"header\", \"body\"\n def __init__(self, header, body):\n self.header = header\n self.body = body\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageDonation\"\n dict[\"header\"] = self.header.toDict()\n dict[\"body\"] = self.body.toDict()\n return dict\n\n\nclass PropsUIPageStart:\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageStart\"\n return dict\n\n\nclass PropsUIPageEnd:\n __slots__ = \"header\" \n def __init__(self, header):\n self.header = header\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageEnd\"\n dict[\"header\"] = self.header.toDict()\n return dict\n\n\nclass Translatable:\n __slots__ = \"translations\"\n def __init__(self, translations):\n self.translations = translations\n def toDict(self):\n dict = {}\n dict[\"translations\"] = self.translations\n return dict \n";
+declare const pyPortApi: "\nclass CommandUIRender:\n __slots__ = \"page\"\n def __init__(self, page):\n self.page = page\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"CommandUIRender\"\n dict[\"page\"] = self.page.toDict()\n return dict\n\nclass CommandSystemDonate:\n __slots__ = \"key\", \"json_string\"\n def __init__(self, key, json_string):\n self.key = key\n self.json_string = json_string\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"CommandSystemDonate\"\n dict[\"key\"] = self.key\n dict[\"json_string\"] = self.json_string\n return dict\n\n \nclass PropsUIHeader:\n __slots__ = \"title\"\n def __init__(self, title):\n self.title = title\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIHeader\"\n dict[\"title\"] = self.title.toDict()\n return dict\n\n\nclass PropsUIFooter:\n __slots__ = \"progress_percentage\"\n def __init__(self, progress_percentage):\n self.progress_percentage = progress_percentage\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIFooter\"\n dict[\"progressPercentage\"] = self.progress_percentage\n return dict\n\n\nclass PropsUIPromptConfirm:\n __slots__ = \"text\", \"ok\", \"cancel\"\n def __init__(self, text, ok, cancel):\n self.text = text\n self.ok = ok\n self.cancel = cancel\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConfirm\"\n dict[\"text\"] = self.text.toDict()\n dict[\"ok\"] = self.ok.toDict()\n dict[\"cancel\"] = self.cancel.toDict()\n return dict\n\n\nclass PropsUIPromptConsentForm:\n __slots__ = \"tables\", \"meta_tables\"\n def __init__(self, tables, meta_tables):\n self.tables = tables\n self.meta_tables = meta_tables\n def translate_tables(self):\n output = []\n for table in self.tables:\n output.append(table.toDict())\n return output\n def translate_meta_tables(self):\n output = []\n for table in self.meta_tables:\n output.append(table.toDict())\n return output\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConsentForm\"\n dict[\"tables\"] = self.translate_tables()\n dict[\"metaTables\"] = self.translate_meta_tables()\n return dict\n\n\nclass PropsUIPromptConsentFormTable:\n __slots__ = \"id\", \"title\", \"data_frame\"\n def __init__(self, id, title, data_frame):\n self.id = id\n self.title = title\n self.data_frame = data_frame\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConsentFormTable\"\n dict[\"id\"] = self.id\n dict[\"title\"] = self.title\n dict[\"data_frame\"] = self.data_frame.to_json()\n return dict\n\n\nclass PropsUIPromptFileInput:\n __slots__ = \"description\", \"extensions\"\n def __init__(self, description, extensions):\n self.description = description\n self.extensions = extensions\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptFileInput\"\n dict[\"description\"] = self.description.toDict()\n dict[\"extensions\"] = self.extensions\n return dict\n\n\nclass PropsUIPromptRadioInput:\n __slots__ = \"title\", \"description\", \"items\"\n def __init__(self, title, description, items):\n self.title = title\n self.description = description\n self.items = items\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptRadioInput\"\n dict[\"title\"] = self.title.toDict()\n dict[\"description\"] = self.description.toDict()\n dict[\"items\"] = self.items\n return dict\n\n\nclass PropsUIPageDonation:\n __slots__ = \"platform\", \"header\", \"body\", \"footer\"\n def __init__(self, platform, header, body, footer):\n self.platform = platform\n self.header = header\n self.body = body\n self.footer = footer\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageDonation\"\n dict[\"platform\"] = self.platform\n dict[\"header\"] = self.header.toDict()\n dict[\"body\"] = self.body.toDict()\n dict[\"footer\"] = self.footer.toDict()\n return dict\n\n\nclass PropsUIPageEnd:\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageEnd\"\n return dict\n\n\nclass Translatable:\n __slots__ = \"translations\"\n def __init__(self, translations):\n self.translations = translations\n def toDict(self):\n dict = {}\n dict[\"translations\"] = self.translations\n return dict \n";
diff --git a/dist/framework/processing/python/worker.js b/dist/framework/processing/python/worker.js
index 193acbab..e6e55655 100644
--- a/dist/framework/processing/python/worker.js
+++ b/dist/framework/processing/python/worker.js
@@ -80,7 +80,7 @@ function loadScript(script) {
self.pyodide.runPython(pyPortApi);
self.pyodide.runPython(script);
}
-var pyPortApi = "\nclass CommandUIRender:\n __slots__ = \"page\"\n def __init__(self, page):\n self.page = page\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"CommandUIRender\"\n dict[\"page\"] = self.page.toDict()\n return dict\n\nclass CommandSystemDonate:\n __slots__ = \"key\", \"json_string\"\n def __init__(self, key, json_string):\n self.key = key\n self.json_string = json_string\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"CommandSystemDonate\"\n dict[\"key\"] = self.key\n dict[\"json_string\"] = self.json_string\n return dict\n\n \nclass PropsUIHeader:\n __slots__ = \"title\"\n def __init__(self, title):\n self.title = title\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIHeader\"\n dict[\"title\"] = self.title.toDict()\n return dict\n\n\nclass PropsUIPromptConfirm:\n __slots__ = \"text\", \"ok\", \"cancel\"\n def __init__(self, text, ok, cancel):\n self.text = text\n self.ok = ok\n self.cancel = cancel\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConfirm\"\n dict[\"text\"] = self.text.toDict()\n dict[\"ok\"] = self.ok.toDict()\n dict[\"cancel\"] = self.cancel.toDict()\n return dict\n\n\nclass PropsUIPromptConsentForm:\n __slots__ = \"title\", \"description\", \"tables\", \"meta_tables\"\n def __init__(self, title, description, tables, meta_tables):\n self.title = title\n self.description = description \n self.tables = tables\n self.meta_tables = meta_tables\n def translate_tables(self):\n output = []\n for table in self.tables:\n output.append(table.toDict())\n return output\n def translate_meta_tables(self):\n output = []\n for table in self.meta_tables:\n output.append(table.toDict())\n return output\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConsentForm\"\n dict[\"title\"] = self.title.toDict()\n dict[\"description\"] = self.description.toDict()\n dict[\"tables\"] = self.translate_tables()\n dict[\"metaTables\"] = self.translate_meta_tables()\n return dict\n\n\nclass PropsUIPromptConsentFormTable:\n __slots__ = \"id\", \"title\", \"data_frame\"\n def __init__(self, id, title, data_frame):\n self.id = id\n self.title = title\n self.data_frame = data_frame\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConsentFormTable\"\n dict[\"id\"] = self.id\n dict[\"title\"] = self.title\n dict[\"data_frame\"] = self.data_frame.to_json()\n return dict\n\n\nclass PropsUIPromptFileInput:\n __slots__ = \"title\", \"description\", \"extensions\"\n def __init__(self, title, description, extensions):\n self.title = title\n self.description = description\n self.extensions = extensions\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptFileInput\"\n dict[\"title\"] = self.title.toDict()\n dict[\"description\"] = self.description.toDict()\n dict[\"extensions\"] = self.extensions\n return dict\n\n\nclass PropsUIPromptRadioInput:\n __slots__ = \"title\", \"description\", \"items\"\n def __init__(self, title, description, items):\n self.title = title\n self.description = description\n self.items = items\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptRadioInput\"\n dict[\"title\"] = self.title.toDict()\n dict[\"description\"] = self.description.toDict()\n dict[\"items\"] = self.items\n return dict\n\n\nclass PropsUIPageDonation:\n __slots__ = \"header\", \"body\"\n def __init__(self, header, body):\n self.header = header\n self.body = body\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageDonation\"\n dict[\"header\"] = self.header.toDict()\n dict[\"body\"] = self.body.toDict()\n return dict\n\n\nclass PropsUIPageStart:\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageStart\"\n return dict\n\n\nclass PropsUIPageEnd:\n __slots__ = \"header\" \n def __init__(self, header):\n self.header = header\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageEnd\"\n dict[\"header\"] = self.header.toDict()\n return dict\n\n\nclass Translatable:\n __slots__ = \"translations\"\n def __init__(self, translations):\n self.translations = translations\n def toDict(self):\n dict = {}\n dict[\"translations\"] = self.translations\n return dict \n";
+var pyPortApi = "\nclass CommandUIRender:\n __slots__ = \"page\"\n def __init__(self, page):\n self.page = page\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"CommandUIRender\"\n dict[\"page\"] = self.page.toDict()\n return dict\n\nclass CommandSystemDonate:\n __slots__ = \"key\", \"json_string\"\n def __init__(self, key, json_string):\n self.key = key\n self.json_string = json_string\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"CommandSystemDonate\"\n dict[\"key\"] = self.key\n dict[\"json_string\"] = self.json_string\n return dict\n\n \nclass PropsUIHeader:\n __slots__ = \"title\"\n def __init__(self, title):\n self.title = title\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIHeader\"\n dict[\"title\"] = self.title.toDict()\n return dict\n\n\nclass PropsUIFooter:\n __slots__ = \"progress_percentage\"\n def __init__(self, progress_percentage):\n self.progress_percentage = progress_percentage\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIFooter\"\n dict[\"progressPercentage\"] = self.progress_percentage\n return dict\n\n\nclass PropsUIPromptConfirm:\n __slots__ = \"text\", \"ok\", \"cancel\"\n def __init__(self, text, ok, cancel):\n self.text = text\n self.ok = ok\n self.cancel = cancel\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConfirm\"\n dict[\"text\"] = self.text.toDict()\n dict[\"ok\"] = self.ok.toDict()\n dict[\"cancel\"] = self.cancel.toDict()\n return dict\n\n\nclass PropsUIPromptConsentForm:\n __slots__ = \"tables\", \"meta_tables\"\n def __init__(self, tables, meta_tables):\n self.tables = tables\n self.meta_tables = meta_tables\n def translate_tables(self):\n output = []\n for table in self.tables:\n output.append(table.toDict())\n return output\n def translate_meta_tables(self):\n output = []\n for table in self.meta_tables:\n output.append(table.toDict())\n return output\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConsentForm\"\n dict[\"tables\"] = self.translate_tables()\n dict[\"metaTables\"] = self.translate_meta_tables()\n return dict\n\n\nclass PropsUIPromptConsentFormTable:\n __slots__ = \"id\", \"title\", \"data_frame\"\n def __init__(self, id, title, data_frame):\n self.id = id\n self.title = title\n self.data_frame = data_frame\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptConsentFormTable\"\n dict[\"id\"] = self.id\n dict[\"title\"] = self.title\n dict[\"data_frame\"] = self.data_frame.to_json()\n return dict\n\n\nclass PropsUIPromptFileInput:\n __slots__ = \"description\", \"extensions\"\n def __init__(self, description, extensions):\n self.description = description\n self.extensions = extensions\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptFileInput\"\n dict[\"description\"] = self.description.toDict()\n dict[\"extensions\"] = self.extensions\n return dict\n\n\nclass PropsUIPromptRadioInput:\n __slots__ = \"title\", \"description\", \"items\"\n def __init__(self, title, description, items):\n self.title = title\n self.description = description\n self.items = items\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPromptRadioInput\"\n dict[\"title\"] = self.title.toDict()\n dict[\"description\"] = self.description.toDict()\n dict[\"items\"] = self.items\n return dict\n\n\nclass PropsUIPageDonation:\n __slots__ = \"platform\", \"header\", \"body\", \"footer\"\n def __init__(self, platform, header, body, footer):\n self.platform = platform\n self.header = header\n self.body = body\n self.footer = footer\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageDonation\"\n dict[\"platform\"] = self.platform\n dict[\"header\"] = self.header.toDict()\n dict[\"body\"] = self.body.toDict()\n dict[\"footer\"] = self.footer.toDict()\n return dict\n\n\nclass PropsUIPageEnd:\n def toDict(self):\n dict = {}\n dict[\"__type__\"] = \"PropsUIPageEnd\"\n return dict\n\n\nclass Translatable:\n __slots__ = \"translations\"\n def __init__(self, translations):\n self.translations = translations\n def toDict(self):\n dict = {}\n dict[\"translations\"] = self.translations\n return dict \n";
function pyWorker() {
return "\n from collections.abc import Generator\n import json\n import html\n import pandas as pd\n\n\n class ScriptWrapper(Generator):\n def __init__(self, script):\n self.script = script\n def send(self, data):\n command = self.script.send(data)\n return command.toDict()\n def throw(self, type=None, value=None, traceback=None):\n raise StopIteration\n script = process()\n ScriptWrapper(script)\n ";
}
diff --git a/dist/framework/types/elements.d.ts b/dist/framework/types/elements.d.ts
index 578b7718..3bc3c53d 100644
--- a/dist/framework/types/elements.d.ts
+++ b/dist/framework/types/elements.d.ts
@@ -1,8 +1,8 @@
import { PropsUIPage } from './pages';
import { PropsUIPrompt } from './prompts';
-export declare type PropsUI = PropsUIText | PropsUIButton | PropsUICheckBox | PropsUIRadioItem | PropsUISpinner | PropsUIHeader | PropsUITable | PropsUISearchBar | PropsUIPage | PropsUIPrompt;
-export declare type PropsUIText = PropsUITextTitle0 | PropsUITextTitle1 | PropsUITextTitle2 | PropsUITextTitle6 | PropsUITextBodyLarge | PropsUITextLabel;
-export declare type PropsUIButton = PropsUIButtonPrimary | PropsUIButtonSecundary | PropsUIButtonForward | PropsUIButtonLabel;
+export declare type PropsUI = PropsUIText | PropsUIButton | PropsUICheckBox | PropsUIRadioItem | PropsUISpinner | PropsUIProgress | PropsUIHeader | PropsUITable | PropsUISearchBar | PropsUIPage | PropsUIPrompt;
+export declare type PropsUIText = PropsUITextTitle0 | PropsUITextTitle1 | PropsUITextTitle2 | PropsUITextTitle3 | PropsUITextTitle6 | PropsUITextBodyLarge | PropsUITextLabel;
+export declare type PropsUIButton = PropsUIButtonPrimary | PropsUIButtonSecundary | PropsUIButtonBack | PropsUIButtonForward | PropsUIButtonIconBack | PropsUIButtonIconForward | PropsUIButtonIcon | PropsUIButtonLabel | PropsUIButtonIconLabel;
export declare function isPropsUI(arg: any): arg is PropsUI;
export declare function isPropsUIText(arg: any): arg is PropsUIText;
export interface PropsUITextLabel {
@@ -12,6 +12,13 @@ export interface PropsUITextLabel {
margin?: string;
}
export declare function isPropsUITextLabel(arg: any): arg is PropsUITextLabel;
+export interface PropsUITextCaption {
+ __type__: 'PropsUITextCaption';
+ text: string;
+ color?: string;
+ margin?: string;
+}
+export declare function isPropsUITextCaption(arg: any): arg is PropsUITextCaption;
export interface PropsUITextBodyLarge {
__type__: 'PropsUITextBodyLarge';
text: string;
@@ -26,6 +33,13 @@ export interface PropsUITextBodyMedium {
margin?: string;
}
export declare function isPropsUITextBodyMedium(arg: any): arg is PropsUITextBodyMedium;
+export interface PropsUITextBodySmall {
+ __type__: 'PropsUITextBodySmall';
+ text: string;
+ color?: string;
+ margin?: string;
+}
+export declare function isPropsUITextBodySmall(arg: any): arg is PropsUITextBodySmall;
export interface PropsUITextTitle0 {
__type__: 'PropsUITextTitle0';
text: string;
@@ -47,6 +61,20 @@ export interface PropsUITextTitle2 {
margin?: string;
}
export declare function isPropsUITextTitle2(arg: any): arg is PropsUITextTitle2;
+export interface PropsUITextTitle3 {
+ __type__: 'PropsUITextTitle3';
+ text: string;
+ color?: string;
+ margin?: string;
+}
+export declare function isPropsUITextTitle3(arg: any): arg is PropsUITextTitle3;
+export interface PropsUITextTitle4 {
+ __type__: 'PropsUITextTitle4';
+ text: string;
+ color?: string;
+ margin?: string;
+}
+export declare function isPropsUITextTitle4(arg: any): arg is PropsUITextTitle4;
export interface PropsUITextTitle6 {
__type__: 'PropsUITextTitle6';
text: string;
@@ -83,6 +111,31 @@ export interface PropsUIButtonForward {
onClick: () => void;
}
export declare function isPropsUIButtonForward(arg: any): arg is PropsUIButtonForward;
+export interface PropsUIButtonIconBack {
+ __type__: 'PropsUIButtonIconBack';
+ onClick: () => void;
+}
+export declare function isPropsUIButtonIconBack(arg: any): arg is PropsUIButtonIconBack;
+export interface PropsUIButtonIconForward {
+ __type__: 'PropsUIButtonIconForward';
+ onClick: () => void;
+}
+export declare function isPropsUIButtonIconForward(arg: any): arg is PropsUIButtonIconForward;
+export interface PropsUIButtonIcon {
+ __type__: 'PropsUIButtonIcon';
+ icon: string;
+ onClick: () => void;
+}
+export declare function isPropsUIButtonIcon(arg: any): arg is PropsUIButtonIcon;
+export interface PropsUIButtonIconLabel {
+ __type__: 'PropsUIButtonIconLabel';
+ icon: string;
+ label: string;
+ color?: string;
+ alignment?: string;
+ onClick: () => void;
+}
+export declare function isPropsUIButtonIconLabel(arg: any): arg is PropsUIButtonIconLabel;
export interface PropsUIButtonLabel {
__type__: 'PropsUIButtonLabel';
label: string;
@@ -109,11 +162,21 @@ export interface PropsUISpinner {
color?: string;
}
export declare function isPropsUISpinner(arg: any): arg is PropsUISpinner;
+export interface PropsUIProgress {
+ __type__: 'PropsUIProgress';
+ percentage: number;
+}
+export declare function isPropsUIProgress(arg: any): arg is PropsUIProgress;
export interface PropsUIHeader {
__type__: 'PropsUIHeader';
title: Text;
}
export declare function isPropsUIHeader(arg: any): arg is PropsUIHeader;
+export interface PropsUIFooter {
+ __type__: 'PropsUIFooter';
+ progressPercentage: number;
+}
+export declare function isPropsUIFooter(arg: any): arg is PropsUIFooter;
export interface PropsUITable {
__type__: 'PropsUITable';
id: string;
diff --git a/dist/framework/types/elements.js b/dist/framework/types/elements.js
index d289fe04..3f66acee 100644
--- a/dist/framework/types/elements.js
+++ b/dist/framework/types/elements.js
@@ -6,6 +6,7 @@ export function isPropsUI(arg) {
return isPropsUIText(arg) ||
isPropsUIButton(arg) ||
isPropsUISpinner(arg) ||
+ isPropsUIProgress(arg) ||
isPropsUIHeader(arg) ||
isPropsUITable(arg) ||
isPropsUIPage(arg) ||
@@ -15,20 +16,31 @@ export function isPropsUI(arg) {
export function isPropsUIText(arg) {
return isPropsUITextTitle0(arg) ||
isPropsUITextTitle0(arg) ||
- isPropsUITextTitle0(arg) ||
+ isPropsUITextTitle1(arg) ||
+ isPropsUITextTitle2(arg) ||
+ isPropsUITextTitle3(arg) ||
+ isPropsUITextTitle4(arg) ||
+ isPropsUITextTitle6(arg) ||
isPropsUITextBodyLarge(arg) ||
isPropsUITextBodyMedium(arg) ||
- isPropsUITextLabel(arg);
+ isPropsUITextLabel(arg) ||
+ isPropsUITextCaption(arg);
}
export function isPropsUITextLabel(arg) {
return isInstanceOf(arg, 'PropsUITextLabel', ['text', 'color', 'margin']);
}
+export function isPropsUITextCaption(arg) {
+ return isInstanceOf(arg, 'PropsUITextCaption', ['text', 'color', 'margin']);
+}
export function isPropsUITextBodyLarge(arg) {
return isInstanceOf(arg, 'PropsUITextBodyLarge', ['text', 'color', 'margin']);
}
export function isPropsUITextBodyMedium(arg) {
return isInstanceOf(arg, 'PropsUITextBodyMedium', ['text', 'color', 'margin']);
}
+export function isPropsUITextBodySmall(arg) {
+ return isInstanceOf(arg, 'PropsUITextBodySmall', ['text', 'color', 'margin']);
+}
export function isPropsUITextTitle0(arg) {
return isInstanceOf(arg, 'PropsUITextTitle0', ['text', 'color', 'margin']);
}
@@ -38,6 +50,12 @@ export function isPropsUITextTitle1(arg) {
export function isPropsUITextTitle2(arg) {
return isInstanceOf(arg, 'PropsUITextTitle2', ['text', 'color', 'margin']);
}
+export function isPropsUITextTitle3(arg) {
+ return isInstanceOf(arg, 'PropsUITextTitle3', ['text', 'color', 'margin']);
+}
+export function isPropsUITextTitle4(arg) {
+ return isInstanceOf(arg, 'PropsUITextTitle4', ['text', 'color', 'margin']);
+}
export function isPropsUITextTitle6(arg) {
return isInstanceOf(arg, 'PropsUITextTitle6', ['text', 'color', 'margin']);
}
@@ -45,8 +63,13 @@ export function isPropsUITextTitle6(arg) {
export function isPropsUIButton(arg) {
return isPropsUIButtonPrimary(arg) ||
isPropsUIButtonSecundary(arg) ||
+ isPropsUIButtonBack(arg) ||
isPropsUIButtonForward(arg) ||
- isPropsUIButtonLabel(arg);
+ isPropsUIButtonIconBack(arg) ||
+ isPropsUIButtonIconForward(arg) ||
+ isPropsUIButtonIcon(arg) ||
+ isPropsUIButtonLabel(arg) ||
+ isPropsUIButtonIconLabel(arg);
}
export function isPropsUIButtonPrimary(arg) {
return isInstanceOf(arg, 'PropsUIButtonPrimary', ['label', 'color', 'onClick']);
@@ -60,6 +83,18 @@ export function isPropsUIButtonBack(arg) {
export function isPropsUIButtonForward(arg) {
return isInstanceOf(arg, 'PropsUIButtonForward', ['label', 'onClick']);
}
+export function isPropsUIButtonIconBack(arg) {
+ return isInstanceOf(arg, 'PropsUIButtonIconBack', ['onClick']);
+}
+export function isPropsUIButtonIconForward(arg) {
+ return isInstanceOf(arg, 'PropsUIButtonIconForward', ['onClick']);
+}
+export function isPropsUIButtonIcon(arg) {
+ return isInstanceOf(arg, 'PropsUIButtonIcon', ['icon', 'onClick']);
+}
+export function isPropsUIButtonIconLabel(arg) {
+ return isInstanceOf(arg, 'PropsUIButtonIconLabel', ['icon', 'label', 'color', 'alignment', 'onClick']);
+}
export function isPropsUIButtonLabel(arg) {
return isInstanceOf(arg, 'PropsUIButtonLabel', ['label', 'onClick']);
}
@@ -72,9 +107,15 @@ export function isPropsUICheckBox(arg) {
export function isPropsUISpinner(arg) {
return isInstanceOf(arg, 'PropsUISpinner', ['color', 'spinning']);
}
+export function isPropsUIProgress(arg) {
+ return isInstanceOf(arg, 'PropsUIProgress', ['percentage']);
+}
export function isPropsUIHeader(arg) {
return isInstanceOf(arg, 'PropsUIHeader', ['title']);
}
+export function isPropsUIFooter(arg) {
+ return isInstanceOf(arg, 'PropsUIFooter', ['progressPercentage']);
+}
export function isPropsUITable(arg) {
return isInstanceOf(arg, 'PropsUITable', ['readOnly', 'pageSize', 'id', 'head', 'body']);
}
diff --git a/dist/framework/types/pages.d.ts b/dist/framework/types/pages.d.ts
index f93e9519..7ca91a9e 100644
--- a/dist/framework/types/pages.d.ts
+++ b/dist/framework/types/pages.d.ts
@@ -1,23 +1,20 @@
-import { PropsUIHeader } from './elements';
+import { PropsUIFooter, PropsUIHeader } from './elements';
import { PropsUIPromptFileInput, PropsUIPromptConfirm, PropsUIPromptConsentForm } from './prompts';
-export declare type PropsUIPage = PropsUIPageSplashScreen | PropsUIPageDonation | PropsUIPageStart | PropsUIPageEnd;
+export declare type PropsUIPage = PropsUIPageSplashScreen | PropsUIPageDonation | PropsUIPageEnd;
export declare function isPropsUIPage(arg: any): arg is PropsUIPage;
export interface PropsUIPageSplashScreen {
__type__: 'PropsUIPageSplashScreen';
}
export declare function isPropsUIPageSplashScreen(arg: any): arg is PropsUIPageSplashScreen;
-export interface PropsUIPageStart {
- __type__: 'PropsUIPageStart';
-}
-export declare function isPropsUIPageStart(arg: any): arg is PropsUIPageStart;
export interface PropsUIPageDonation {
__type__: 'PropsUIPageDonation';
+ platform: string;
header: PropsUIHeader;
body: PropsUIPromptFileInput | PropsUIPromptConfirm | PropsUIPromptConsentForm;
+ footer: PropsUIFooter;
}
export declare function isPropsUIPageDonation(arg: any): arg is PropsUIPageDonation;
export interface PropsUIPageEnd {
__type__: 'PropsUIPageEnd';
- header: PropsUIHeader;
}
export declare function isPropsUIPageEnd(arg: any): arg is PropsUIPageEnd;
diff --git a/dist/framework/types/pages.js b/dist/framework/types/pages.js
index 2d627787..2a678fb9 100644
--- a/dist/framework/types/pages.js
+++ b/dist/framework/types/pages.js
@@ -2,18 +2,14 @@ import { isInstanceOf } from '../helpers';
export function isPropsUIPage(arg) {
return (isPropsUIPageSplashScreen(arg) ||
isPropsUIPageDonation(arg) ||
- isPropsUIPageStart(arg) ||
isPropsUIPageEnd(arg));
}
export function isPropsUIPageSplashScreen(arg) {
return isInstanceOf(arg, 'PropsUIPageSplashScreen', []);
}
-export function isPropsUIPageStart(arg) {
- return isInstanceOf(arg, 'PropsUIPageStart', []);
-}
export function isPropsUIPageDonation(arg) {
- return isInstanceOf(arg, 'PropsUIPageDonation', ['header', 'body']);
+ return isInstanceOf(arg, 'PropsUIPageDonation', ['platform', 'header', 'body', 'footer']);
}
export function isPropsUIPageEnd(arg) {
- return isInstanceOf(arg, 'PropsUIPageEnd', ['header']);
+ return isInstanceOf(arg, 'PropsUIPageEnd', []);
}
diff --git a/dist/framework/types/prompts.d.ts b/dist/framework/types/prompts.d.ts
index 1b2a62e8..6afc8801 100644
--- a/dist/framework/types/prompts.d.ts
+++ b/dist/framework/types/prompts.d.ts
@@ -10,7 +10,6 @@ export interface PropsUIPromptConfirm {
export declare function isPropsUIPromptConfirm(arg: any): arg is PropsUIPromptConfirm;
export interface PropsUIPromptFileInput {
__type__: 'PropsUIPromptFileInput';
- title: Text;
description: Text;
extensions: string;
}
@@ -24,8 +23,6 @@ export interface PropsUIPromptRadioInput {
export declare function isPropsUIPromptRadioInput(arg: any): arg is PropsUIPromptRadioInput;
export interface PropsUIPromptConsentForm {
__type__: 'PropsUIPromptConsentForm';
- title: Text;
- description: Text;
tables: PropsUIPromptConsentFormTable[];
metaTables: PropsUIPromptConsentFormTable[];
}
diff --git a/dist/framework/types/prompts.js b/dist/framework/types/prompts.js
index ea92a326..d4147e07 100644
--- a/dist/framework/types/prompts.js
+++ b/dist/framework/types/prompts.js
@@ -8,13 +8,13 @@ export function isPropsUIPromptConfirm(arg) {
return isInstanceOf(arg, 'PropsUIPromptConfirm', ['text', 'ok', 'cancel']);
}
export function isPropsUIPromptFileInput(arg) {
- return isInstanceOf(arg, 'PropsUIPromptFileInput', ['title', 'description', 'extensions']);
+ return isInstanceOf(arg, 'PropsUIPromptFileInput', ['description', 'extensions']);
}
export function isPropsUIPromptRadioInput(arg) {
return isInstanceOf(arg, 'PropsUIPromptRadioInput', ['title', 'description', 'items']);
}
export function isPropsUIPromptConsentForm(arg) {
- return isInstanceOf(arg, 'PropsUIPromptConsentForm', ['title', 'description', 'tables', 'metaTables']);
+ return isInstanceOf(arg, 'PropsUIPromptConsentForm', ['tables', 'metaTables']);
}
export function isPropsUIPromptConsentFormTable(arg) {
return isInstanceOf(arg, 'PropsUIPromptConsentFormTable', ['id', 'title', 'description', 'data_frame']);
diff --git a/dist/framework/visualisation/react/engine.js b/dist/framework/visualisation/react/engine.js
index 00b36255..30f6c05b 100644
--- a/dist/framework/visualisation/react/engine.js
+++ b/dist/framework/visualisation/react/engine.js
@@ -66,13 +66,11 @@ var ReactEngine = /** @class */ (function () {
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
- case 0:
- console.log('[ReactEngine] render page: ' + JSON.stringify(props));
- return [4 /*yield*/, new Promise(function (resolve) {
- var context = { locale: _this.locale, resolve: resolve };
- var page = _this.factory.createPage(props, context);
- _this.renderElements([page]);
- })];
+ case 0: return [4 /*yield*/, new Promise(function (resolve) {
+ var context = { locale: _this.locale, resolve: resolve };
+ var page = _this.factory.createPage(props, context);
+ _this.renderElements([page]);
+ })];
case 1: return [2 /*return*/, _a.sent()];
}
});
diff --git a/dist/framework/visualisation/react/factory.js b/dist/framework/visualisation/react/factory.js
index 2a45a3a6..3b44c471 100644
--- a/dist/framework/visualisation/react/factory.js
+++ b/dist/framework/visualisation/react/factory.js
@@ -11,8 +11,7 @@ var __assign = (this && this.__assign) || function () {
};
import { jsx as _jsx } from "react/jsx-runtime";
import { EndPage } from './ui/pages/end_page';
-import { StartPage } from './ui/pages/start_page';
-import { isPropsUIPageEnd, isPropsUIPageDonation, isPropsUIPageStart, isPropsUIPageSplashScreen } from '../../types/pages';
+import { isPropsUIPageEnd, isPropsUIPageDonation, isPropsUIPageSplashScreen } from '../../types/pages';
import { DonationPage } from './ui/pages/donation_page';
import { SplashScreen } from './ui/pages/splash_screen';
var ReactFactory = /** @class */ (function () {
@@ -22,9 +21,6 @@ var ReactFactory = /** @class */ (function () {
if (isPropsUIPageSplashScreen(page)) {
return _jsx(SplashScreen, __assign({}, page, context));
}
- if (isPropsUIPageStart(page)) {
- return _jsx(StartPage, __assign({}, page, context));
- }
if (isPropsUIPageEnd(page)) {
return _jsx(EndPage, __assign({}, page, context));
}
diff --git a/dist/framework/visualisation/react/main.js b/dist/framework/visualisation/react/main.js
index 44007eae..cef41dd1 100644
--- a/dist/framework/visualisation/react/main.js
+++ b/dist/framework/visualisation/react/main.js
@@ -13,5 +13,5 @@ import { jsx as _jsx } from "react/jsx-runtime";
export var Main = function (_a) {
var elements = _a.elements;
elements = elements.map(function (element, index) { return __assign(__assign({}, element), { key: "".concat(index) }); });
- return (_jsx("div", __assign({ className: 'flex w-full' }, { children: _jsx("div", __assign({ className: 'flex-grow m-6 md:8 lg:m-14 max-w-sheet' }, { children: _jsx("div", __assign({ className: 'w-full' }, { children: elements })) })) })));
+ return (_jsx("div", __assign({ className: 'w-full h-full' }, { children: elements })));
};
diff --git a/dist/framework/visualisation/react/ui/elements/button.d.ts b/dist/framework/visualisation/react/ui/elements/button.d.ts
index b9e8befb..8fefec09 100644
--- a/dist/framework/visualisation/react/ui/elements/button.d.ts
+++ b/dist/framework/visualisation/react/ui/elements/button.d.ts
@@ -1,8 +1,12 @@
///
import { Weak } from '../../../../helpers';
-import { PropsUIButtonBack, PropsUIButtonForward, PropsUIButtonLabel, PropsUIButtonPrimary, PropsUIButtonSecundary } from '../../../../types/elements';
+import { PropsUIButtonBack, PropsUIButtonForward, PropsUIButtonIcon, PropsUIButtonIconBack, PropsUIButtonIconForward, PropsUIButtonIconLabel, PropsUIButtonLabel, PropsUIButtonPrimary, PropsUIButtonSecundary } from '../../../../types/elements';
export declare const PrimaryButton: ({ label, spinning, enabled, color, onClick }: Weak) => JSX.Element;
export declare const SecondaryButton: ({ label, color, onClick }: Weak) => JSX.Element;
export declare const BackButton: ({ label, onClick }: Weak) => JSX.Element;
export declare const ForwardButton: ({ label, onClick }: Weak) => JSX.Element;
+export declare const BackIconButton: ({ onClick }: Weak) => JSX.Element;
+export declare const ForwardIconButton: ({ onClick }: Weak) => JSX.Element;
+export declare const IconButton: ({ icon, onClick }: Weak) => JSX.Element;
+export declare const IconLabelButton: ({ icon, label, color, alignment, onClick }: Weak) => JSX.Element;
export declare const LabelButton: ({ label, color, onClick }: Weak) => JSX.Element;
diff --git a/dist/framework/visualisation/react/ui/elements/button.js b/dist/framework/visualisation/react/ui/elements/button.js
index e94ea16d..6d1e97d6 100644
--- a/dist/framework/visualisation/react/ui/elements/button.js
+++ b/dist/framework/visualisation/react/ui/elements/button.js
@@ -21,19 +21,35 @@ function spinnerColor(buttonColor) {
}
export var PrimaryButton = function (_a) {
var label = _a.label, _b = _a.spinning, spinning = _b === void 0 ? false : _b, _c = _a.enabled, enabled = _c === void 0 ? true : _c, _d = _a.color, color = _d === void 0 ? 'bg-primary text-white' : _d, onClick = _a.onClick;
- return (_jsxs("div", __assign({ className: 'relative' }, { children: [_jsx("div", __assign({ className: "pt-15px pb-15px pr-4 pl-4 leading-none font-button text-button rounded ".concat(enabled ? 'cursor-pointer active:shadow-top4px active:pt-4 active:pb-14px' : '', " ").concat(color), onClick: onClick }, { children: _jsx("div", __assign({ id: 'confirm-button', className: "flex-wrap ".concat(spinning ? 'opacity-0' : '') }, { children: label })) })), _jsx("div", __assign({ className: "absolute top-0 h-full w-full flex flex-col justify-center items-center ".concat(spinning ? '' : 'hidden') }, { children: _jsx("div", __assign({ className: 'w-5 h-5' }, { children: _jsx(Spinner, { color: spinnerColor(color), spinning: spinning }) })) }))] })));
+ return (_jsxs("div", __assign({ className: 'relative min-w-button' }, { children: [_jsx("div", __assign({ className: "flex flex-col items-center leading-none font-button text-button rounded ".concat(enabled ? 'cursor-pointer active:shadow-top4px' : '', " ").concat(color), onClick: onClick }, { children: _jsx("div", __assign({ id: 'confirm-button', className: "pt-15px pb-15px pr-4 pl-4 ".concat(enabled ? 'active:pt-4 active:pb-14px' : '', " ").concat(spinning ? 'opacity-0' : '') }, { children: label })) })), _jsx("div", __assign({ className: "absolute top-0 h-full w-full flex flex-col justify-center items-center ".concat(spinning ? '' : 'hidden') }, { children: _jsx("div", __assign({ className: 'w-5 h-5' }, { children: _jsx(Spinner, { color: spinnerColor(color), spinning: spinning }) })) }))] })));
};
export var SecondaryButton = function (_a) {
var label = _a.label, _b = _a.color, color = _b === void 0 ? 'bg-delete text-delete' : _b, onClick = _a.onClick;
- return (_jsx("div", __assign({ className: "pt-13px pb-13px active:pt-14px active:pb-3 active:shadow-top2px border-2 font-button text-button rounded bg-opacity-0 pr-4 pl-4 cursor-pointer ".concat(color), onClick: onClick }, { children: _jsx("div", __assign({ className: 'flex-wrap' }, { children: label })) })));
+ return (_jsx("div", __assign({ className: 'relative min-w-button' }, { children: _jsx("div", __assign({ className: "flex flex-col items-center active:shadow-top2px border-2 font-button text-button rounded bg-opacity-0 cursor-pointer ".concat(color), onClick: onClick }, { children: _jsx("div", __assign({ className: 'pt-13px pb-13px pr-4 pl-4 active:pt-14px active:pb-3' }, { children: label })) })) })));
};
export var BackButton = function (_a) {
var label = _a.label, onClick = _a.onClick;
- return (_jsx("div", __assign({ className: 'pt-1 pb-1 active:pt-5px active:pb-3px rounded bg-opacity-0 focus:outline-none cursor-pointer ', onClick: onClick }, { children: _jsxs("div", __assign({ className: 'flex items-center' }, { children: [_jsx("div", { children: _jsx("img", { className: 'mr-2 -mt-2px', src: BackSvg, alt: label }) }), _jsx("div", __assign({ className: 'focus:outline-none' }, { children: _jsx("div", __assign({ className: 'flex flex-col justify-center h-full items-center' }, { children: _jsx("div", __assign({ className: 'flex-wrap text-button font-button text-grey1' }, { children: label })) })) }))] })) })));
+ return _jsx(IconLabelButton, { icon: BackSvg, label: label, onClick: onClick });
};
export var ForwardButton = function (_a) {
var label = _a.label, onClick = _a.onClick;
- return (_jsx("div", __assign({ className: 'pt-1 pb-1 active:pt-5px active:pb-3px rounded bg-opacity-0 focus:outline-none cursor-pointer ', onClick: onClick }, { children: _jsxs("div", __assign({ className: 'flex items-center' }, { children: [_jsx("div", __assign({ className: 'focus:outline-none' }, { children: _jsx("div", __assign({ className: 'flex flex-col justify-center h-full items-center' }, { children: _jsx("div", __assign({ className: 'flex-wrap text-button font-button text-grey1' }, { children: label })) })) })), _jsx("div", { children: _jsx("img", { className: 'ml-2 -mt-2px', src: ForwardSvg, alt: label }) })] })) })));
+ return _jsx(IconLabelButton, { icon: ForwardSvg, label: label, onClick: onClick, alignment: 'right' });
+};
+export var BackIconButton = function (_a) {
+ var onClick = _a.onClick;
+ return _jsx(IconButton, { icon: BackSvg, onClick: onClick });
+};
+export var ForwardIconButton = function (_a) {
+ var onClick = _a.onClick;
+ return _jsx(IconButton, { icon: ForwardSvg, onClick: onClick });
+};
+export var IconButton = function (_a) {
+ var icon = _a.icon, onClick = _a.onClick;
+ return (_jsx("div", __assign({ className: 'active:pt-5px active:pb-3px focus:outline-none cursor-pointer w-6 h-6', onClick: onClick }, { children: _jsxs("div", __assign({ className: 'flex flex-col items-center h-full w-full' }, { children: [_jsx("div", { className: 'flex-grow' }), _jsx("div", { children: _jsx("img", { className: '-mt-2px', src: icon }) }), _jsx("div", { className: 'flex-grow' })] })) })));
+};
+export var IconLabelButton = function (_a) {
+ var icon = _a.icon, label = _a.label, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.alignment, alignment = _c === void 0 ? 'left' : _c, onClick = _a.onClick;
+ return (_jsx("div", __assign({ className: 'pt-1 pb-1 active:pt-5px active:pb-3px rounded bg-opacity-0 focus:outline-none cursor-pointer ', onClick: onClick }, { children: _jsxs("div", __assign({ className: 'flex items-center' }, { children: [_jsx("div", __assign({ className: "".concat(alignment === 'left' ? '' : 'hidden') }, { children: _jsx("img", { className: 'mr-2 -mt-2px', src: icon, alt: label }) })), _jsx("div", __assign({ className: 'focus:outline-none' }, { children: _jsx("div", __assign({ className: 'flex flex-col justify-center h-full items-center' }, { children: _jsx("div", __assign({ className: "flex-wrap text-button font-button ".concat(color) }, { children: label })) })) })), _jsx("div", __assign({ className: "".concat(alignment !== 'left' ? '' : 'hidden') }, { children: _jsx("img", { className: 'ml-2 -mt-2px', src: icon, alt: label }) }))] })) })));
};
export var LabelButton = function (_a) {
var label = _a.label, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, onClick = _a.onClick;
diff --git a/dist/framework/visualisation/react/ui/elements/header.js b/dist/framework/visualisation/react/ui/elements/header.js
index 0252b769..912419fe 100644
--- a/dist/framework/visualisation/react/ui/elements/header.js
+++ b/dist/framework/visualisation/react/ui/elements/header.js
@@ -1,6 +1,6 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { Translator } from '../../../../translator';
-import { Title0 } from './text';
+import { Title1 } from './text';
function prepareCopy(_a) {
var title = _a.title, locale = _a.locale;
return {
@@ -9,5 +9,5 @@ function prepareCopy(_a) {
}
export var Header = function (props) {
var title = prepareCopy(props).title;
- return (_jsx(Title0, { text: title }));
+ return (_jsx(Title1, { text: title }));
};
diff --git a/dist/framework/visualisation/react/ui/elements/instructions.d.ts b/dist/framework/visualisation/react/ui/elements/instructions.d.ts
new file mode 100644
index 00000000..e5abffc2
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/elements/instructions.d.ts
@@ -0,0 +1,8 @@
+///
+import { ReactFactoryContext } from '../../factory';
+interface InstructionsProps {
+ platform: string;
+}
+declare type Props = InstructionsProps & ReactFactoryContext;
+export declare const Instructions: (props: Props) => JSX.Element;
+export {};
diff --git a/dist/framework/visualisation/react/ui/elements/instructions.js b/dist/framework/visualisation/react/ui/elements/instructions.js
new file mode 100644
index 00000000..2b458213
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/elements/instructions.js
@@ -0,0 +1,59 @@
+var __assign = (this && this.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
+import { Translator } from '../../../../translator';
+import { BodyMedium, Title3 } from './text';
+import TwitterSvg from '../../../../../assets/images/twitter.svg';
+import FacebookSvg from '../../../../../assets/images/facebook.svg';
+import InstagramSvg from '../../../../../assets/images/instagram.svg';
+import YoutubeSvg from '../../../../../assets/images/youtube.svg';
+import TextBundle from '../../../../text_bundle';
+export var Instructions = function (props) {
+ var _a = prepareCopy(props), title = _a.title, text = _a.text;
+ var platform = props.platform.toLowerCase();
+ return (_jsxs("div", __assign({ className: 'flex flex-col gap-6 p-8 border-2 border-grey4 rounded' }, { children: [_jsxs("div", __assign({ className: 'flex flex-row gap-8 items-center' }, { children: [_jsx("div", __assign({ className: 'flex-grow' }, { children: _jsx(Title3, { text: title, margin: '' }) })), _jsx("div", __assign({ className: 'h-12' }, { children: _jsx("img", { className: 'h-12', src: icon[platform] }) }))] })), _jsx(BodyMedium, { text: text, color: 'text-grey2', margin: '' })] })));
+};
+function prepareCopy(_a) {
+ var platform = _a.platform, locale = _a.locale;
+ var textBundle = text[platform.toLowerCase()];
+ return {
+ title: Translator.translate(title, locale),
+ text: Translator.translate(textBundle, locale)
+ };
+}
+var title = new TextBundle()
+ .add('en', 'Instructions')
+ .add('nl', 'Instructies');
+var twitterText = new TextBundle()
+ .add('en', 'If you have received an email with a link to your data from Twitter. Then click on the link and save the file. If you then select this file, profiling information will be extracted from it, which you can then view and donate.')
+ .add('nl', 'Als je een email met een link naar jouw gegevens hebt ontvangen van Twitter. Klik dan op de link en sla het bestand op. Als u dit bestand vervolgens selecteert dan wordt daar profiling informatie uit gehaald, die u vervolgens kunt bekijken en doneren.');
+var facebookText = new TextBundle()
+ .add('en', 'If you have received an email with a link to your data from Facebook. Then click on the link and save the file. If you then select this file, profiling information will be extracted from it, which you can then view and donate.')
+ .add('nl', 'Als je een email met een link naar jouw gegevens hebt ontvangen van Facebook. Klik dan op de link en sla het bestand op. Als u dit bestand vervolgens selecteert dan wordt daar profiling informatie uit gehaald, die u vervolgens kunt bekijken en doneren.');
+var instagramText = new TextBundle()
+ .add('en', 'If you have received an email with a link to your data from Instagram. Then click on the link and save the file. If you then select this file, profiling information will be extracted from it, which you can then view and donate.')
+ .add('nl', 'Als je een email met een link naar jouw gegevens hebt ontvangen van Instagram. Klik dan op de link en sla het bestand op. Als u dit bestand vervolgens selecteert dan wordt daar profiling informatie uit gehaald, die u vervolgens kunt bekijken en doneren.');
+var youtubeText = new TextBundle()
+ .add('en', 'If you have received an email with a link to your data from Google. Then click on the link and save the file. If you then select this file, profiling information will be extracted from it, which you can then view and donate.')
+ .add('nl', 'Als je een email met een link naar jouw gegevens hebt ontvangen van Google. Klik dan op de link en sla het bestand op. Als u dit bestand vervolgens selecteert dan wordt daar profiling informatie uit gehaald, die u vervolgens kunt bekijken en doneren.');
+var text = {
+ twitter: twitterText,
+ facebook: facebookText,
+ instagram: instagramText,
+ youtube: youtubeText
+};
+var icon = {
+ twitter: TwitterSvg,
+ facebook: FacebookSvg,
+ instagram: InstagramSvg,
+ youtube: YoutubeSvg
+};
diff --git a/dist/framework/visualisation/react/ui/elements/page_icon.d.ts b/dist/framework/visualisation/react/ui/elements/page_icon.d.ts
new file mode 100644
index 00000000..ae40a797
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/elements/page_icon.d.ts
@@ -0,0 +1,9 @@
+///
+interface PropsUIPageIcon {
+ index: number;
+ selected: boolean;
+ onClick: () => void;
+}
+declare type Props = PropsUIPageIcon;
+export declare const PageIcon: ({ index, selected, onClick }: Props) => JSX.Element;
+export {};
diff --git a/dist/framework/visualisation/react/ui/elements/page_icon.js b/dist/framework/visualisation/react/ui/elements/page_icon.js
new file mode 100644
index 00000000..2d52fb3c
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/elements/page_icon.js
@@ -0,0 +1,23 @@
+var __assign = (this && this.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+import { jsx as _jsx } from "react/jsx-runtime";
+export var PageIcon = function (_a) {
+ var index = _a.index, selected = _a.selected, onClick = _a.onClick;
+ function width() {
+ if (index > 999)
+ return 'w-10';
+ if (index > 99)
+ return 'w-9';
+ return 'w-8';
+ }
+ return (_jsx("div", __assign({ className: "rounded ".concat(width(), " h-8 cursor-pointer flex-shrink-0 overflow-hidden ").concat(selected ? 'bg-primary' : 'bg-grey5 '), onClick: onClick }, { children: _jsx("div", __assign({ className: 'flex flex-row items-center justify-center w-full h-full' }, { children: _jsx("div", __assign({ className: "text-label font-label ".concat(selected ? 'text-white' : 'text-grey2') }, { children: "".concat(index) })) })) })));
+};
diff --git a/dist/framework/visualisation/react/ui/elements/progress.d.ts b/dist/framework/visualisation/react/ui/elements/progress.d.ts
new file mode 100644
index 00000000..b8d3b69a
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/elements/progress.d.ts
@@ -0,0 +1,6 @@
+///
+import { Weak } from '../../../../helpers';
+import { PropsUIProgress } from '../../../../types/elements';
+declare type Props = Weak;
+export declare const Progress: ({ percentage }: Props) => JSX.Element;
+export {};
diff --git a/dist/framework/visualisation/react/ui/elements/progress.js b/dist/framework/visualisation/react/ui/elements/progress.js
new file mode 100644
index 00000000..0802dc2c
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/elements/progress.js
@@ -0,0 +1,16 @@
+var __assign = (this && this.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
+export var Progress = function (_a) {
+ var percentage = _a.percentage;
+ return (_jsxs("div", __assign({ id: 'progress', className: 'relative w-full overflow-hidden rounded-full' }, { children: [_jsx("div", __assign({ className: 'flex flex-row items-center gap-4' }, { children: _jsx("div", { className: 'flex-grow h-4 bg-primarylight' }) })), _jsx("div", { className: 'absolute top-0 h-4 bg-primary', style: { width: "".concat(percentage, "%") } })] })));
+};
diff --git a/dist/framework/visualisation/react/ui/elements/table.d.ts b/dist/framework/visualisation/react/ui/elements/table.d.ts
index 4fbe9593..1db63268 100644
--- a/dist/framework/visualisation/react/ui/elements/table.d.ts
+++ b/dist/framework/visualisation/react/ui/elements/table.d.ts
@@ -1,9 +1,10 @@
///
import { Weak } from '../../../../helpers';
import { PropsUITable, PropsUITableRow } from '../../../../types/elements';
-declare type Props = Weak & TableContext;
+import { ReactFactoryContext } from '../../factory';
+declare type Props = Weak & TableContext & ReactFactoryContext;
export interface TableContext {
onChange: (id: string, rows: PropsUITableRow[]) => void;
}
-export declare const Table: ({ id, head, body, readOnly, pageSize, onChange }: Props) => JSX.Element;
+export declare const Table: ({ id, head, body, readOnly, pageSize, locale, onChange }: Props) => JSX.Element;
export {};
diff --git a/dist/framework/visualisation/react/ui/elements/table.js b/dist/framework/visualisation/react/ui/elements/table.js
index b3d04baa..dbd902a6 100644
--- a/dist/framework/visualisation/react/ui/elements/table.js
+++ b/dist/framework/visualisation/react/ui/elements/table.js
@@ -12,91 +12,180 @@ var __assign = (this && this.__assign) || function () {
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
import _ from 'lodash';
import React from 'react';
-import { BackButton, ForwardButton, PrimaryButton, SecondaryButton } from './button';
+import TextBundle from '../../../../text_bundle';
+import { Translator } from '../../../../translator';
+import { BackIconButton, ForwardIconButton, IconLabelButton } from './button';
import { CheckBox } from './check_box';
import { SearchBar } from './search_bar';
-import { BodyLarge, BodyMedium, Title6 } from './text';
+import { Caption, Label, Title3 } from './text';
+import UndoSvg from '../../../../../assets/images/undo.svg';
+import DeleteSvg from '../../../../../assets/images/delete.svg';
+import { PageIcon } from './page_icon';
export var Table = function (_a) {
- var id = _a.id, head = _a.head, body = _a.body, _b = _a.readOnly, readOnly = _b === void 0 ? false : _b, _c = _a.pageSize, pageSize = _c === void 0 ? 7 : _c, onChange = _a.onChange;
- var _d = React.useState(false), editMode = _d[0], setEditMode = _d[1];
- var _e = React.useState([]), query = _e[0], setQuery = _e[1];
- var _f = React.useState(body.rows), alteredRows = _f[0], setAlteredRows = _f[1];
- var _g = React.useState(alteredRows), filteredRows = _g[0], setFilteredRows = _g[1];
- var _h = React.useState(createPages(filteredRows)), pages = _h[0], setPages = _h[1];
- var _j = React.useState(pages[0]), currentPage = _j[0], setCurrentPage = _j[1];
- var _k = React.useState([]), selectedRows = _k[0], setSelectedRows = _k[1];
- function createPages(rows) {
- if (rows.length === 0) {
- return [{ index: 0, rows: rows }];
+ var id = _a.id, head = _a.head, body = _a.body, _b = _a.readOnly, readOnly = _b === void 0 ? false : _b, _c = _a.pageSize, pageSize = _c === void 0 ? 7 : _c, locale = _a.locale, onChange = _a.onChange;
+ var pageWindowlegSize = 3;
+ var query = React.useRef([]);
+ var alteredRows = React.useRef(body.rows);
+ var filteredRows = React.useRef(alteredRows.current);
+ var initialState = {
+ edit: false,
+ pageCount: getPageCount(),
+ page: 0,
+ pageWindow: updatePageWindow(0),
+ rows: updateRows(0),
+ selected: [],
+ deletedCount: 0,
+ visibility: {
+ search: alteredRows.current.length > pageSize,
+ delete: false,
+ undo: false,
+ table: filteredRows.current.length > 0,
+ noData: filteredRows.current.length === 0,
+ noDataLeft: false,
+ noResults: false
}
- return _
- .range(0, Math.ceil(rows.length / pageSize))
- .map(function (index) { return { index: index, rows: createPage(index, rows) }; });
+ };
+ var _d = React.useState(initialState), state = _d[0], setState = _d[1];
+ var copy = prepareCopy(locale);
+ function display(element) {
+ return visible(element) ? '' : 'hidden';
}
- function createPage(page, rows) {
- var offset = page * pageSize;
- return rows.slice(offset, offset + pageSize);
+ function visible(element) {
+ if (typeof state.visibility[element] === 'boolean') {
+ return state.visibility[element];
+ }
+ return false;
+ }
+ function updatePageWindow(currentPage) {
+ var pageWindowSize = (pageWindowlegSize * 2) + 1;
+ var pageCount = getPageCount();
+ var range = [];
+ if (pageWindowSize >= pageCount && pageCount > 0) {
+ range = _.range(0, Math.min(pageCount, pageWindowSize));
+ }
+ else if (pageWindowSize < pageCount) {
+ var maxIndex = pageCount - 1;
+ var start = void 0;
+ var end = void 0;
+ if (currentPage < pageWindowlegSize) {
+ // begin
+ start = 0;
+ end = Math.min(pageCount, pageWindowSize);
+ }
+ else if (maxIndex - currentPage <= pageWindowlegSize) {
+ // end
+ start = maxIndex - (pageWindowSize - 1);
+ end = maxIndex + 1;
+ }
+ else {
+ // middle
+ start = currentPage - pageWindowlegSize;
+ end = currentPage + pageWindowlegSize + 1;
+ }
+ range = _.range(start, end);
+ }
+ return range;
+ }
+ function getPageCount() {
+ if (filteredRows.current.length === 0) {
+ return 0;
+ }
+ return Math.ceil(filteredRows.current.length / pageSize);
+ }
+ function updateRows(currentPage) {
+ var offset = currentPage * pageSize;
+ return filteredRows.current.slice(offset, offset + pageSize);
}
function renderHeadRow(props) {
- return (_jsxs("tr", { children: [editMode ? renderHeadCheck() : '', props.cells.map(function (cell, index) { return renderHeadCell(cell, index); })] }));
+ return (_jsxs("tr", { children: [state.edit ? renderHeadCheck() : '', props.cells.map(function (cell, index) { return renderHeadCell(cell, index); })] }));
}
function renderHeadCheck() {
- var selected = selectedRows.length > 0 && selectedRows.length === currentPage.rows.length;
- return (_jsx("td", { children: _jsx(CheckBox, { id: '-1', selected: selected, onSelect: function () { return handleSelectHead(); } }) }, 'check-head'));
+ var selected = state.selected.length > 0 && state.selected.length === state.rows.length;
+ return (_jsx("td", __assign({ className: 'pl-4 w-10' }, { children: _jsx(CheckBox, { id: '-1', selected: selected, onSelect: function () { return handleSelectHead(); } }) }), 'check-head'));
}
function renderHeadCell(props, index) {
- return (_jsx("th", __assign({ className: 'px-2 pt-3 pb-13px text-left' }, { children: _jsx(Title6, { text: props.text, margin: '' }) }), "".concat(index)));
+ return (_jsx("th", __assign({ className: 'h-12 px-4 text-left' }, { children: _jsx("div", __assign({ className: 'font-table-header text-table text-grey1' }, { children: props.text })) }), "".concat(index)));
}
- function renderRows(rows) {
- return rows.map(function (row, index) { return renderRow(row, index); });
+ function renderRows() {
+ return state.rows.map(function (row, index) { return renderRow(row, index); });
}
function renderRow(row, rowIndex) {
- return (_jsxs("tr", __assign({ className: 'hover:bg-grey5' }, { children: [editMode ? renderRowCheck(row.id) : '', row.cells.map(function (cell, cellIndex) { return renderRowCell(cell, cellIndex); })] }), "".concat(rowIndex)));
+ return (_jsxs("tr", __assign({ className: 'hover:bg-grey6' }, { children: [state.edit ? renderRowCheck(row.id) : '', row.cells.map(function (cell, cellIndex) { return renderRowCell(cell, cellIndex); })] }), "".concat(rowIndex)));
}
function renderRowCheck(rowId) {
- var selected = selectedRows.includes(rowId);
- return (_jsx("td", __assign({ className: 'w-8 min-w-8' }, { children: _jsx(CheckBox, { id: rowId, selected: selected, onSelect: function () { return handleSelectRow(rowId); } }) }), "check-".concat(rowId)));
+ var selected = state.selected.includes(rowId);
+ return (_jsx("td", __assign({ className: 'pl-4' }, { children: _jsx(CheckBox, { id: rowId, selected: selected, onSelect: function () { return handleSelectRow(rowId); } }) }), "check-".concat(rowId)));
}
function renderRowCell(props, cellIndex) {
- return (_jsx("td", __assign({ className: 'px-2 pt-3 pb-13px' }, { children: _jsx(BodyMedium, { text: props.text, margin: '' }) }), "".concat(cellIndex)));
+ return (_jsx("td", __assign({ className: 'h-12 px-4' }, { children: _jsx("div", __assign({ className: 'font-table-row text-table text-grey1' }, { children: props.text })) }), "".concat(cellIndex)));
+ }
+ function renderPageIcons() {
+ return (_jsx("div", __assign({ className: 'flex flex-row gap-2' }, { children: state.pageWindow.map(function (page) { return renderPageIcon(page); }) })));
+ }
+ function renderPageIcon(index) {
+ return _jsx(PageIcon, { index: index + 1, selected: state.page === index, onClick: function () { return handleNewPage(index); } }, "page-".concat(index));
+ }
+ function filterRows() {
+ if (query.current.length === 0) {
+ return alteredRows.current;
+ }
+ return alteredRows.current.filter(function (row) { return matchRow(row, query.current); });
+ }
+ function matchRow(row, query) {
+ var rowText = row.cells.map(function (cell) { return cell.text; }).join(' ');
+ return query.find(function (word) { return !rowText.includes(word); }) === undefined;
}
function handleSelectHead() {
- var allRowsSelected = selectedRows.length === currentPage.rows.length;
+ var allRowsSelected = state.selected.length === state.rows.length;
if (allRowsSelected) {
- setSelectedRows([]);
+ setState(function (state) {
+ return __assign(__assign({}, state), { selected: [] });
+ });
}
else {
handleSelectAll();
}
}
function handleSelectRow(rowId) {
- var newSelected = selectedRows.slice(0);
- var index = selectedRows.indexOf(rowId);
- if (index === -1) {
- newSelected.push(rowId);
- }
- else {
- newSelected.splice(index, 1);
- }
- setSelectedRows(newSelected);
+ setState(function (state) {
+ var selected = state.selected.slice(0);
+ var index = selected.indexOf(rowId);
+ if (index === -1) {
+ selected.push(rowId);
+ }
+ else {
+ selected.splice(index, 1);
+ }
+ return __assign(__assign({}, state), { selected: selected });
+ });
}
function handleSelectAll() {
- var allRowIds = currentPage.rows.map(function (row) { return row.id; });
- setSelectedRows(allRowIds);
+ setState(function (state) {
+ var selected = state.rows.map(function (row) { return row.id; });
+ return __assign(__assign({}, state), { selected: selected });
+ });
}
function handlePrevious() {
- var index = currentPage.index === 0 ? pages.length - 1 : currentPage.index - 1;
- setSelectedRows([]);
- setCurrentPage(pages[index]);
+ setState(function (state) {
+ var page = state.page === 0 ? state.pageCount - 1 : state.page - 1;
+ var pageWindow = updatePageWindow(page);
+ var rows = updateRows(page);
+ return __assign(__assign({}, state), { page: page, pageWindow: pageWindow, rows: rows });
+ });
}
function handleNext() {
- var index = currentPage.index === pages.length - 1 ? 0 : currentPage.index + 1;
- setSelectedRows([]);
- setCurrentPage(pages[index]);
+ setState(function (state) {
+ var page = state.page === state.pageCount - 1 ? 0 : state.page + 1;
+ var pageWindow = updatePageWindow(page);
+ var rows = updateRows(page);
+ return __assign(__assign({}, state), { page: page, pageWindow: pageWindow, rows: rows });
+ });
}
function handleDeleteSelected() {
- var currentSelectedRows = selectedRows.slice(0);
- var newAlteredRows = alteredRows.slice(0);
+ var currentSelectedRows = state.selected.slice(0);
+ if (currentSelectedRows.length === 0)
+ return;
+ var newAlteredRows = alteredRows.current.slice(0);
var _loop_1 = function (rowId) {
var index = newAlteredRows.findIndex(function (row) { return row.id === rowId; });
if (index !== -1) {
@@ -107,36 +196,127 @@ export var Table = function (_a) {
var rowId = currentSelectedRows_1[_i];
_loop_1(rowId);
}
- updateAlteredRows(newAlteredRows, query);
- }
- function updateAlteredRows(alteredRows, query) {
- var filteredRows = filterRows(alteredRows, query);
- var newPages = createPages(filteredRows);
- var newCurrentPageIndex = Math.min(newPages.length, currentPage.index);
- var newCurrentPage = newPages[newCurrentPageIndex];
- setAlteredRows(alteredRows);
- setFilteredRows(filteredRows);
- setPages(newPages);
- setCurrentPage(newCurrentPage);
- setSelectedRows([]);
- onChange(id, alteredRows);
- }
- function filterRows(rows, query) {
- if (query.length === 0) {
- return rows;
- }
- return rows.filter(function (row) { return matchRow(row, query); });
- }
- function matchRow(row, query) {
- var rowText = row.cells.map(function (cell) { return cell.text; }).join(' ');
- return query.find(function (word) { return !rowText.includes(word); }) === undefined;
+ alteredRows.current = newAlteredRows;
+ filteredRows.current = filterRows();
+ setState(function (state) {
+ var pageCount = getPageCount();
+ var page = Math.max(0, Math.min(pageCount - 1, state.page));
+ var pageWindow = updatePageWindow(page);
+ var rows = updateRows(page);
+ var deletedCount = body.rows.length - alteredRows.current.length;
+ var visibility = __assign(__assign({}, state.visibility), { undo: deletedCount > 0, table: filteredRows.current.length > 0, noData: false, noDataLeft: alteredRows.current.length === 0, noResults: alteredRows.current.length > 0 && filteredRows.current.length === 0 });
+ return __assign(__assign({}, state), { page: page, pageCount: pageCount, pageWindow: pageWindow, rows: rows, deletedCount: deletedCount, selected: [], visibility: visibility });
+ });
+ onChange(id, alteredRows.current);
}
function handleUndo() {
- updateAlteredRows(body.rows, query);
+ alteredRows.current = body.rows;
+ filteredRows.current = filterRows();
+ setState(function (state) {
+ var pageCount = getPageCount();
+ var page = Math.min(pageCount, state.page);
+ var pageWindow = updatePageWindow(page);
+ var rows = updateRows(state.page);
+ var visibility = __assign(__assign({}, state.visibility), { undo: false, table: filteredRows.current.length > 0, noData: false, noDataLeft: false, noResults: filteredRows.current.length === 0 });
+ return __assign(__assign({}, state), { page: page, pageCount: pageCount, pageWindow: pageWindow, rows: rows, deletedCount: 0, selected: [], visibility: visibility });
+ });
+ onChange(id, body.rows);
}
- function handleSearch(query) {
- setQuery(query);
- updateAlteredRows(alteredRows, query);
+ function handleSearch(newQuery) {
+ query.current = newQuery;
+ filteredRows.current = filterRows();
+ setState(function (state) {
+ var pageCount = getPageCount();
+ var page = Math.min(pageCount, state.page);
+ var pageWindow = updatePageWindow(page);
+ var rows = updateRows(state.page);
+ var visibility = __assign(__assign({}, state.visibility), { table: filteredRows.current.length > 0, noData: body.rows.length === 0, noDataLeft: body.rows.length > 0 && alteredRows.current.length === 0, noResults: body.rows.length > 0 && alteredRows.current.length > 0 && filteredRows.current.length === 0 });
+ return __assign(__assign({}, state), { page: page, pageCount: pageCount, pageWindow: pageWindow, rows: rows, visibility: visibility });
+ });
+ }
+ function handleNewPage(page) {
+ setState(function (state) {
+ var rows = updateRows(page);
+ return __assign(__assign({}, state), { page: page, rows: rows });
+ });
+ }
+ function handleEditToggle() {
+ setState(function (state) {
+ var edit = !state.edit;
+ var visibility = __assign(__assign({}, state.visibility), { delete: edit });
+ return __assign(__assign({}, state), { edit: edit, visibility: visibility });
+ });
+ }
+ return (_jsxs(_Fragment, { children: [_jsxs("div", __assign({ className: 'flex flex-row gap-4 items-center' }, { children: [_jsxs("div", __assign({ className: "flex flex-row items-center gap-2 mt-2 ".concat(body.rows.length <= pageSize ? 'hidden' : '', " ") }, { children: [_jsx(BackIconButton, { onClick: handlePrevious }), _jsx("div", { children: renderPageIcons() }), _jsx(ForwardIconButton, { onClick: handleNext })] })), _jsx("div", { className: 'flex-grow' }), _jsx(Caption, { text: copy.pages, color: 'text-grey2', margin: '' }), _jsx("div", __assign({ className: "".concat(display('search')) }, { children: _jsx(SearchBar, { placeholder: copy.searchPlaceholder, onSearch: function (query) { return handleSearch(query); } }) }))] })), _jsx("div", __assign({ className: "flex flex-col gap-4 justify-center h-full ".concat(display('table')) }, { children: _jsxs("table", __assign({ className: 'text-grey1 table-fixed divide-y divide-grey4' }, { children: [_jsx("thead", { children: renderHeadRow(head) }), _jsx("tbody", __assign({ className: 'divide-y divide-grey4' }, { children: renderRows() }))] })) })), _jsx("div", __assign({ className: "flex flex-col justify-center items-center w-full h-table bg-grey6 ".concat(display('noData')) }, { children: _jsx(Title3, { text: copy.noData, color: 'text-grey3', margin: '' }) })), _jsx("div", __assign({ className: "flex flex-col justify-center items-center w-full h-table bg-grey6 ".concat(display('noDataLeft')) }, { children: _jsx(Title3, { text: copy.noDataLeft, color: 'text-grey3', margin: '' }) })), _jsx("div", __assign({ className: "flex flex-col justify-center items-center w-full h-table bg-grey6 ".concat(display('noResults')) }, { children: _jsx(Title3, { text: copy.noResults, color: 'text-grey3', margin: '' }) })), _jsxs("div", __assign({ className: "flex flex-row items-center gap-6 mt-2 h-8 ".concat(body.rows.length === 0 ? 'hidden' : '', " ") }, { children: [_jsxs("div", __assign({ className: 'flex flex-row gap-4 items-center' }, { children: [_jsx(CheckBox, { id: 'edit', selected: state.edit, onSelect: handleEditToggle }), _jsx(Label, { text: copy.edit, margin: 'mt-1px' })] })), _jsx("div", __assign({ className: "".concat(display('delete'), " mt-1px") }, { children: _jsx(IconLabelButton, { label: copy.delete, color: 'text-delete', icon: DeleteSvg, onClick: handleDeleteSelected }) })), _jsx("div", { className: 'flex-grow' }), _jsx(Label, { text: copy.deleted }), _jsx("div", __assign({ className: "".concat(display('undo')) }, { children: _jsx(IconLabelButton, { label: copy.undo, color: 'text-primary', icon: UndoSvg, onClick: handleUndo }) }))] }))] }));
+ function prepareCopy(locale) {
+ return {
+ edit: Translator.translate(editLabel, locale),
+ undo: Translator.translate(undoLabel, locale),
+ noData: Translator.translate(noDataLabel, locale),
+ noDataLeft: Translator.translate(noDataLeftLabel, locale),
+ noResults: Translator.translate(noResultsLabel, locale),
+ pages: Translator.translate(pagesLabel(state.pageCount), locale),
+ delete: Translator.translate(deleteLabel, locale),
+ deleted: Translator.translate(deletedLabel(body.rows.length - alteredRows.current.length), locale),
+ searchPlaceholder: Translator.translate(searchPlaceholder, locale)
+ };
}
- return (_jsxs(_Fragment, { children: [_jsxs("div", __assign({ className: 'flex flex-row gap-4' }, { children: [_jsx("div", __assign({ className: "".concat(!editMode && !readOnly ? '' : 'hidden') }, { children: _jsx(PrimaryButton, { label: 'Edit', onClick: function () { return setEditMode(true); }, color: 'bg-delete text-white' }) })), _jsx("div", __assign({ className: "".concat(editMode ? '' : 'hidden') }, { children: _jsx(PrimaryButton, { label: 'Select all', onClick: handleSelectAll }) })), _jsx("div", __assign({ className: "".concat(editMode ? '' : 'hidden') }, { children: _jsx(SecondaryButton, { label: 'Delete', onClick: handleDeleteSelected }) })), _jsx("div", __assign({ className: "".concat(editMode && body.rows.length > 0 ? '' : 'hidden') }, { children: _jsx(SecondaryButton, { label: 'Undo', onClick: handleUndo, color: 'text-grey1' }) })), _jsx("div", __assign({ className: "".concat(alteredRows.length > pageSize ? '' : 'hidden') }, { children: _jsx(SearchBar, { placeholder: 'Search', onSearch: handleSearch }) }))] })), _jsxs("div", __assign({ className: "".concat(filteredRows.length === 0 ? 'hidden' : '') }, { children: [_jsxs("table", __assign({ className: 'text-grey1 table-auto ' }, { children: [_jsx("thead", { children: renderHeadRow(head) }), _jsx("tbody", { children: renderRows(currentPage.rows) })] })), _jsxs("div", __assign({ className: "flex flex-row gap-4 mt-2 ".concat(filteredRows.length <= pageSize ? 'hidden' : '', " ") }, { children: [_jsx(BackButton, { label: 'Previous', onClick: handlePrevious }), _jsxs("div", { children: [currentPage.index + 1, " / ", pages.length] }), _jsx(ForwardButton, { label: 'Next', onClick: handleNext })] }))] })), _jsx("div", __assign({ className: "flex flex-col ".concat(alteredRows.length === 0 ? '' : 'hidden') }, { children: _jsx(BodyLarge, { text: 'Empty data set', margin: '' }) })), _jsx("div", __assign({ className: "flex flex-col ".concat(alteredRows.length > 0 && filteredRows.length === 0 ? '' : 'hidden') }, { children: _jsx(BodyLarge, { text: 'Nothing found', margin: '' }) }))] }));
};
+var searchPlaceholder = new TextBundle()
+ .add('en', 'Search')
+ .add('nl', 'Zoeken');
+var noDataLabel = new TextBundle()
+ .add('en', 'No information found')
+ .add('nl', 'Geen informatie gevonden');
+var noDataLeftLabel = new TextBundle()
+ .add('en', 'No information left')
+ .add('nl', 'Geen informatie overgebleven');
+var noResultsLabel = new TextBundle()
+ .add('en', 'No search results')
+ .add('nl', 'Geen zoek resultaten');
+var editLabel = new TextBundle()
+ .add('en', 'Edit table')
+ .add('nl', 'Bewerk tabel');
+var undoLabel = new TextBundle()
+ .add('en', 'Undo')
+ .add('nl', 'Herstel');
+var deleteLabel = new TextBundle()
+ .add('en', 'Delete selected')
+ .add('nl', 'Verwijder geselecteerde');
+function deletedNoneRowLabel() {
+ return new TextBundle()
+ .add('en', 'No changes made')
+ .add('nl', 'Geen aanpassingen');
+}
+function deletedRowLabel(amount) {
+ return new TextBundle()
+ .add('en', "You deleted ".concat(amount, " row"))
+ .add('nl', "Je hebt ".concat(amount, " rij verwijderd"));
+}
+function deletedRowsLabel(amount) {
+ return new TextBundle()
+ .add('en', "You deleted ".concat(amount, " rows"))
+ .add('nl', "Je hebt ".concat(amount, " rijen verwijderd"));
+}
+function deletedLabel(amount) {
+ if (amount === 0)
+ return deletedNoneRowLabel();
+ if (amount === 1)
+ return deletedRowLabel(amount);
+ return deletedRowsLabel(amount);
+}
+function singlePageLabel() {
+ return new TextBundle()
+ .add('en', '1 page')
+ .add('nl', '1 pagina');
+}
+function multiplePagesLabel(amount) {
+ return new TextBundle()
+ .add('en', "".concat(amount, " pages"))
+ .add('nl', "".concat(amount, " pagina's"));
+}
+function pagesLabel(amount) {
+ if (amount === 1)
+ return singlePageLabel();
+ return multiplePagesLabel(amount);
+}
diff --git a/dist/framework/visualisation/react/ui/elements/text.d.ts b/dist/framework/visualisation/react/ui/elements/text.d.ts
index ad7fea77..357fff2c 100644
--- a/dist/framework/visualisation/react/ui/elements/text.d.ts
+++ b/dist/framework/visualisation/react/ui/elements/text.d.ts
@@ -1,10 +1,14 @@
///
import { Weak } from '../../../../helpers';
-import { PropsUITextBodyLarge, PropsUITextBodyMedium, PropsUITextLabel, PropsUITextTitle0, PropsUITextTitle1, PropsUITextTitle2, PropsUITextTitle6 } from '../../../../types/elements';
+import { PropsUITextBodyLarge, PropsUITextBodyMedium, PropsUITextBodySmall, PropsUITextLabel, PropsUITextCaption, PropsUITextTitle0, PropsUITextTitle1, PropsUITextTitle2, PropsUITextTitle3, PropsUITextTitle4, PropsUITextTitle6 } from '../../../../types/elements';
export declare const BodyLarge: ({ text, color, margin }: Weak) => JSX.Element;
export declare const BodyMedium: ({ text, color, margin }: Weak) => JSX.Element;
+export declare const BodySmall: ({ text, color, margin }: Weak) => JSX.Element;
export declare const Title0: ({ text, color, margin }: Weak) => JSX.Element;
export declare const Title1: ({ text, color, margin }: Weak) => JSX.Element;
export declare const Title2: ({ text, color, margin }: Weak) => JSX.Element;
+export declare const Title3: ({ text, color, margin }: Weak) => JSX.Element;
+export declare const Title4: ({ text, color, margin }: Weak) => JSX.Element;
export declare const Title6: ({ text, color, margin }: Weak) => JSX.Element;
export declare const Label: ({ text, color, margin }: Weak) => JSX.Element;
+export declare const Caption: ({ text, color, margin }: Weak) => JSX.Element;
diff --git a/dist/framework/visualisation/react/ui/elements/text.js b/dist/framework/visualisation/react/ui/elements/text.js
index 59a9112c..9a922335 100644
--- a/dist/framework/visualisation/react/ui/elements/text.js
+++ b/dist/framework/visualisation/react/ui/elements/text.js
@@ -18,18 +18,30 @@ export var BodyMedium = function (_a) {
var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? 'mb-6 md:mb-8 lg:mb-10' : _c;
return (_jsx("div", __assign({ className: "text-bodymedium font-body ".concat(color, " ").concat(margin) }, { children: text })));
};
+export var BodySmall = function (_a) {
+ var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? '' : _c;
+ return (_jsx("div", __assign({ className: "text-bodysmall font-body ".concat(color, " ").concat(margin) }, { children: text })));
+};
export var Title0 = function (_a) {
var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? 'mb-6 md:mb-8 lg:mb-10' : _c;
return (_jsx("div", __assign({ className: "text-title4 font-title4 sm:text-title2 sm:font-title2 lg:text-title0 lg:font-title0 ".concat(color, " ").concat(margin) }, { children: text })));
};
export var Title1 = function (_a) {
- var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? 'mb-6 md:mb-8 lg:mb-10' : _c;
+ var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? 'mb-6 md:mb-8' : _c;
return (_jsx("div", __assign({ className: "text-title3 font-title3 sm:text-title2 lg:text-title1 lg:font-title1 ".concat(color, " ").concat(margin) }, { children: text })));
};
export var Title2 = function (_a) {
var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? 'mb-6 md:mb-8 lg:mb-10' : _c;
return (_jsx("div", __assign({ className: "text-title4 font-title4 sm:text-title3 sm:font-title3 lg:text-title2 lg:font-title2 ".concat(color, " ").concat(margin) }, { children: text })));
};
+export var Title3 = function (_a) {
+ var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? 'mb-3 md:mb-5 lg:mb-6' : _c;
+ return (_jsx("div", __assign({ className: "text-title5 font-title5 sm:text-title4 sm:font-title4 lg:text-title3 lg:font-title3 ".concat(color, " ").concat(margin) }, { children: text })));
+};
+export var Title4 = function (_a) {
+ var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? 'mb-3 md:mb-5 lg:mb-6' : _c;
+ return (_jsx("div", __assign({ className: "text-title6 font-title6 sm:text-title5 sm:font-title5 lg:text-title4 lg:font-title4 ".concat(color, " ").concat(margin) }, { children: text })));
+};
export var Title6 = function (_a) {
var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? 'mb-2' : _c;
return (_jsx("div", __assign({ className: "text-title6 font-title6 ".concat(margin, " ").concat(color) }, { children: text })));
@@ -38,3 +50,7 @@ export var Label = function (_a) {
var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? '' : _c;
return (_jsx("div", __assign({ className: "text-label font-label ".concat(color, " ").concat(margin) }, { children: text })));
};
+export var Caption = function (_a) {
+ var text = _a.text, _b = _a.color, color = _b === void 0 ? 'text-grey1' : _b, _c = _a.margin, margin = _c === void 0 ? '' : _c;
+ return (_jsx("div", __assign({ className: "text-caption font-caption ".concat(color, " ").concat(margin) }, { children: text })));
+};
diff --git a/dist/framework/visualisation/react/ui/pages/donation_page.js b/dist/framework/visualisation/react/ui/pages/donation_page.js
index 95fa7a28..37d2e845 100644
--- a/dist/framework/visualisation/react/ui/pages/donation_page.js
+++ b/dist/framework/visualisation/react/ui/pages/donation_page.js
@@ -14,15 +14,21 @@ import TextBundle from '../../../../text_bundle';
import { Translator } from '../../../../translator';
import { isPropsUIPromptConfirm, isPropsUIPromptConsentForm, isPropsUIPromptFileInput } from '../../../../types/prompts';
import { ForwardButton } from '../elements/button';
-import { Title0 } from '../elements/text';
+import { Title1 } from '../elements/text';
import { Confirm } from '../prompts/confirm';
import { ConsentForm } from '../prompts/consent_form';
import { FileInput } from '../prompts/file_input';
+import { Footer } from './templates/footer';
+import { Sidebar } from './templates/sidebar';
+import LogoSvg from '../../../../../assets/images/logo.svg';
+import { Page } from './templates/page';
+import { Progress } from '../elements/progress';
+import { Instructions } from '../elements/instructions';
export var DonationPage = function (props) {
var _a = prepareCopy(props), title = _a.title, forwardButton = _a.forwardButton;
- var resolve = props.resolve;
+ var platform = props.platform, locale = props.locale, resolve = props.resolve;
function renderBody(props) {
- var context = { locale: props.locale, resolve: props.resolve };
+ var context = { locale: locale, resolve: props.resolve };
var body = props.body;
if (isPropsUIPromptFileInput(body)) {
return _jsx(FileInput, __assign({}, body, context));
@@ -38,7 +44,10 @@ export var DonationPage = function (props) {
function handleSkip() {
resolve === null || resolve === void 0 ? void 0 : resolve({ __type__: 'PayloadFalse', value: false });
}
- return (_jsxs(_Fragment, { children: [_jsx(Title0, { text: title }), renderBody(props), _jsx("div", { className: 'mb-10' }), _jsxs("div", __assign({ className: 'flex flex-row gap-4 items-center w-full' }, { children: [_jsx("div", { className: 'flex-grow' }), _jsx(ForwardButton, { label: forwardButton, onClick: handleSkip })] }))] }));
+ var footer = (_jsx(Footer, { middle: _jsx(Progress, { percentage: props.footer.progressPercentage }), right: _jsxs("div", __assign({ className: 'flex flex-row' }, { children: [_jsx("div", { className: 'flex-grow' }), _jsx(ForwardButton, { label: forwardButton, onClick: handleSkip })] })) }));
+ var sidebar = (_jsx(Sidebar, { logo: LogoSvg, content: _jsx(Instructions, { platform: platform, locale: locale }) }));
+ var body = (_jsxs(_Fragment, { children: [_jsx(Title1, { text: title }), renderBody(props)] }));
+ return (_jsx(Page, { body: body, sidebar: sidebar, footer: footer }));
};
function prepareCopy(_a) {
var title = _a.header.title, locale = _a.locale;
@@ -49,6 +58,6 @@ function prepareCopy(_a) {
}
var forwardButtonLabel = function () {
return new TextBundle()
- .add('en', 'Skip this step')
- .add('nl', 'Sla deze stap over');
+ .add('en', 'Skip')
+ .add('nl', 'Overslaan');
};
diff --git a/dist/framework/visualisation/react/ui/pages/end_page.js b/dist/framework/visualisation/react/ui/pages/end_page.js
index b5aba48a..fd3e3135 100644
--- a/dist/framework/visualisation/react/ui/pages/end_page.js
+++ b/dist/framework/visualisation/react/ui/pages/end_page.js
@@ -1,16 +1,28 @@
-var __assign = (this && this.__assign) || function () {
- __assign = Object.assign || function(t) {
- for (var s, i = 1, n = arguments.length; i < n; i++) {
- s = arguments[i];
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
- t[p] = s[p];
- }
- return t;
- };
- return __assign.apply(this, arguments);
-};
-import { jsx as _jsx } from "react/jsx-runtime";
-import { Header } from '../elements/header';
+import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
+import { Footer } from './templates/footer';
+import { Sidebar } from './templates/sidebar';
+import LogoSvg from '../../../../../assets/images/logo.svg';
+import { Page } from './templates/page';
+import TextBundle from '../../../../text_bundle';
+import { Translator } from '../../../../translator';
+import { BodyLarge, Title1 } from '../elements/text';
export var EndPage = function (props) {
- return (_jsx(Header, __assign({}, props.header, { locale: props.locale })));
+ var _a = prepareCopy(props), title = _a.title, text = _a.text;
+ var footer = _jsx(Footer, {});
+ var sidebar = _jsx(Sidebar, { logo: LogoSvg });
+ var body = (_jsxs(_Fragment, { children: [_jsx(Title1, { text: title }), _jsx(BodyLarge, { text: text })] }));
+ return (_jsx(Page, { body: body, sidebar: sidebar, footer: footer }));
};
+function prepareCopy(_a) {
+ var locale = _a.locale;
+ return {
+ title: Translator.translate(title, locale),
+ text: Translator.translate(text, locale)
+ };
+}
+var title = new TextBundle()
+ .add('en', 'Thank you')
+ .add('nl', 'Bedankt');
+var text = new TextBundle()
+ .add('en', 'Thank you for your participation. You can now close this page or refresh the page to go through the flow again.')
+ .add('nl', 'Hartelijk dank voor uw deelname. U kunt deze pagina nu sluiten of de pagina verversen om de flow nogmaals te doorlopen.');
diff --git a/dist/framework/visualisation/react/ui/pages/splash_screen.js b/dist/framework/visualisation/react/ui/pages/splash_screen.js
index 486d9e4b..a49cca58 100644
--- a/dist/framework/visualisation/react/ui/pages/splash_screen.js
+++ b/dist/framework/visualisation/react/ui/pages/splash_screen.js
@@ -15,7 +15,11 @@ import TextBundle from '../../../../text_bundle';
import { Translator } from '../../../../translator';
import { PrimaryButton } from '../elements/button';
import { CheckBox } from '../elements/check_box';
-import { BodyLarge, Label, Title0 } from '../elements/text';
+import { BodyLarge, Label, Title1 } from '../elements/text';
+import LogoSvg from '../../../../../assets/images/logo.svg';
+import { Footer } from './templates/footer';
+import { Page } from './templates/page';
+import { Sidebar } from './templates/sidebar';
function prepareCopy(_a) {
var locale = _a.locale;
return {
@@ -39,7 +43,10 @@ export var SplashScreen = function (props) {
function handleCheck() {
setChecked(true);
}
- return (_jsxs(_Fragment, { children: [_jsx(Title0, { text: title }), _jsx(BodyLarge, { text: description }), _jsxs("div", __assign({ className: 'flex flex-col gap-8' }, { children: [_jsxs("div", __assign({ className: 'flex flex-row gap-4 items-center' }, { children: [_jsx(CheckBox, { id: '0', selected: checked, onSelect: function () { return handleCheck(); } }), _jsx(Label, { text: privacyLabel })] })), _jsx("div", __assign({ className: "flex flex-row gap-4 ".concat(checked ? '' : 'opacity-30') }, { children: _jsx(PrimaryButton, { label: continueButton, onClick: handleContinue, enabled: checked, spinning: waiting }) }))] }))] }));
+ var footer = _jsx(Footer, {});
+ var sidebar = _jsx(Sidebar, { logo: LogoSvg });
+ var body = (_jsxs(_Fragment, { children: [_jsx(Title1, { text: title }), _jsx(BodyLarge, { text: description }), _jsxs("div", __assign({ className: 'flex flex-col gap-8' }, { children: [_jsxs("div", __assign({ className: 'flex flex-row gap-4 items-center' }, { children: [_jsx(CheckBox, { id: '0', selected: checked, onSelect: function () { return handleCheck(); } }), _jsx(Label, { text: privacyLabel })] })), _jsx("div", __assign({ className: "flex flex-row gap-4 ".concat(checked ? '' : 'opacity-30') }, { children: _jsx(PrimaryButton, { label: continueButton, onClick: handleContinue, enabled: checked, spinning: waiting }) }))] }))] }));
+ return (_jsx(Page, { body: body, sidebar: sidebar, footer: footer }));
};
var title = new TextBundle()
.add('en', 'Welcome')
diff --git a/dist/framework/visualisation/react/ui/pages/start_page.d.ts b/dist/framework/visualisation/react/ui/pages/start_page.d.ts
deleted file mode 100644
index 7406f007..00000000
--- a/dist/framework/visualisation/react/ui/pages/start_page.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-///
-import { Weak } from '../../../../helpers';
-import { PropsUIPageStart } from '../../../../types/pages';
-import { ReactFactoryContext } from '../../factory';
-declare type Props = Weak & ReactFactoryContext;
-export declare const StartPage: (props: Props) => JSX.Element;
-export {};
diff --git a/dist/framework/visualisation/react/ui/pages/start_page.js b/dist/framework/visualisation/react/ui/pages/start_page.js
deleted file mode 100644
index 042cb85f..00000000
--- a/dist/framework/visualisation/react/ui/pages/start_page.js
+++ /dev/null
@@ -1,41 +0,0 @@
-var __assign = (this && this.__assign) || function () {
- __assign = Object.assign || function(t) {
- for (var s, i = 1, n = arguments.length; i < n; i++) {
- s = arguments[i];
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
- t[p] = s[p];
- }
- return t;
- };
- return __assign.apply(this, arguments);
-};
-import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
-import TextBundle from '../../../../text_bundle';
-import { Translator } from '../../../../translator';
-import { PrimaryButton } from '../elements/button';
-import { BodyLarge, Title0 } from '../elements/text';
-export var StartPage = function (props) {
- var resolve = props.resolve;
- var _a = prepareCopy(props), title = _a.title, description = _a.description, startButton = _a.startButton;
- function handleStart() {
- resolve === null || resolve === void 0 ? void 0 : resolve({ __type__: 'PayloadVoid', value: undefined });
- }
- return (_jsxs(_Fragment, { children: [_jsx(Title0, { text: title }), _jsx(BodyLarge, { text: description }), _jsx("div", __assign({ className: 'flex flex-row gap-4' }, { children: _jsx(PrimaryButton, { label: startButton, onClick: handleStart }) }))] }));
-};
-function prepareCopy(_a) {
- var locale = _a.locale;
- return {
- title: Translator.translate(title, locale),
- description: Translator.translate(description, locale),
- startButton: Translator.translate(startButtonLabel, locale)
- };
-}
-var title = new TextBundle()
- .add('en', 'Instructions')
- .add('nl', 'Instructies');
-var startButtonLabel = new TextBundle()
- .add('en', 'Start')
- .add('nl', 'Start');
-var description = new TextBundle()
- .add('en', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.')
- .add('nl', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.');
diff --git a/dist/framework/visualisation/react/ui/pages/templates/footer.d.ts b/dist/framework/visualisation/react/ui/pages/templates/footer.d.ts
new file mode 100644
index 00000000..e08c3640
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/pages/templates/footer.d.ts
@@ -0,0 +1,8 @@
+///
+interface FooterProps {
+ left?: JSX.Element;
+ middle?: JSX.Element;
+ right?: JSX.Element;
+}
+export declare const Footer: ({ left, middle, right }: FooterProps) => JSX.Element;
+export {};
diff --git a/dist/framework/visualisation/react/ui/pages/templates/footer.js b/dist/framework/visualisation/react/ui/pages/templates/footer.js
new file mode 100644
index 00000000..19e420eb
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/pages/templates/footer.js
@@ -0,0 +1,19 @@
+var __assign = (this && this.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
+function footerLinks() {
+ return (_jsxs("div", __assign({ className: 'flex flex-row gap-4 text-link font-link' }, { children: [_jsx("div", __assign({ className: ' text-primary underline' }, { children: _jsx("a", __assign({ href: 'https://eyra.co', target: '_blank', rel: 'noreferrer' }, { children: "Privacy" })) })), _jsx("div", { className: 'bg-grey3 w-1px' }), _jsx("div", __assign({ className: ' text-primary underline' }, { children: _jsx("a", __assign({ href: 'https://eyra.co', target: '_blank', rel: 'noreferrer' }, { children: "Support" })) }))] })));
+}
+export var Footer = function (_a) {
+ var _b = _a.left, left = _b === void 0 ? footerLinks() : _b, middle = _a.middle, right = _a.right;
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: 'bg-grey4 h-px' }), _jsx("div", __assign({ className: 'h-full flex flex-col justify-center' }, { children: _jsxs("div", __assign({ className: 'flex flex-row gap-4 px-14' }, { children: [_jsx("div", __assign({ className: 'w-1/3' }, { children: left })), _jsx("div", __assign({ className: 'w-1/3' }, { children: middle })), _jsx("div", __assign({ className: 'w-1/3' }, { children: right }))] })) }))] }));
+};
diff --git a/dist/framework/visualisation/react/ui/pages/templates/page.d.ts b/dist/framework/visualisation/react/ui/pages/templates/page.d.ts
new file mode 100644
index 00000000..5f6909d0
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/pages/templates/page.d.ts
@@ -0,0 +1,8 @@
+///
+interface PageProps {
+ body: JSX.Element;
+ sidebar: JSX.Element;
+ footer: JSX.Element;
+}
+export declare const Page: (props: PageProps) => JSX.Element;
+export {};
diff --git a/dist/framework/visualisation/react/ui/pages/templates/page.js b/dist/framework/visualisation/react/ui/pages/templates/page.js
new file mode 100644
index 00000000..55a31cca
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/pages/templates/page.js
@@ -0,0 +1,15 @@
+var __assign = (this && this.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
+export var Page = function (props) {
+ return (_jsxs("div", __assign({ className: 'flex flex-col w-full h-full gap-4' }, { children: [_jsxs("div", __assign({ className: 'flex flex-row w-full gap-10 pt-20 pr-14' }, { children: [_jsx("div", __assign({ className: 'flex-1 pl-14' }, { children: props.body })), _jsx("div", __assign({ className: 'w-sidebar flex-shrink-0' }, { children: props.sidebar }))] })), _jsx("div", { className: 'flex-grow' }), _jsx("div", __assign({ className: 'h-footer flex-shrink-0' }, { children: props.footer }))] })));
+};
diff --git a/dist/framework/visualisation/react/ui/pages/templates/sidebar.d.ts b/dist/framework/visualisation/react/ui/pages/templates/sidebar.d.ts
new file mode 100644
index 00000000..215dff6a
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/pages/templates/sidebar.d.ts
@@ -0,0 +1,7 @@
+///
+interface SidebarProps {
+ logo: string;
+ content?: JSX.Element;
+}
+export declare const Sidebar: (props: SidebarProps) => JSX.Element;
+export {};
diff --git a/dist/framework/visualisation/react/ui/pages/templates/sidebar.js b/dist/framework/visualisation/react/ui/pages/templates/sidebar.js
new file mode 100644
index 00000000..d33addae
--- /dev/null
+++ b/dist/framework/visualisation/react/ui/pages/templates/sidebar.js
@@ -0,0 +1,15 @@
+var __assign = (this && this.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
+export var Sidebar = function (props) {
+ return (_jsxs("div", __assign({ className: 'flex flex-col gap-10' }, { children: [_jsxs("div", __assign({ className: 'flex-wrap flex flex-row' }, { children: [_jsx("div", { className: 'flex-grow' }), _jsx("div", __assign({ className: 'h-logo' }, { children: _jsx("img", { src: props.logo }) })), _jsx("div", { className: 'flex-grow' })] })), _jsx("div", { children: props.content })] })));
+};
diff --git a/dist/framework/visualisation/react/ui/prompts/confirm.js b/dist/framework/visualisation/react/ui/prompts/confirm.js
index 32ecad99..287dece5 100644
--- a/dist/framework/visualisation/react/ui/prompts/confirm.js
+++ b/dist/framework/visualisation/react/ui/prompts/confirm.js
@@ -12,7 +12,7 @@ var __assign = (this && this.__assign) || function () {
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Translator } from '../../../../translator';
import { BodyLarge } from '../elements/text';
-import { LabelButton, PrimaryButton } from '../elements/button';
+import { PrimaryButton } from '../elements/button';
export var Confirm = function (props) {
var resolve = props.resolve;
var _a = prepareCopy(props), text = _a.text, ok = _a.ok, cancel = _a.cancel;
@@ -22,7 +22,7 @@ export var Confirm = function (props) {
function handleCancel() {
resolve === null || resolve === void 0 ? void 0 : resolve({ __type__: 'PayloadFalse', value: false });
}
- return (_jsxs(_Fragment, { children: [_jsx(BodyLarge, { text: text, margin: 'mb-4' }), _jsxs("div", __assign({ className: 'flex flex-row gap-4' }, { children: [_jsx(PrimaryButton, { label: ok, onClick: handleOk }), _jsx(LabelButton, { label: cancel, onClick: handleCancel })] }))] }));
+ return (_jsxs(_Fragment, { children: [_jsx(BodyLarge, { text: text, margin: 'mb-4' }), _jsxs("div", __assign({ className: 'flex flex-row gap-4' }, { children: [_jsx(PrimaryButton, { label: ok, onClick: handleOk, color: 'text-grey1 bg-tertiary' }), _jsx(PrimaryButton, { label: cancel, onClick: handleCancel, color: 'text-white bg-primary' })] }))] }));
};
function prepareCopy(_a) {
var text = _a.text, ok = _a.ok, cancel = _a.cancel, locale = _a.locale;
diff --git a/dist/framework/visualisation/react/ui/prompts/consent_form.js b/dist/framework/visualisation/react/ui/prompts/consent_form.js
index 1a3aaf66..baf9f77c 100644
--- a/dist/framework/visualisation/react/ui/prompts/consent_form.js
+++ b/dist/framework/visualisation/react/ui/prompts/consent_form.js
@@ -13,18 +13,17 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
import { assert } from '../../../../helpers';
import { Table } from '../elements/table';
import { PrimaryButton } from '../elements/button';
-import { BodyLarge, Title1, Title2 } from '../elements/text';
+import { BodyLarge, Title4 } from '../elements/text';
import TextBundle from '../../../../text_bundle';
import { Translator } from '../../../../translator';
import React from 'react';
import _ from 'lodash';
export var ConsentForm = function (props) {
- var tablesIn = React.useState(parseTables(props.tables))[0];
- var _a = React.useState(tablesIn), tablesOut = _a[0], setTablesOut = _a[1];
- var _b = React.useState(false), metaTablesVisible = _b[0], setMetaTablesVisible = _b[1];
- var metaTables = React.useState(parseTables(props.metaTables))[0];
- var resolve = props.resolve;
- var _c = prepareCopy(props), title = _c.title, description = _c.description, donateButton = _c.donateButton;
+ var tablesIn = React.useRef(parseTables(props.tables));
+ var metaTables = React.useRef(parseTables(props.metaTables));
+ var tablesOut = React.useRef(tablesIn.current);
+ var locale = props.locale, resolve = props.resolve;
+ var _a = prepareCopy(props), description = _a.description, donateButton = _a.donateButton;
function rowCell(dataFrame, column, row) {
var text = String(dataFrame[column]["".concat(row)]);
return { __type__: 'PropsUITableCell', text: text };
@@ -60,6 +59,7 @@ export var ConsentForm = function (props) {
return result;
}
function parseTables(tablesData) {
+ console.log('parseTables');
return tablesData.map(function (table) { return parseTable(table); });
}
function parseTable(tableData) {
@@ -74,18 +74,18 @@ export var ConsentForm = function (props) {
}
function renderTable(table, readOnly) {
if (readOnly === void 0) { readOnly = false; }
- return (_jsxs("div", __assign({ className: 'flex flex-col gap-4 mb-4' }, { children: [_jsx(Title2, { text: table.title, margin: '' }), _jsx(Table, __assign({}, table, { readOnly: readOnly, onChange: handleTableChange }))] }), table.id));
+ return (_jsxs("div", __assign({ className: 'flex flex-col gap-4 mb-4' }, { children: [_jsx(Title4, { text: table.title, margin: '' }), _jsx(Table, __assign({}, table, { readOnly: readOnly, locale: locale, onChange: handleTableChange }))] }), table.id));
}
function handleTableChange(id, rows) {
- var tablesCopy = tablesOut.slice(0);
+ var tablesCopy = tablesOut.current.slice(0);
var index = tablesCopy.findIndex(function (table) { return table.id === id; });
if (index > -1) {
- var _a = tablesCopy[index], title_1 = _a.title, head = _a.head, oldBody = _a.body, oldDeletedRowCount = _a.deletedRowCount;
+ var _a = tablesCopy[index], title = _a.title, head = _a.head, oldBody = _a.body, oldDeletedRowCount = _a.deletedRowCount;
var body = { __type__: 'PropsUITableBody', rows: rows };
var deletedRowCount = oldDeletedRowCount + (oldBody.rows.length - rows.length);
- tablesCopy[index] = { __type__: 'PropsUITable', id: id, head: head, body: body, title: title_1, deletedRowCount: deletedRowCount };
+ tablesCopy[index] = { __type__: 'PropsUITable', id: id, head: head, body: body, title: title, deletedRowCount: deletedRowCount };
}
- setTablesOut(tablesCopy);
+ tablesOut.current = tablesCopy;
}
function handleDonate() {
var value = serializeConsentData();
@@ -99,13 +99,13 @@ export var ConsentForm = function (props) {
return serializeMetaTables().concat(serializeDeletedMetaData());
}
function serializeTables() {
- return tablesOut.map(function (table) { return serializeTable(table); });
+ return tablesOut.current.map(function (table) { return serializeTable(table); });
}
function serializeMetaTables() {
- return metaTables.map(function (table) { return serializeTable(table); });
+ return metaTables.current.map(function (table) { return serializeTable(table); });
}
function serializeDeletedMetaData() {
- var rawData = tablesOut
+ var rawData = tablesOut.current
.filter(function (_a) {
var deletedRowCount = _a.deletedRowCount;
return deletedRowCount > 0;
@@ -129,18 +129,18 @@ export var ConsentForm = function (props) {
var values = row.cells.map(function (cell) { return cell.text; });
return _.fromPairs(_.zip(keys, values));
}
- return (_jsxs(_Fragment, { children: [_jsx(Title1, { text: title }), _jsx(BodyLarge, { text: description }), _jsxs("div", __assign({ className: 'flex flex-col gap-8' }, { children: [tablesIn.map(function (table) { return renderTable(table); }), metaTablesVisible ? metaTables.map(function (table) { return renderTable(table, true); }) : _jsx("div", {}), _jsxs("div", __assign({ className: 'flex flex-row gap-4 mt-2' }, { children: [metaTablesVisible ? '' : _jsx(PrimaryButton, { label: 'Show meta data', onClick: function () { setMetaTablesVisible(true); } }), _jsx(PrimaryButton, { label: donateButton, onClick: handleDonate, color: 'bg-success text-white' })] }))] }))] }));
+ return (_jsxs(_Fragment, { children: [_jsx(BodyLarge, { text: description }), _jsxs("div", __assign({ className: 'flex flex-col gap-8' }, { children: [tablesIn.current.map(function (table) { return renderTable(table); }), _jsx("div", __assign({ className: 'flex flex-row gap-4' }, { children: _jsx(PrimaryButton, { label: donateButton, onClick: handleDonate, color: 'bg-success text-white' }) }))] }))] }));
};
function prepareCopy(_a) {
- var title = _a.title, description = _a.description, locale = _a.locale;
+ var locale = _a.locale;
return {
- title: Translator.translate(title, locale),
description: Translator.translate(description, locale),
- donateButton: Translator.translate(donateButtonLabel(), locale)
+ donateButton: Translator.translate(donateButtonLabel, locale)
};
}
-var donateButtonLabel = function () {
- return new TextBundle()
- .add('en', 'Yes, donate')
- .add('nl', 'Ja, doneer');
-};
+var donateButtonLabel = new TextBundle()
+ .add('en', 'Consent')
+ .add('nl', 'Consent');
+var description = new TextBundle()
+ .add('en', 'Please have a good look at the extracted data before giving consent to use this data.')
+ .add('nl', 'Bekijk de gegevens goed voordat je consent geeft om deze te gebruiken.');
diff --git a/dist/framework/visualisation/react/ui/prompts/file_input.js b/dist/framework/visualisation/react/ui/prompts/file_input.js
index b5cfb0ff..dbe0ee1a 100644
--- a/dist/framework/visualisation/react/ui/prompts/file_input.js
+++ b/dist/framework/visualisation/react/ui/prompts/file_input.js
@@ -14,12 +14,13 @@ import * as React from 'react';
import TextBundle from '../../../../text_bundle';
import { Translator } from '../../../../translator';
import { PrimaryButton } from '../elements/button';
+import { BodyLarge, BodySmall } from '../elements/text';
export var FileInput = function (props) {
- var _a = React.useState(), selectedFile = _a[0], setSelectedFile = _a[1];
- var _b = React.useState(true), confirmHidden = _b[0], setConfirmHidden = _b[1];
+ var _a;
+ var _b = React.useState(), selectedFile = _b[0], setSelectedFile = _b[1];
var input = React.useRef(null);
var resolve = props.resolve;
- var _c = prepareCopy(props), title = _c.title, description = _c.description, extensions = _c.extensions, selectButton = _c.selectButton, continueButton = _c.continueButton;
+ var _c = prepareCopy(props), description = _c.description, note = _c.note, placeholder = _c.placeholder, extensions = _c.extensions, selectButton = _c.selectButton, continueButton = _c.continueButton;
function handleClick() {
var _a;
(_a = input.current) === null || _a === void 0 ? void 0 : _a.click();
@@ -28,7 +29,6 @@ export var FileInput = function (props) {
var files = event.target.files;
if (files != null && files.length > 0) {
setSelectedFile(files[0]);
- setConfirmHidden(false);
}
else {
console.log('[FileInput] Error selecting file: ' + JSON.stringify(files));
@@ -39,13 +39,14 @@ export var FileInput = function (props) {
resolve === null || resolve === void 0 ? void 0 : resolve({ __type__: 'PayloadFile', value: selectedFile });
}
}
- return (_jsxs(_Fragment, { children: [_jsx("div", __assign({ className: 'text-title5 font-title5 sm:text-title4 sm:font-title4 lg:text-title3 lg:font-title3 text-grey1' }, { children: title })), _jsx("div", { className: 'mt-8' }), _jsxs("div", __assign({ id: 'select-panel' }, { children: [_jsx("div", __assign({ className: 'flex-wrap text-bodylarge font-body text-grey1 text-left' }, { children: description })), _jsx("div", { className: 'mt-4' }), _jsxs("div", __assign({ className: 'flex flex-row items-center gap-4' }, { children: [_jsx("div", __assign({ className: 'flex-wrap cursor-pointer' }, { children: _jsx("div", __assign({ id: 'select-button', className: 'pt-15px pb-15px active:shadow-top4px active:pt-4 active:pb-14px leading-none font-button text-button rounded pr-4 pl-4 bg-primary text-white', onClick: handleClick }, { children: selectButton })) })), _jsx("div", __assign({ className: 'flex-wrap' }, { children: _jsx("div", __assign({ id: 'selected-filename', className: 'flex-wrap text-subhead font-subhead text-grey1' }, { children: selectedFile === null || selectedFile === void 0 ? void 0 : selectedFile.name })) }))] })), _jsx("input", { ref: input, id: 'input', type: 'file', className: 'hidden', accept: extensions, onChange: handleSelect })] })), _jsx("div", { className: 'mt-10' }), _jsx("div", __assign({ className: 'flex flex-row gap-4 items-center' }, { children: _jsx("div", __assign({ className: confirmHidden ? 'hidden' : '' }, { children: _jsx(PrimaryButton, { label: continueButton, onClick: handleConfirm, color: 'bg-tertiary text-grey1' }) })) }))] }));
+ return (_jsx(_Fragment, { children: _jsxs("div", __assign({ id: 'select-panel' }, { children: [_jsx("div", __assign({ className: 'flex-wrap text-bodylarge font-body text-grey1 text-left' }, { children: description })), _jsx("div", { className: 'mt-8' }), _jsxs("div", __assign({ className: 'p-6 border-grey4 border-2 rounded' }, { children: [_jsx("input", { ref: input, id: 'input', type: 'file', className: 'hidden', accept: extensions, onChange: handleSelect }), _jsxs("div", __assign({ className: 'flex flex-row gap-4 items-center' }, { children: [_jsx(BodyLarge, { text: (_a = selectedFile === null || selectedFile === void 0 ? void 0 : selectedFile.name) !== null && _a !== void 0 ? _a : placeholder, margin: '', color: selectedFile === undefined ? 'text-grey2' : 'textgrey1' }), _jsx("div", { className: 'flex-grow' }), _jsx(PrimaryButton, { onClick: handleClick, label: selectButton, color: 'bg-tertiary text-grey1' })] }))] })), _jsx("div", { className: 'mt-4' }), _jsxs("div", __assign({ className: "".concat(selectedFile === undefined ? 'opacity-30' : 'opacity-100') }, { children: [_jsx(BodySmall, { text: note, margin: '' }), _jsx("div", { className: 'mt-8' }), _jsx("div", __assign({ className: 'flex flex-row gap-4' }, { children: _jsx(PrimaryButton, { label: continueButton, onClick: handleConfirm, enabled: selectedFile !== undefined }) }))] }))] })) }));
};
function prepareCopy(_a) {
- var title = _a.title, description = _a.description, extensions = _a.extensions, locale = _a.locale;
+ var description = _a.description, extensions = _a.extensions, locale = _a.locale;
return {
- title: Translator.translate(title, locale),
description: Translator.translate(description, locale),
+ note: Translator.translate(note(), locale),
+ placeholder: Translator.translate(placeholder(), locale),
extensions: extensions,
selectButton: Translator.translate(selectButtonLabel(), locale),
continueButton: Translator.translate(continueButtonLabel(), locale)
@@ -61,3 +62,13 @@ var selectButtonLabel = function () {
.add('en', 'Choose file')
.add('nl', 'Kies bestand');
};
+var note = function () {
+ return new TextBundle()
+ .add('en', 'Note: The process to extract the correct data from the file is done on your own computer. No data is stored or sent yet.')
+ .add('nl', 'NB: Het proces om de juiste gegevens uit het bestand te halen gebeurt op uw eigen computer. Er worden nog geen gegevens opgeslagen of verstuurd.');
+};
+var placeholder = function () {
+ return new TextBundle()
+ .add('en', 'Choose a file')
+ .add('nl', 'Kies een bestand');
+};
diff --git a/dist/py_script.js b/dist/py_script.js
index 0ba4d0dc..fc8dd914 100644
--- a/dist/py_script.js
+++ b/dist/py_script.js
@@ -1 +1 @@
-export var PyScript = "\nimport pandas as pd\nimport zipfile\n\ndef process():\n yield render_start_page()\n\n platforms = [\"Twitter\", \"Instagram\", \"Youtube\"]\n for index, platform in enumerate(platforms):\n meta_data = [] \n meta_data.append((\"debug\", f\"{platform}: start\"))\n\n data = None\n while True:\n meta_data.append((\"debug\", f\"{platform}: prompt file\"))\n promptFile = prompt_file(platform, \"application/zip, text/plain\")\n fileResult = yield render_donation_page(index+1, platform, promptFile)\n if fileResult.__type__ == 'PayloadString':\n meta_data.append((\"debug\", f\"{platform}: extracting file\"))\n extractionResult = doSomethingWithTheFile(platform, fileResult.value)\n if extractionResult != 'invalid': \n meta_data.append((\"debug\", f\"{platform}: extraction successful, go to consent form\")) \n data = extractionResult\n break\n else:\n meta_data.append((\"debug\", f\"{platform}: prompt confirmation to retry file selection\")) \n retry_result = yield render_donation_page(index+1, platform, retry_confirmation())\n if retry_result.__type__ == 'PayloadTrue':\n meta_data.append((\"debug\", f\"{platform}: skip due to invalid file\")) \n continue\n else: \n meta_data.append((\"debug\", f\"{platform}: retry prompt file\")) \n break\n else:\n meta_data.append((\"debug\", f\"{platform}: skip to next step\")) \n break\n\n if data is not None:\n meta_data.append((\"debug\", f\"{platform}: prompt consent\"))\n prompt = prompt_consent(platform, data, meta_data)\n consent_result = yield render_donation_page(index+1, platform, prompt)\n if consent_result.__type__ == \"PayloadJSON\":\n meta_data.append((\"debug\", f\"{platform}: donate consent data\"))\n yield donate(platform, consent_result.value)\n\n yield render_end_page()\n\n\ndef render_start_page():\n page = PropsUIPageStart()\n return CommandUIRender(page)\n\n\ndef render_end_page():\n header = PropsUIHeader(Translatable({\n \"en\": \"Thank you\",\n \"nl\": \"Dank je wel\"\n }))\n page = PropsUIPageEnd(header)\n return CommandUIRender(page)\n\n\ndef render_donation_page(index, platform, body):\n header = PropsUIHeader(Translatable({\n \"en\": f\"Step {index}: {platform}\",\n \"nl\": f\"Stap {index}: {platform}\"\n }))\n page = PropsUIPageDonation(header, body)\n return CommandUIRender(page)\n\n\ndef retry_confirmation():\n text = Translatable({\n \"en\": \"The selected file is invalid. Do you want to select a different file?\",\n \"nl\": \"Het geselecteerde bestaand is ongeldig. Wil je een ander bestand selecteren ?\"\n })\n ok = Translatable({\n \"en\": \"Different file\",\n \"nl\": \"Ander bestand\"\n })\n cancel = Translatable({\n \"en\": \"Cancel\",\n \"nl\": \"Annuleren\"\n })\n return PropsUIPromptConfirm(text, ok, cancel)\n\n\ndef prompt_file(platform, extensions):\n title = Translatable({\n \"en\": f\"Select {platform} file\",\n \"nl\": f\"Selecteer {platform} bestand\"\n })\n\n description = Translatable({\n \"en\": \"Please select this file so we can extract relevant information for our research.\",\n \"nl\": \"Je kan deze file nu selecteren zodat wij er relevante informatie uit kunnen halen voor ons onderzoek.\"\n })\n\n return PropsUIPromptFileInput(title, description, extensions)\n\n\ndef doSomethingWithTheFile(platform, filename):\n return extract_zip_contents(filename)\n\n\ndef extract_zip_contents(filename):\n names = []\n try:\n file = zipfile.ZipFile(filename)\n data = []\n for name in file.namelist():\n names.append(name)\n info = file.getinfo(name)\n data.append((name, info.compress_size, info.file_size))\n return data\n except:\n return \"invalid\" \n\n\ndef prompt_consent(id, data, meta_data):\n title = Translatable({\n \"en\": \"Extracted data\",\n \"nl\": \"Gevonden gegevens\"\n })\n\n description = Translatable({\n \"en\": \"Please have a good look at the extracted data before giving consent to use this data.\",\n \"nl\": \"Bekijk de gegevens goed voordat je consent geeft om deze te gebruiken.\"\n })\n\n data_frame = pd.DataFrame(data, columns=[\"filename\", \"compressed size\", \"size\"])\n table = PropsUIPromptConsentFormTable(\"zip_content\", \"The zip contains the following files:\", data_frame)\n meta_frame = pd.DataFrame(meta_data, columns=[\"type\", \"message\"])\n meta_table = PropsUIPromptConsentFormTable(\"log_messages\", \"Log messages:\", meta_frame)\n return PropsUIPromptConsentForm(title, description, [table], [meta_table])\n\n\ndef donate(key, json_string):\n return CommandSystemDonate(key, json_string)\n";
+export var PyScript = "\nimport pandas as pd\nimport zipfile\n\ndef process():\n platforms = [\"Twitter\", \"Facebook\", \"Instagram\", \"Youtube\"]\n\n subflows = len(platforms)\n steps = 2\n step_percentage = (100/subflows)/steps\n\n # progress in %\n progress = 0\n\n for index, platform in enumerate(platforms):\n meta_data = [] \n meta_data.append((\"debug\", f\"{platform}: start\"))\n\n # STEP 1: select the file\n progress += step_percentage\n data = None\n while True:\n meta_data.append((\"debug\", f\"{platform}: prompt file\"))\n promptFile = prompt_file(platform, \"application/zip, text/plain\")\n fileResult = yield render_donation_page(platform, promptFile, progress)\n if fileResult.__type__ == 'PayloadString':\n meta_data.append((\"debug\", f\"{platform}: extracting file\"))\n extractionResult = doSomethingWithTheFile(platform, fileResult.value)\n if extractionResult != 'invalid': \n meta_data.append((\"debug\", f\"{platform}: extraction successful, go to consent form\")) \n data = extractionResult\n break\n else:\n meta_data.append((\"debug\", f\"{platform}: prompt confirmation to retry file selection\")) \n retry_result = yield render_donation_page(platform, retry_confirmation(platform), progress)\n if retry_result.__type__ == 'PayloadTrue':\n meta_data.append((\"debug\", f\"{platform}: skip due to invalid file\")) \n continue\n else: \n meta_data.append((\"debug\", f\"{platform}: retry prompt file\")) \n break\n else:\n meta_data.append((\"debug\", f\"{platform}: skip to next step\")) \n break\n\n # STEP 2: ask for consent\n progress += step_percentage\n if data is not None:\n meta_data.append((\"debug\", f\"{platform}: prompt consent\"))\n prompt = prompt_consent(platform, data, meta_data)\n consent_result = yield render_donation_page(platform, prompt, progress)\n if consent_result.__type__ == \"PayloadJSON\":\n meta_data.append((\"debug\", f\"{platform}: donate consent data\"))\n yield donate(platform, consent_result.value)\n\n yield render_end_page()\n\n\ndef render_end_page():\n page = PropsUIPageEnd()\n return CommandUIRender(page)\n\n\ndef render_donation_page(platform, body, progress):\n header = PropsUIHeader(Translatable({\n \"en\": platform,\n \"nl\": platform\n }))\n\n footer = PropsUIFooter(progress)\n page = PropsUIPageDonation(platform, header, body, footer)\n return CommandUIRender(page)\n\n\ndef retry_confirmation(platform):\n text = Translatable({\n \"en\": f\"We can not process your {platform} file, please try again if you want to choose another file.\",\n \"nl\": f\"We kunnen uw {platform} bestand niet verwerken, probeer opnieuw als u een ander bestand wilt kiezen.\"\n })\n ok = Translatable({\n \"en\": \"Try again\",\n \"nl\": \"Probeer opnieuw\"\n })\n cancel = Translatable({\n \"en\": \"Continue\",\n \"nl\": \"Verder\"\n })\n return PropsUIPromptConfirm(text, ok, cancel)\n\n\ndef prompt_file(platform, extensions):\n description = Translatable({\n \"en\": \"Please select this file so we can extract relevant information for our research.\",\n \"nl\": \"Je kan deze file nu selecteren zodat wij er relevante informatie uit kunnen halen voor ons onderzoek.\"\n })\n\n return PropsUIPromptFileInput(description, extensions)\n\n\ndef doSomethingWithTheFile(platform, filename):\n return extract_zip_contents(filename)\n\n\ndef extract_zip_contents(filename):\n names = []\n try:\n file = zipfile.ZipFile(filename)\n data = []\n for name in file.namelist():\n names.append(name)\n info = file.getinfo(name)\n data.append((name, info.compress_size, info.file_size))\n return data\n except:\n return \"invalid\" \n\n\ndef prompt_consent(id, data, meta_data):\n\n data_frame = pd.DataFrame(data, columns=[\"filename\", \"compressed size\", \"size\"])\n table = PropsUIPromptConsentFormTable(\"zip_content\", \"Zip file contents\", data_frame)\n meta_frame = pd.DataFrame(meta_data, columns=[\"type\", \"message\"])\n meta_table = PropsUIPromptConsentFormTable(\"log_messages\", \"Log messages:\", meta_frame)\n return PropsUIPromptConsentForm([table], [meta_table])\n\n\ndef donate(key, json_string):\n return CommandSystemDonate(key, json_string)\n";
diff --git a/dist/styles.css b/dist/styles.css
index fc21cbcb..f74c7921 100644
--- a/dist/styles.css
+++ b/dist/styles.css
@@ -1 +1 @@
-/*! tailwindcss v3.1.8 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::-webkit-backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.absolute{position:absolute}.relative{position:relative}.top-0{top:0}.m-6{margin:1.5rem}.mr-2{margin-right:.5rem}.-mt-2px{margin-top:-2px}.ml-2{margin-left:.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mb-6{margin-bottom:1.5rem}.mb-2{margin-bottom:.5rem}.mb-10{margin-bottom:2.5rem}.mb-4{margin-bottom:1rem}.mt-8{margin-top:2rem}.mt-4{margin-top:1rem}.mt-10{margin-top:2.5rem}.flex{display:flex}.table{display:table}.hidden{display:none}.h-full{height:100%}.h-5{height:1.25rem}.h-48px{height:48px}.w-full{width:100%}.w-5{width:1.25rem}.w-8{width:2rem}.max-w-sheet{max-width:760px}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.table-auto{table-layout:auto}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;user-select:none}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-8{gap:2rem}.rounded{border-radius:.25rem}.border-2{border-width:2px}.border-solid{border-style:solid}.border-grey3{--tw-border-opacity:1;border-color:rgb(204 204 204/var(--tw-border-opacity))}.bg-tertiary{--tw-bg-opacity:1;background-color:rgb(255 207 96/var(--tw-bg-opacity))}.bg-primary{--tw-bg-opacity:1;background-color:rgb(66 114 239/var(--tw-bg-opacity))}.bg-delete{--tw-bg-opacity:1;background-color:rgb(219 30 30/var(--tw-bg-opacity))}.bg-success{--tw-bg-opacity:1;background-color:rgb(111 202 55/var(--tw-bg-opacity))}.bg-opacity-0{--tw-bg-opacity:0}.px-2{padding-left:.5rem;padding-right:.5rem}.pt-15px{padding-top:15px}.pb-15px{padding-bottom:15px}.pr-4{padding-right:1rem}.pl-4{padding-left:1rem}.pt-13px{padding-top:13px}.pb-13px{padding-bottom:13px}.pt-1{padding-top:.25rem}.pb-1{padding-bottom:.25rem}.pl-3{padding-left:.75rem}.pr-3{padding-right:.75rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.font-button,.font-label{font-family:Finador-Bold,sans-serif}.font-body{font-family:Finador-Light,sans-serif}.font-title3,.font-title4{font-family:Finador-Black,sans-serif}.font-title5,.font-title6{font-family:Finador-Bold,sans-serif}.font-subhead{font-family:Finador-Medium,sans-serif}.text-button{font-size:18px;line-height:18px}.text-label{font-size:16px;line-height:16px}.text-bodymedium{font-size:20px;line-height:30px}.text-bodylarge{font-size:24px;line-height:36px}.text-title4{font-size:28px;line-height:32px}.text-title3{font-size:32px;line-height:38px}.text-title6{font-size:20px;line-height:22px}.text-title5{font-size:24px;line-height:26px}.text-subhead{font-size:20px;line-height:20px}.leading-none{line-height:1}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-delete{--tw-text-opacity:1;color:rgb(219 30 30/var(--tw-text-opacity))}.text-grey1{--tw-text-opacity:1;color:rgb(34 34 34/var(--tw-text-opacity))}.opacity-0{opacity:0}.opacity-30{opacity:.3}.filter{-webkit-filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.hover\:bg-grey5:hover{--tw-bg-opacity:1;background-color:rgb(246 246 246/var(--tw-bg-opacity))}.focus\:border-primary:focus{--tw-border-opacity:1;border-color:rgb(66 114 239/var(--tw-border-opacity))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.active\:pt-4:active{padding-top:1rem}.active\:pb-14px:active{padding-bottom:14px}.active\:pt-14px:active{padding-top:14px}.active\:pb-3:active{padding-bottom:.75rem}.active\:pt-5px:active{padding-top:5px}.active\:pb-3px:active{padding-bottom:3px}.active\:shadow-top4px:active{--tw-shadow:inset 0 4px 0 0 rgba(0,0,0,.15);--tw-shadow-colored:inset 0 4px 0 0 var(--tw-shadow-color)}.active\:shadow-top2px:active,.active\:shadow-top4px:active{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.active\:shadow-top2px:active{--tw-shadow:inset 0 2px 0 0 rgba(0,0,0,.15);--tw-shadow-colored:inset 0 2px 0 0 var(--tw-shadow-color)}@media (min-width:640px){.sm\:font-title2,.sm\:font-title3,.sm\:font-title4{font-family:Finador-Black,sans-serif}.sm\:text-title2{font-size:40px;line-height:44px}.sm\:text-title3{font-size:32px;line-height:38px}.sm\:text-title4{font-size:28px;line-height:32px}}@media (min-width:768px){.md\:mb-8{margin-bottom:2rem}}@media (min-width:1024px){.lg\:m-14{margin:3.5rem}.lg\:mb-10{margin-bottom:2.5rem}.lg\:font-title0{font-family:Finador-Black,sans-serif}.lg\:font-title1{font-family:Arial,sans-serif}.lg\:font-title2,.lg\:font-title3{font-family:Finador-Black,sans-serif}.lg\:text-title0{font-size:64px;line-height:68px}.lg\:text-title1{font-size:50px;line-height:50px}.lg\:text-title2{font-size:40px;line-height:44px}.lg\:text-title3{font-size:32px;line-height:38px}}
\ No newline at end of file
+/*! tailwindcss v3.1.8 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::-webkit-backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.top-0{top:0}.-mt-2px{margin-top:-2px}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-1px{margin-top:1px}.mb-6{margin-bottom:1.5rem}.mb-3{margin-bottom:.75rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mt-8{margin-top:2rem}.mt-4{margin-top:1rem}.flex{display:flex}.table{display:table}.contents{display:contents}.hidden{display:none}.h-full{height:100%}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-12{height:3rem}.h-8{height:2rem}.h-4{height:1rem}.h-48px{height:48px}.h-table{height:384px}.h-px{height:1px}.h-footer{height:88px}.h-logo{height:110px}.w-full{width:100%}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-10{width:2.5rem}.w-9{width:2.25rem}.w-8{width:2rem}.w-1px{width:1px}.w-1\/3{width:33.333333%}.w-sidebar{width:320px}.min-w-button{min-width:200px}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.table-fixed{table-layout:fixed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;user-select:none}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.gap-3{gap:.75rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-4{gap:1rem}.gap-2{gap:.5rem}.gap-10{gap:2.5rem}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-grey4>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(238 238 238/var(--tw-divide-opacity))}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.border-2{border-width:2px}.border-solid{border-style:solid}.border-grey4{--tw-border-opacity:1;border-color:rgb(238 238 238/var(--tw-border-opacity))}.border-grey3{--tw-border-opacity:1;border-color:rgb(204 204 204/var(--tw-border-opacity))}.bg-tertiary{--tw-bg-opacity:1;background-color:rgb(255 207 96/var(--tw-bg-opacity))}.bg-primary{--tw-bg-opacity:1;background-color:rgb(66 114 239/var(--tw-bg-opacity))}.bg-delete{--tw-bg-opacity:1;background-color:rgb(219 30 30/var(--tw-bg-opacity))}.bg-grey5{--tw-bg-opacity:1;background-color:rgb(246 246 246/var(--tw-bg-opacity))}.bg-primarylight{--tw-bg-opacity:1;background-color:rgb(227 234 253/var(--tw-bg-opacity))}.bg-grey6{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-success{--tw-bg-opacity:1;background-color:rgb(111 202 55/var(--tw-bg-opacity))}.bg-grey3{--tw-bg-opacity:1;background-color:rgb(204 204 204/var(--tw-bg-opacity))}.bg-grey4{--tw-bg-opacity:1;background-color:rgb(238 238 238/var(--tw-bg-opacity))}.bg-opacity-0{--tw-bg-opacity:0}.p-8{padding:2rem}.p-6{padding:1.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-14{padding-left:3.5rem;padding-right:3.5rem}.pt-15px{padding-top:15px}.pb-15px{padding-bottom:15px}.pr-4{padding-right:1rem}.pl-4{padding-left:1rem}.pt-13px{padding-top:13px}.pb-13px{padding-bottom:13px}.pt-1{padding-top:.25rem}.pb-1{padding-bottom:.25rem}.pl-3{padding-left:.75rem}.pr-3{padding-right:.75rem}.pt-20{padding-top:5rem}.pr-14{padding-right:3.5rem}.pl-14{padding-left:3.5rem}.text-left{text-align:left}.font-button,.font-label{font-family:Finador-Bold,sans-serif}.font-body{font-family:Finador-Light,sans-serif}.font-table-header{font-family:Finador-Bold,sans-serif}.font-table-row{font-family:Finador-Regular,sans-serif}.font-title3,.font-title4{font-family:Finador-Black,sans-serif}.font-title5,.font-title6{font-family:Finador-Bold,sans-serif}.font-caption,.font-link{font-family:Finador-Medium,sans-serif}.text-button{font-size:18px;line-height:18px}.text-label{font-size:16px;line-height:16px}.text-bodymedium{font-size:20px;line-height:30px}.text-table{font-size:14px;line-height:14px}.text-bodylarge{font-size:24px;line-height:36px}.text-bodysmall{font-size:16px;line-height:24px}.text-title4{font-size:28px;line-height:32px}.text-title3{font-size:32px;line-height:38px}.text-title5{font-size:24px;line-height:26px}.text-title6{font-size:20px;line-height:22px}.text-caption{font-size:14px;line-height:18px}.text-link{font-size:16px;line-height:24px}.leading-none{line-height:1}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-delete{--tw-text-opacity:1;color:rgb(219 30 30/var(--tw-text-opacity))}.text-grey1{--tw-text-opacity:1;color:rgb(34 34 34/var(--tw-text-opacity))}.text-grey2{--tw-text-opacity:1;color:rgb(153 153 153/var(--tw-text-opacity))}.text-grey3{--tw-text-opacity:1;color:rgb(204 204 204/var(--tw-text-opacity))}.text-primary{--tw-text-opacity:1;color:rgb(66 114 239/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.opacity-30{opacity:.3}.opacity-100{opacity:1}.filter{-webkit-filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.hover\:bg-grey6:hover{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.focus\:border-primary:focus{--tw-border-opacity:1;border-color:rgb(66 114 239/var(--tw-border-opacity))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.active\:pt-4:active{padding-top:1rem}.active\:pb-14px:active{padding-bottom:14px}.active\:pt-14px:active{padding-top:14px}.active\:pb-3:active{padding-bottom:.75rem}.active\:pt-5px:active{padding-top:5px}.active\:pb-3px:active{padding-bottom:3px}.active\:shadow-top4px:active{--tw-shadow:inset 0 4px 0 0 rgba(0,0,0,.15);--tw-shadow-colored:inset 0 4px 0 0 var(--tw-shadow-color)}.active\:shadow-top2px:active,.active\:shadow-top4px:active{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.active\:shadow-top2px:active{--tw-shadow:inset 0 2px 0 0 rgba(0,0,0,.15);--tw-shadow-colored:inset 0 2px 0 0 var(--tw-shadow-color)}@media (min-width:640px){.sm\:font-title2,.sm\:font-title3,.sm\:font-title4{font-family:Finador-Black,sans-serif}.sm\:font-title5{font-family:Finador-Bold,sans-serif}.sm\:text-title2{font-size:40px;line-height:44px}.sm\:text-title3{font-size:32px;line-height:38px}.sm\:text-title4{font-size:28px;line-height:32px}.sm\:text-title5{font-size:24px;line-height:26px}}@media (min-width:768px){.md\:mb-8{margin-bottom:2rem}.md\:mb-5{margin-bottom:1.25rem}}@media (min-width:1024px){.lg\:mb-10{margin-bottom:2.5rem}.lg\:mb-6{margin-bottom:1.5rem}.lg\:font-title0,.lg\:font-title1,.lg\:font-title2,.lg\:font-title3,.lg\:font-title4{font-family:Finador-Black,sans-serif}.lg\:text-title0{font-size:64px;line-height:68px}.lg\:text-title1{font-size:50px;line-height:50px}.lg\:text-title2{font-size:40px;line-height:44px}.lg\:text-title3{font-size:32px;line-height:38px}.lg\:text-title4{font-size:28px;line-height:32px}}
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
index aa069f27..5213c094 100644
--- a/public/index.html
+++ b/public/index.html
@@ -24,11 +24,16 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
+
React App
-
+