feat: Tabs in column (#16593)

* fix:fix get permission function

* feat: add tabs inside column

* lint: fix lint

* test: fix test

* test: fix tests

* test: fix tests

* fix: pass onChangeTab function through layout
diff --git a/superset-frontend/spec/javascripts/dashboard/util/isValidChild_spec.ts b/superset-frontend/spec/javascripts/dashboard/util/isValidChild_spec.ts
index d689f1e..6ff56b8 100644
--- a/superset-frontend/spec/javascripts/dashboard/util/isValidChild_spec.ts
+++ b/superset-frontend/spec/javascripts/dashboard/util/isValidChild_spec.ts
@@ -83,6 +83,7 @@
       [ROOT, TABS, TAB, ROW, COLUMN, ROW, COLUMN, CHART],
       [ROOT, TABS, TAB, ROW, COLUMN, ROW, COLUMN, MARKDOWN],
       [ROOT, TABS, TAB, TABS, TAB, ROW, COLUMN, ROW, COLUMN, MARKDOWN],
+      [ROOT, GRID, ROW, COLUMN, TABS],
     ];
 
     validExamples.forEach((example, exampleIdx) => {
@@ -127,7 +128,6 @@
       [ROOT, GRID, ROW, [TABS]],
       [ROOT, GRID, ROW, [TAB]],
       [ROOT, GRID, ROW, [DIVIDER]],
-      [ROOT, GRID, ROW, COLUMN, [TABS]],
       [ROOT, GRID, ROW, COLUMN, [TAB]],
       [ROOT, GRID, ROW, COLUMN, ROW, [DIVIDER]],
       [ROOT, GRID, ROW, COLUMN, ROW, COLUMN, [ROW]], // too nested
diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
index 87f1cbc..9d44767 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
@@ -48,6 +48,7 @@
   dashboardId: PropTypes.number.isRequired,
   component: componentShape.isRequired,
   parentComponent: componentShape.isRequired,
+  getComponentById: PropTypes.func.isRequired,
   index: PropTypes.number.isRequired,
   depth: PropTypes.number.isRequired,
   editMode: PropTypes.bool.isRequired,
@@ -268,16 +269,22 @@
       isComponentVisible,
       dashboardId,
       fullSizeChartId,
+      getComponentById = () => undefined,
     } = this.props;
 
     const { chartId } = component.meta;
     const isFullSize = fullSizeChartId === chartId;
 
     // inherit the size of parent columns
-    const widthMultiple =
-      parentComponent.type === COLUMN_TYPE
-        ? parentComponent.meta.width || GRID_MIN_COLUMN_COUNT
-        : component.meta.width || GRID_MIN_COLUMN_COUNT;
+    const columnParentWidth = getComponentById(
+      parentComponent.parents?.find(parent => parent.startsWith(COLUMN_TYPE)),
+    )?.meta?.width;
+    let widthMultiple = component.meta.width || GRID_MIN_COLUMN_COUNT;
+    if (parentComponent.type === COLUMN_TYPE) {
+      widthMultiple = parentComponent.meta.width || GRID_MIN_COLUMN_COUNT;
+    } else if (columnParentWidth && widthMultiple > columnParentWidth) {
+      widthMultiple = columnParentWidth;
+    }
 
     let chartWidth = 0;
     let chartHeight = 0;
diff --git a/superset-frontend/src/dashboard/components/gridComponents/Column.jsx b/superset-frontend/src/dashboard/components/gridComponents/Column.jsx
index d636349..90666d6 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Column.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Column.jsx
@@ -110,6 +110,7 @@
       onResizeStop,
       handleComponentDrop,
       editMode,
+      onChangeTab,
       isComponentVisible,
     } = this.props;
 
@@ -191,6 +192,7 @@
                     onResize={onResize}
                     onResizeStop={onResizeStop}
                     isComponentVisible={isComponentVisible}
+                    onChangeTab={onChangeTab}
                   />
                 ))}
 
diff --git a/superset-frontend/src/dashboard/components/gridComponents/Row.jsx b/superset-frontend/src/dashboard/components/gridComponents/Row.jsx
index a6b3598..b0037bf 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Row.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Row.jsx
@@ -109,6 +109,7 @@
       onResizeStop,
       handleComponentDrop,
       editMode,
+      onChangeTab,
       isComponentVisible,
     } = this.props;
 
@@ -176,6 +177,7 @@
                   onResize={onResize}
                   onResizeStop={onResizeStop}
                   isComponentVisible={isComponentVisible}
+                  onChangeTab={onChangeTab}
                 />
               ))}
 
diff --git a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
index 5049715..12397ea 100644
--- a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
+++ b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
@@ -75,6 +75,7 @@
   const component = dashboardLayout[id];
   const props = {
     component,
+    getComponentById: id => dashboardLayout[id],
     parentComponent: dashboardLayout[parentId],
     editMode: dashboardState.editMode,
     filters: getActiveFilters(),
diff --git a/superset-frontend/src/dashboard/util/isValidChild.ts b/superset-frontend/src/dashboard/util/isValidChild.ts
index 70ec4d0..78d8984 100644
--- a/superset-frontend/src/dashboard/util/isValidChild.ts
+++ b/superset-frontend/src/dashboard/util/isValidChild.ts
@@ -48,7 +48,7 @@
 import { DASHBOARD_ROOT_DEPTH as rootDepth } from './constants';
 
 const depthOne = rootDepth + 1;
-const depthTwo = rootDepth + 2;
+// const depthTwo = rootDepth + 2; // Meantime no need
 const depthThree = rootDepth + 3;
 const depthFour = rootDepth + 4;
 const depthFive = rootDepth + 5;
@@ -77,17 +77,17 @@
   },
 
   [TABS_TYPE]: {
-    [TAB_TYPE]: depthTwo,
+    [TAB_TYPE]: depthThree,
   },
 
   [TAB_TYPE]: {
-    [CHART_TYPE]: depthTwo,
-    [MARKDOWN_TYPE]: depthTwo,
-    [COLUMN_TYPE]: depthTwo,
-    [DIVIDER_TYPE]: depthTwo,
-    [HEADER_TYPE]: depthTwo,
-    [ROW_TYPE]: depthTwo,
-    [TABS_TYPE]: depthTwo,
+    [CHART_TYPE]: depthFive,
+    [MARKDOWN_TYPE]: depthFive,
+    [COLUMN_TYPE]: depthThree,
+    [DIVIDER_TYPE]: depthFive,
+    [HEADER_TYPE]: depthFive,
+    [ROW_TYPE]: depthThree,
+    [TABS_TYPE]: depthThree,
   },
 
   [COLUMN_TYPE]: {
@@ -96,6 +96,7 @@
     [MARKDOWN_TYPE]: depthFive,
     [ROW_TYPE]: depthThree,
     [DIVIDER_TYPE]: depthThree,
+    [TABS_TYPE]: depthThree,
   },
 
   // these have no valid children