This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch plugin-architecture-poc
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 904fbd95dc3c218e65548519fdb5cf2abd55973f
Author: Michael S. Molina <[email protected]>
AuthorDate: Mon Jan 20 16:17:56 2025 -0300

    chore: Plugins architecture POC
---
 superset-frontend/src/pages/SqlLabPoc/index.tsx | 145 ++++++++++++++++++++++++
 superset-frontend/src/views/routes.tsx          |   8 ++
 superset/initialization/__init__.py             |  11 ++
 superset/views/sqllab_poc.py                    |  41 +++++++
 4 files changed, 205 insertions(+)

diff --git a/superset-frontend/src/pages/SqlLabPoc/index.tsx 
b/superset-frontend/src/pages/SqlLabPoc/index.tsx
new file mode 100644
index 0000000000..247c368e6a
--- /dev/null
+++ b/superset-frontend/src/pages/SqlLabPoc/index.tsx
@@ -0,0 +1,145 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { CSSObject } from '@emotion/react';
+import { css, styled } from '@superset-ui/core';
+import Icons from 'src/components/Icons';
+
+const PlaceholderStyles: CSSObject = css`
+  flex: 1;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  gap: 12px;
+`;
+
+const MainPanel = styled.div`
+  flex: 1;
+  display: flex;
+  flex-direction: row;
+`;
+
+const Toolbar = () => {
+  return (
+    <div
+      css={css`
+        display: flex;
+        flex-direction: column;
+        gap: 12px;
+        margin: 8px;
+      `}
+    >
+      <Icons.Table />
+      <Icons.NavDashboard />
+    </div>
+  );
+};
+
+const LeftPanel = () => {
+  const plugins = [];
+  for (let i = 0; i < 3; i++) {
+    plugins.push(
+      <div
+        css={theme => css`
+          ${PlaceholderStyles};
+          border-bottom: 1px solid ${theme.colors.grayscale.light2};
+        `}
+      >
+        <Icons.Cards />
+        {`Plugin ${i + 1}`}
+      </div>,
+    );
+  }
+  return (
+    <div
+      css={theme => css`
+        width: 400px;
+        gap: 12px;
+        display: flex;
+        flex-direction: column;
+        border-left: 1px solid ${theme.colors.grayscale.light2};
+        border-right: 1px solid ${theme.colors.grayscale.light2};
+      `}
+    >
+      {plugins}
+    </div>
+  );
+};
+
+const CenterPanel = styled.div`
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+`;
+
+const CenterTopPanel = () => {
+  return (
+    <div
+      css={theme => css`
+        ${PlaceholderStyles};
+        border-bottom: 1px solid ${theme.colors.grayscale.light2};
+      `}
+    >
+      <Icons.Cards />
+      SQL Editor plugin
+    </div>
+  );
+};
+
+const CenterBottomPanel = () => {
+  return (
+    <div css={PlaceholderStyles}>
+      <Icons.Cards />
+      SQL execution plugins
+    </div>
+  );
+};
+
+const RightPanel = () => {
+  return (
+    <div
+      css={theme => css`
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        gap: 12px;
+        border-left: 1px solid ${theme.colors.grayscale.light2};
+        width: 400px;
+      `}
+    >
+      <Icons.Cards />
+      AI Chat plugin
+    </div>
+  );
+};
+
+const SqlLabPoc = () => {
+  return (
+    <MainPanel>
+      <Toolbar />
+      <LeftPanel />
+      <CenterPanel>
+        <CenterTopPanel />
+        <CenterBottomPanel />
+      </CenterPanel>
+      <RightPanel />
+    </MainPanel>
+  );
+};
+
+export default SqlLabPoc;
diff --git a/superset-frontend/src/views/routes.tsx 
b/superset-frontend/src/views/routes.tsx
index 7044e8940a..1c8e0397f9 100644
--- a/superset-frontend/src/views/routes.tsx
+++ b/superset-frontend/src/views/routes.tsx
@@ -108,6 +108,10 @@ const SqlLab = lazy(
   () => import(/* webpackChunkName: "SqlLab" */ 'src/pages/SqlLab'),
 );
 
+const SqlLabPoc = lazy(
+  () => import(/* webpackChunkName: "SqlLabPoc" */ 'src/pages/SqlLabPoc'),
+);
+
 const AllEntities = lazy(
   () => import(/* webpackChunkName: "AllEntities" */ 'src/pages/AllEntities'),
 );
@@ -225,6 +229,10 @@ export const routes: Routes = [
     path: '/sqllab/',
     Component: SqlLab,
   },
+  {
+    path: '/sqllab_poc/',
+    Component: SqlLabPoc,
+  },
 ];
 
 if (isFeatureEnabled(FeatureFlag.TaggingSystem)) {
diff --git a/superset/initialization/__init__.py 
b/superset/initialization/__init__.py
index a57325c359..729e87adb5 100644
--- a/superset/initialization/__init__.py
+++ b/superset/initialization/__init__.py
@@ -188,6 +188,7 @@ class SupersetAppInitializer:  # pylint: 
disable=too-many-public-methods
             TabStateView,
         )
         from superset.views.sqllab import SqllabView
+        from superset.views.sqllab_poc import SqlLabPocView
         from superset.views.tags import TagModelView, TagView
         from superset.views.users.api import CurrentUserRestApi, UserRestApi
 
@@ -309,6 +310,7 @@ class SupersetAppInitializer:  # pylint: 
disable=too-many-public-methods
         appbuilder.add_view_no_menu(SavedQueryViewApi)
         appbuilder.add_view_no_menu(SliceAsync)
         appbuilder.add_view_no_menu(SqllabView)
+        appbuilder.add_view_no_menu(SqlLabPocView)
         appbuilder.add_view_no_menu(SqlMetricInlineView)
         appbuilder.add_view_no_menu(Superset)
         appbuilder.add_view_no_menu(TableColumnInlineView)
@@ -331,6 +333,15 @@ class SupersetAppInitializer:  # pylint: 
disable=too-many-public-methods
             category="SQL Lab",
             category_label=__("SQL"),
         )
+        appbuilder.add_link(
+            "SQL Editor POC",
+            label=__("SQL Lab POC"),
+            href="/sqllab_poc/",
+            category_icon="fa-flask",
+            icon="fa-flask",
+            category="SQL Lab",
+            category_label=__("SQL"),
+        )
         appbuilder.add_link(
             "Saved Queries",
             label=__("Saved Queries"),
diff --git a/superset/views/sqllab_poc.py b/superset/views/sqllab_poc.py
new file mode 100644
index 0000000000..724830af72
--- /dev/null
+++ b/superset/views/sqllab_poc.py
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from typing import Any
+
+from flask_appbuilder import permission_name
+from flask_appbuilder.api import expose
+from flask_appbuilder.security.decorators import has_access
+
+from superset import event_logger
+from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP
+from superset.superset_typing import FlaskResponse
+
+from .base import BaseSupersetView
+
+
+class SqlLabPocView(BaseSupersetView):
+    route_base = "/sqllab_poc"
+    class_permission_name = "SQLLab"
+
+    method_permission_name = MODEL_API_RW_METHOD_PERMISSION_MAP
+
+    @expose("/", methods=["GET", "POST"])
+    @has_access
+    @permission_name("read")
+    @event_logger.log_this
+    def root(self, **kwargs: Any) -> FlaskResponse:
+        return self.render_app_template()

Reply via email to