Merge branch 'master' of github.com:appsmithorg/appsmith
This commit is contained in:
commit
ef9a70b9e5
|
|
@ -8,12 +8,13 @@ import { scrollbarLight } from "constants/DefaultTheme";
|
|||
interface TabsComponentProps extends ComponentProps {
|
||||
children?: ReactNode;
|
||||
shouldScrollContents?: boolean;
|
||||
selectedTabId: string;
|
||||
selectedTabWidgetId: string;
|
||||
shouldShowTabs: boolean;
|
||||
onTabChange: (tabId: string) => void;
|
||||
tabs: Array<{
|
||||
id: string;
|
||||
label: string;
|
||||
widgetId: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
|
|
@ -120,10 +121,10 @@ const TabsComponent = (props: TabsComponentProps) => {
|
|||
props.tabs.map((tab, index) => (
|
||||
<StyledText
|
||||
onClick={(event: React.MouseEvent<HTMLDivElement>) => {
|
||||
props.onTabChange(tab.id);
|
||||
props.onTabChange(tab.widgetId);
|
||||
event.stopPropagation();
|
||||
}}
|
||||
selected={props.selectedTabId === tab.id}
|
||||
selected={props.selectedTabWidgetId === tab.widgetId}
|
||||
key={index}
|
||||
>
|
||||
{tab.label}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ class TabControl extends BaseControl<ControlProps> {
|
|||
};
|
||||
|
||||
addOption = () => {
|
||||
const tabs: Array<{
|
||||
let tabs: Array<{
|
||||
id: string;
|
||||
label: string;
|
||||
widgetId: string;
|
||||
|
|
@ -169,11 +169,11 @@ class TabControl extends BaseControl<ControlProps> {
|
|||
"Tab ",
|
||||
tabs.map(tab => tab.label),
|
||||
);
|
||||
tabs.push({
|
||||
id: newTabId,
|
||||
label: newTabLabel,
|
||||
widgetId: generateReactKey(),
|
||||
});
|
||||
tabs = [
|
||||
...tabs,
|
||||
{ id: newTabId, label: newTabLabel, widgetId: generateReactKey() },
|
||||
];
|
||||
|
||||
this.updateProperty(this.props.propertyName, JSON.stringify(tabs));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
|
|||
{
|
||||
type: "MODIFY_PROPS",
|
||||
fn: (widget: WidgetProps & { children?: WidgetProps[] }) => {
|
||||
const tabs = widget.tabs;
|
||||
const tabs = [...widget.tabs];
|
||||
|
||||
const newTabs = tabs.map((tab: any) => {
|
||||
tab.widgetId = generateReactKey();
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ import { forceOpenPropertyPane } from "actions/widgetActions";
|
|||
import { getDataTree } from "selectors/dataTreeSelectors";
|
||||
import { DataTreeWidget } from "entities/DataTree/dataTreeFactory";
|
||||
import { validateProperty } from "./evaluationsSaga";
|
||||
import { WidgetBlueprint } from "reducers/entityReducers/widgetConfigReducer";
|
||||
|
||||
function getChildWidgetProps(
|
||||
parent: FlattenedWidgetProps,
|
||||
|
|
@ -89,10 +90,12 @@ function getChildWidgetProps(
|
|||
const { leftColumn, topRow, newWidgetId, props, type } = params;
|
||||
let { rows, columns, parentColumnSpace, parentRowSpace, widgetName } = params;
|
||||
let minHeight = undefined;
|
||||
const defaultConfig: any = WidgetConfigResponse.config[type];
|
||||
const { blueprint = undefined, ...restDefaultConfig } = {
|
||||
...(WidgetConfigResponse as any).config[type],
|
||||
};
|
||||
if (!widgetName) {
|
||||
const widgetNames = Object.keys(widgets).map(w => widgets[w].widgetName);
|
||||
widgetName = getNextEntityName(defaultConfig.widgetName, widgetNames);
|
||||
widgetName = getNextEntityName(restDefaultConfig.widgetName, widgetNames);
|
||||
}
|
||||
if (type === WidgetTypes.CANVAS_WIDGET) {
|
||||
columns =
|
||||
|
|
@ -104,7 +107,13 @@ function getChildWidgetProps(
|
|||
if (props) props.children = [];
|
||||
}
|
||||
|
||||
const widgetProps = { ...defaultConfig, ...props, columns, rows, minHeight };
|
||||
const widgetProps = {
|
||||
...restDefaultConfig,
|
||||
...props,
|
||||
columns,
|
||||
rows,
|
||||
minHeight,
|
||||
};
|
||||
const widget = generateWidgetProps(
|
||||
parent,
|
||||
type,
|
||||
|
|
@ -127,41 +136,80 @@ function* generateChildWidgets(
|
|||
parent: FlattenedWidgetProps,
|
||||
params: WidgetAddChild,
|
||||
widgets: { [widgetId: string]: FlattenedWidgetProps },
|
||||
propsBlueprint?: WidgetBlueprint,
|
||||
): any {
|
||||
// Get the props for the widget
|
||||
const widget = yield getChildWidgetProps(parent, params, widgets);
|
||||
|
||||
// Add the widget to the canvasWidgets
|
||||
// We need this in here as widgets will be used to get the current widget
|
||||
widgets[widget.widgetId] = widget;
|
||||
if (widget.blueprint && widget.blueprint.view) {
|
||||
|
||||
// Get the default config for the widget from WidgetConfigResponse
|
||||
const defaultConfig = {
|
||||
...(WidgetConfigResponse as any).config[widget.type],
|
||||
};
|
||||
|
||||
// If blueprint is provided in the params, use that
|
||||
// else use the blueprint available in WidgetConfigResponse
|
||||
// else there is no blueprint for this widget
|
||||
const blueprint =
|
||||
propsBlueprint || { ...defaultConfig.blueprint } || undefined;
|
||||
|
||||
// If there is a blueprint.view
|
||||
// We need to generate the children based on the view
|
||||
if (blueprint && blueprint.view) {
|
||||
// Get the list of children props in WidgetAddChild format
|
||||
const childWidgetList: WidgetAddChild[] = yield call(
|
||||
buildWidgetBlueprint,
|
||||
widget.blueprint,
|
||||
blueprint,
|
||||
widget.widgetId,
|
||||
);
|
||||
// For each child props
|
||||
const childPropsList: GeneratedWidgetPayload[] = yield all(
|
||||
childWidgetList.map((props: WidgetAddChild) => {
|
||||
return generateChildWidgets(widget, props, widgets);
|
||||
// Generate full widget props
|
||||
// Notice that we're passing the blueprint if it exists.
|
||||
return generateChildWidgets(
|
||||
widget,
|
||||
props,
|
||||
widgets,
|
||||
props.props?.blueprint,
|
||||
);
|
||||
}),
|
||||
);
|
||||
// Start children array from scratch
|
||||
widget.children = [];
|
||||
childPropsList.forEach((props: GeneratedWidgetPayload) => {
|
||||
// Push the widgetIds of the children generated above into the widget.children array
|
||||
widget.children.push(props.widgetId);
|
||||
// Add the list of widgets generated into the canvasWidgets
|
||||
widgets = props.widgets;
|
||||
});
|
||||
}
|
||||
|
||||
// Finally, add the widget to the canvasWidgets
|
||||
// This is different from above, as this is the final widget props with
|
||||
// a fully populated widget.children property
|
||||
widgets[widget.widgetId] = widget;
|
||||
if (
|
||||
widget.blueprint &&
|
||||
widget.blueprint.operations &&
|
||||
widget.blueprint.operations.length > 0
|
||||
) {
|
||||
|
||||
// Some widgets need to run a few operations like modifying props or adding an action
|
||||
// these operations can be performed on the parent of the widget we're adding
|
||||
// therefore, we pass all widgets to executeWidgetBlueprintOperations
|
||||
// blueprint.operations contain the set of operations to perform to update the canvasWidgets
|
||||
if (blueprint && blueprint.operations && blueprint.operations.length > 0) {
|
||||
// Finalize the canvasWidgets with everything that needs to be updated
|
||||
widgets = yield call(
|
||||
executeWidgetBlueprintOperations,
|
||||
widget.blueprint.operations,
|
||||
blueprint.operations,
|
||||
widgets,
|
||||
widget.widgetId,
|
||||
);
|
||||
}
|
||||
// Add the parentId prop to this widget
|
||||
widget.parentId = parent.widgetId;
|
||||
// Remove the blueprint from the widget (if any)
|
||||
// as blueprints are not useful beyont this point.
|
||||
delete widget.blueprint;
|
||||
return { widgetId: widget.widgetId, widgets };
|
||||
}
|
||||
|
|
@ -847,17 +895,11 @@ function* pasteWidgetSaga() {
|
|||
} else {
|
||||
// If the widget in which to paste the new widget is a tabs widget
|
||||
// Find the currently selected tab canvas widget
|
||||
const { selectedTabId } = yield select(
|
||||
const { selectedTabWidgetId } = yield select(
|
||||
getWidgetMetaProps,
|
||||
parentWidget.widgetId,
|
||||
);
|
||||
const tabs = _.isString(parentWidget.tabs)
|
||||
? JSON.parse(parentWidget.tabs)
|
||||
: parentWidget.tabs;
|
||||
const childWidgetId =
|
||||
tabs.find((tab: any) => tab.id === selectedTabId)?.widgetId ||
|
||||
parentWidget.children[0];
|
||||
childWidget = widgets[childWidgetId];
|
||||
if (selectedTabWidgetId) childWidget = widgets[selectedTabWidgetId];
|
||||
}
|
||||
// If the finally selected parent in which to paste the widget
|
||||
// is a CANVAS_WIDGET, use its widgetId as the new widget's parent Id
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ class TabsWidget extends BaseWidget<
|
|||
};
|
||||
}
|
||||
|
||||
onTabChange = (tabId: string) => {
|
||||
this.props.updateWidgetMetaProperty("selectedTabId", tabId, {
|
||||
onTabChange = (tabWidgetId: string) => {
|
||||
this.props.updateWidgetMetaProperty("selectedTabWidgetId", tabWidgetId, {
|
||||
dynamicString: this.props.onTabSelected,
|
||||
event: {
|
||||
type: EventType.ON_TAB_CHANGE,
|
||||
|
|
@ -34,7 +34,7 @@ class TabsWidget extends BaseWidget<
|
|||
|
||||
static getDerivedPropertiesMap() {
|
||||
return {
|
||||
selectedTab: `{{_.find(this.tabs, { id: this.selectedTabId }).label}}`,
|
||||
selectedTab: `{{_.find(this.tabs, { widgetId: this.selectedTabWidgetId }).label}}`,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -59,12 +59,11 @@ class TabsWidget extends BaseWidget<
|
|||
}
|
||||
|
||||
renderComponent = () => {
|
||||
const selectedTabId = this.props.selectedTabId;
|
||||
|
||||
const selectedTabWidgetId = this.props.selectedTabWidgetId;
|
||||
const childWidgetData: TabContainerWidgetProps = this.props.children
|
||||
?.filter(Boolean)
|
||||
.filter(item => {
|
||||
return selectedTabId === item.tabId;
|
||||
return selectedTabWidgetId === item.widgetId;
|
||||
})[0];
|
||||
if (!childWidgetData) {
|
||||
return null;
|
||||
|
|
@ -171,8 +170,13 @@ class TabsWidget extends BaseWidget<
|
|||
const selectedTab = _.find(this.props.tabs, {
|
||||
label: this.props.defaultTab,
|
||||
});
|
||||
const selectedTabId = selectedTab ? selectedTab.id : undefined;
|
||||
this.props.updateWidgetMetaProperty("selectedTabId", selectedTabId);
|
||||
const selectedTabWidgetId = selectedTab
|
||||
? selectedTab.widgetId
|
||||
: undefined;
|
||||
this.props.updateWidgetMetaProperty(
|
||||
"selectedTabWidgetId",
|
||||
selectedTabWidgetId,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -221,18 +225,24 @@ class TabsWidget extends BaseWidget<
|
|||
label: this.props.defaultTab,
|
||||
});
|
||||
// Find the default Tab id
|
||||
const selectedTabId = selectedTab?.id;
|
||||
const selectedTabWidgetId = selectedTab?.widgetId;
|
||||
// If we have a legitimate default tab Id and it is not already the selected Tab
|
||||
if (selectedTabId && selectedTabId !== this.props.selectedTabId) {
|
||||
if (
|
||||
selectedTabWidgetId &&
|
||||
selectedTabWidgetId !== this.props.selectedTabWidgetId
|
||||
) {
|
||||
// Select the default tab
|
||||
this.props.updateWidgetMetaProperty("selectedTabId", selectedTabId);
|
||||
this.props.updateWidgetMetaProperty(
|
||||
"selectedTabWidgetId",
|
||||
selectedTabWidgetId,
|
||||
);
|
||||
}
|
||||
} else if (!this.props.selectedTabId) {
|
||||
} else if (!this.props.selectedTabWidgetId) {
|
||||
// If no tab is selected
|
||||
// Select the first tab in the tabs list.
|
||||
this.props.updateWidgetMetaProperty(
|
||||
"selectedTabId",
|
||||
this.props.tabs[0].id,
|
||||
"selectedTabWidgetId",
|
||||
this.props.tabs[0].widgetId,
|
||||
);
|
||||
}
|
||||
this.generateTabContainers();
|
||||
|
|
@ -259,7 +269,7 @@ export interface TabsWidgetProps<T extends TabContainerWidgetProps>
|
|||
onTabSelected?: string;
|
||||
snapRows?: number;
|
||||
defaultTab: string;
|
||||
selectedTabId: string;
|
||||
selectedTabWidgetId: string;
|
||||
}
|
||||
|
||||
export default TabsWidget;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user