diff --git a/src/ui/client/builder/pages/plugins.py b/src/ui/client/builder/pages/plugins.py index f4aad07c4..88125f5d7 100644 --- a/src/ui/client/builder/pages/plugins.py +++ b/src/ui/client/builder/pages/plugins.py @@ -9,6 +9,7 @@ from .utils.widgets import ( icons_widget, regular_widget, unmatch_widget, + upload_widget, ) from .utils.table import add_column from .utils.format import get_fields_from_field @@ -47,7 +48,7 @@ def plugins_filter(types: List[str]) -> list: } ] - if len(types) >= 2: + if types is not None and (isinstance(types, list) and len(types) >= 2): filters.append( { "type": "=", @@ -165,13 +166,12 @@ def fallback_message(msg: str, display: Optional[list] = None) -> dict: } -def plugins_list(plugins: Optional[list] = None) -> dict: +def plugins_list(plugins: Optional[list] = None, types: Optional[list] = None) -> dict: if not plugins: return fallback_message(msg="plugins_not_found") items = [] - types = set() for plugin in plugins: items.append( @@ -179,15 +179,15 @@ def plugins_list(plugins: Optional[list] = None) -> dict: name=plugin["id"], version=plugin["version"], description=plugin["description"], - is_deletable=plugin["method"] == "ui", + is_deletable=plugin["type"] in ("manual", "default", "ui", "external"), page=f"/plugins/{plugin['id']}" if plugin["page"] else "", plugin_type=plugin["type"], ) ) - types.add(plugin["type"]) return { "type": "card", + "display": ["main", 0], "widgets": [ title_widget( title="plugins_list_title", # keep it (a18n) @@ -200,11 +200,71 @@ def plugins_list(plugins: Optional[list] = None) -> dict: layout="fitColumns", columns=columns, items=items, - filters=plugins_filter(list(types)), + filters=plugins_filter(types), ), ], } -def plugins_builder(plugins: Optional[list] = None) -> list: - return [plugins_list(plugins=plugins)] +def plugins_tabs(): + return { + "type": "tabs", + "widgets": [ + button_group_widget( + buttons=[ + button_widget( + text="plugins_list_tab", + display=["main", 0], + size="tab", + color="info", + iconColor="white", + iconName="list", + ), + button_widget( + text="plugins_upload_tab", + color="success", + display=["main", 1], + size="tab", + iconColor="white", + iconName="plus", + ), + ] + ) + ], + } + + +def plugins_upload(): + return { + "type": "card", + "display": ["main", 1], + "widgets": [ + title_widget( + title="plugins_upload_title", # keep it (a18n) + ), + subtitle_widget( + subtitle="plugins_upload_subtitle", # keep it (a18n) + ), + upload_widget( + maxScreenW="sm", + ), + button_group_widget( + buttons=[ + button_widget( + text="action_reload", # keep it (a18n) + color="info", + size="normal", + attrs={ + "data-submit-data": "{}", + "data-submit-endpoint": "", + }, + disabled=True, + ), + ] + ), + ], + } + + +def plugins_builder(plugins: Optional[list] = None, types: Optional[list] = None) -> list: + return [plugins_tabs(), plugins_list(plugins=plugins, types=types), plugins_upload()] diff --git a/src/ui/client/builder/pages/utils/widgets.py b/src/ui/client/builder/pages/utils/widgets.py index ef184d9c0..a2529748a 100644 --- a/src/ui/client/builder/pages/utils/widgets.py +++ b/src/ui/client/builder/pages/utils/widgets.py @@ -2133,6 +2133,7 @@ def templates_widget( templates: dict, operation: str = "edit", oldServerName: str = "", + isDraft: Union[str, bool] = False, display: Optional[list] = None ): """ @@ -2143,6 +2144,7 @@ def templates_widget( - `templates` **Object** List of advanced templates that contains settings. Must be a dict with mode as key, then the template name as key with a list of data (different for each modes). - `operation` **String** Operation type (edit, new, delete). (optional, default `"edit"`) - `oldServerName` **String** Old server name. This is a server name before any changes. (optional, default `""`) + - `isDraft` **(String | Boolean)** Is draft mode. "yes" or "no" to set a draft select. Else will be ignored. (optional, default `false`) - `display` **Array** Array need two values : "groupName" in index 0 and "compId" in index 1 in order to be displayed using the display store. More info on the display store itslef. (optional, default `[]`) EXAMPLE @@ -2166,7 +2168,7 @@ def templates_widget( # List of params that will be add only if not default value - list_params = [("operation", operation, "edit"),("oldServerName", oldServerName, ""),("display", display, None)] + list_params = [("operation", operation, "edit"),("oldServerName", oldServerName, ""),("isDraft", isDraft, False),("display", display, None)] for param in list_params: add_key_value(data, param[0], param[1], param[2]) @@ -2310,3 +2312,39 @@ def unmatch_widget( return { "type" : "Unmatch", "data" : data } + +def upload_widget( + disabled: bool = False, + columns: dict = {"pc":"12","tablet":"12","mobile":"12"}, + containerClass: str = "", + maxScreenW: str = "2xl" + ): + """ + This component is used to upload files to the server. ATM only used to upload plugins. + + PARAMETERS + + - `disabled` **Boolean** If true, the upload will be disabled. (optional, default `False`) + - `columns` **Object** Columns object. (optional, default `{"pc":"12","tablet":"12","mobile":"12"}`) + - `containerClass` **String** Container additional class (optional, default `""`) + - `maxScreenW` **String** Max screen width within sm, md, lg, xl, 2xl, 3xl (optional, default `"2xl"`) + + EXAMPLE + + { + disabled : True + } + + """ + + data = { + } + + + # List of params that will be add only if not default value + list_params = [("disabled", disabled, False),("columns", columns, {"pc":"12","tablet":"12","mobile":"12"}),("containerClass", containerClass, ""),("maxScreenW", maxScreenW, "2xl")] + for param in list_params: + add_key_value(data, param[0], param[1], param[2]) + + return { "type" : "Upload", "data" : data } + diff --git a/src/ui/client/builder/test_plugins.py b/src/ui/client/builder/test_plugins.py index 638216be0..753a9ab93 100644 --- a/src/ui/client/builder/test_plugins.py +++ b/src/ui/client/builder/test_plugins.py @@ -3,10 +3,10 @@ from utils import save_builder from pages.plugins import plugins_builder plugins = [ - {"name": "plugin1", "version": "1.0.0", "description": "This is plugin1", "type": "core", "is_deletable": False, "page": "/mypage"}, - {"name": "plugin2", "version": "1.0.0", "description": "This is plugin2", "type": "external", "is_deletable": False, "page": "/mypag1"}, - {"name": "plugin3", "version": "1.0.0", "description": "This is plugin3", "type": "pro", "is_deletable": True, "page": ""}, - {"name": "plugin4", "version": "1.0.0", "description": "This is plugin4", "type": "pro", "is_deletable": True, "page": ""}, + {"id": "plugin1", "name": "plugin1", "version": "1.0.0", "description": "This is plugin1", "type": "core", "is_deletable": False, "page": "/mypage"}, + {"id": "plugin2", "name": "plugin2", "version": "1.0.0", "description": "This is plugin2", "type": "external", "is_deletable": False, "page": "/mypag1"}, + {"id": "plugin3", "name": "plugin3", "version": "1.0.0", "description": "This is plugin3", "type": "pro", "is_deletable": True, "page": ""}, + {"id": "plugin4", "name": "plugin4", "version": "1.0.0", "description": "This is plugin4", "type": "pro", "is_deletable": True, "page": ""}, ] types = ["core", "external", "pro"] diff --git a/src/ui/client/dashboard/components/Builder/Plugins.vue b/src/ui/client/dashboard/components/Builder/Plugins.vue index 81b9939aa..7f1358489 100644 --- a/src/ui/client/dashboard/components/Builder/Plugins.vue +++ b/src/ui/client/dashboard/components/Builder/Plugins.vue @@ -5,6 +5,7 @@ import GridLayout from "@components/Widget/GridLayout.vue"; import ListDetails from "@components/List/Details.vue"; import Title from "@components/Widget/Title.vue"; import Subtitle from "@components/Widget/Subtitle.vue"; +import Upload from "@components/Widget/Upload.vue"; import Text from "@components/Widget/Text.vue"; import Tabulator from "@components/Widget/Tabulator.vue"; import ButtonGroup from "@components/Widget/ButtonGroup.vue"; @@ -75,6 +76,10 @@ const props = defineProps({