fix: move create app from template flow logic from state to redux (#31177)
## Description This PR attempts to move logic from state to redux. For some reason state logic is not getting transferred to release and prod sites. #### PR fixes following issue(s) Fixes # (issue number) > if no issue exists, please create an issue and ask the maintainers about this first > > #### Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video > > #### Type of change > Please delete options that are not relevant. - Bug fix (non-breaking change which fixes an issue) - New feature (non-breaking change which adds functionality) - Breaking change (fix or feature that would cause existing functionality to not work as expected) - Chore (housekeeping or task changes that don't impact user perception) - This change requires a documentation update > > > ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] JUnit - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a new modal for creating applications from templates, enhancing user experience. - **Enhancements** - Improved state management for the create app from templates modal using Redux, ensuring smoother user interactions. - **Refactor** - Streamlined the application creation process from templates by removing redundant code and utilizing Redux actions for better maintainability. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
712a28e059
commit
d6fadc2dc2
|
|
@ -118,3 +118,11 @@ export const setActiveLoadingTemplateId = (templateId: string) => ({
|
||||||
type: ReduxActionTypes.SET_ACTIVE_LOADING_TEMPLATE_ID,
|
type: ReduxActionTypes.SET_ACTIVE_LOADING_TEMPLATE_ID,
|
||||||
payload: templateId,
|
payload: templateId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const showCreateAppFromTemplatesModal = () => ({
|
||||||
|
type: ReduxActionTypes.SHOW_CREATE_APP_FROM_TEMPLATES_MODAL,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const hideCreateAppFromTemplatesModal = () => ({
|
||||||
|
type: ReduxActionTypes.HIDE_CREATE_APP_FROM_TEMPLATES_MODAL,
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -732,6 +732,8 @@ const ActionTypes = {
|
||||||
REMOVE_FROM_RECENTLY_ADDED_WIDGET: "REMOVE_FROM_RECENTLY_ADDED_WIDGET",
|
REMOVE_FROM_RECENTLY_ADDED_WIDGET: "REMOVE_FROM_RECENTLY_ADDED_WIDGET",
|
||||||
SHOW_TEMPLATES_MODAL: "SHOW_TEMPLATES_MODAL",
|
SHOW_TEMPLATES_MODAL: "SHOW_TEMPLATES_MODAL",
|
||||||
HIDE_TEMPLATES_MODAL: "HIDE_TEMPLATES_MODAL",
|
HIDE_TEMPLATES_MODAL: "HIDE_TEMPLATES_MODAL",
|
||||||
|
SHOW_CREATE_APP_FROM_TEMPLATES_MODAL: "SHOW_CREATE_APP_FROM_TEMPLATES_MODAL",
|
||||||
|
HIDE_CREATE_APP_FROM_TEMPLATES_MODAL: "HIDE_CREATE_APP_FROM_TEMPLATES_MODAL",
|
||||||
GET_TEMPLATE_FILTERS_INIT: "GET_TEMPLATE_FILTERS_INIT",
|
GET_TEMPLATE_FILTERS_INIT: "GET_TEMPLATE_FILTERS_INIT",
|
||||||
GET_TEMPLATE_FILTERS_SUCCESS: "GET_TEMPLATE_FILTERS_SUCCESS",
|
GET_TEMPLATE_FILTERS_SUCCESS: "GET_TEMPLATE_FILTERS_SUCCESS",
|
||||||
INIT_TRIGGER_VALUES: "INIT_TRIGGER_VALUES",
|
INIT_TRIGGER_VALUES: "INIT_TRIGGER_VALUES",
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,27 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import CreateNewAppFromTemplatesModal from ".";
|
import CreateNewAppFromTemplatesModal from ".";
|
||||||
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { createAppFromTemplatesModalSelector } from "selectors/templatesSelectors";
|
||||||
|
import { hideCreateAppFromTemplatesModal } from "actions/templateActions";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
currentWorkspaceId: string;
|
currentWorkspaceId: string;
|
||||||
handleClose: () => void;
|
|
||||||
isOpen: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreateNewAppFromTemplatesWrapper = ({
|
const CreateNewAppFromTemplatesWrapper = ({ currentWorkspaceId }: Props) => {
|
||||||
currentWorkspaceId,
|
|
||||||
handleClose,
|
|
||||||
isOpen,
|
|
||||||
}: Props) => {
|
|
||||||
const isCreateAppFromTemplatesEnabled = useFeatureFlag(
|
const isCreateAppFromTemplatesEnabled = useFeatureFlag(
|
||||||
"release_show_create_app_from_templates_enabled",
|
"release_show_create_app_from_templates_enabled",
|
||||||
);
|
);
|
||||||
|
const isOpen = useSelector(createAppFromTemplatesModalSelector);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
if (!isCreateAppFromTemplatesEnabled) return null;
|
if (!isCreateAppFromTemplatesEnabled) return null;
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
dispatch(hideCreateAppFromTemplatesModal());
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CreateNewAppFromTemplatesModal
|
<CreateNewAppFromTemplatesModal
|
||||||
currentWorkSpaceId={currentWorkspaceId}
|
currentWorkSpaceId={currentWorkspaceId}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
||||||
import CreateNewAppFromTemplatesWrapper from "./CreateNewAppFromTemplateModal/CreateNewAppFromTemplatesWrapper";
|
import CreateNewAppFromTemplatesWrapper from "./CreateNewAppFromTemplateModal/CreateNewAppFromTemplatesWrapper";
|
||||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||||
import ImportModal from "pages/common/ImportModal";
|
import ImportModal from "pages/common/ImportModal";
|
||||||
|
import { showCreateAppFromTemplatesModal } from "actions/templateActions";
|
||||||
|
|
||||||
export const { cloudHosting } = getAppsmithConfigs();
|
export const { cloudHosting } = getAppsmithConfigs();
|
||||||
|
|
||||||
|
|
@ -494,14 +495,8 @@ export const WorkspaceSelectorWrapper = styled.div`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function ApplicationsSection(props: any) {
|
export function ApplicationsSection(props: any) {
|
||||||
const {
|
const { activeWorkspaceId, applications, packages, workflows, workspaces } =
|
||||||
activeWorkspaceId,
|
props;
|
||||||
applications,
|
|
||||||
onStartFromTemplateClick,
|
|
||||||
packages,
|
|
||||||
workflows,
|
|
||||||
workspaces,
|
|
||||||
} = props;
|
|
||||||
const enableImportExport = true;
|
const enableImportExport = true;
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const theme = useContext(ThemeContext);
|
const theme = useContext(ThemeContext);
|
||||||
|
|
@ -642,7 +637,7 @@ export function ApplicationsSection(props: any) {
|
||||||
|
|
||||||
const onCreateNewApplicationFromTemplate = () => {
|
const onCreateNewApplicationFromTemplate = () => {
|
||||||
AnalyticsUtil.logEvent("TEMPLATE_DROPDOWN_CLICK");
|
AnalyticsUtil.logEvent("TEMPLATE_DROPDOWN_CLICK");
|
||||||
onStartFromTemplateClick();
|
dispatch(showCreateAppFromTemplatesModal());
|
||||||
};
|
};
|
||||||
|
|
||||||
function NoWorkspaceFound() {
|
function NoWorkspaceFound() {
|
||||||
|
|
@ -969,7 +964,6 @@ export const ApplictionsMainPage = (props: any) => {
|
||||||
<ApplicationsSection
|
<ApplicationsSection
|
||||||
activeWorkspaceId={activeWorkspaceId}
|
activeWorkspaceId={activeWorkspaceId}
|
||||||
applications={fetchedApplications}
|
applications={fetchedApplications}
|
||||||
onStartFromTemplateClick={props.onStartFromTemplateClick}
|
|
||||||
packages={packagesOfWorkspace}
|
packages={packagesOfWorkspace}
|
||||||
searchKeyword={searchKeyword}
|
searchKeyword={searchKeyword}
|
||||||
workflows={workflowsOfWorkspace}
|
workflows={workflowsOfWorkspace}
|
||||||
|
|
@ -1011,9 +1005,7 @@ export interface ApplicationProps {
|
||||||
isReconnectModalOpen: boolean;
|
isReconnectModalOpen: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApplicationState {
|
export interface ApplicationState {}
|
||||||
startFromTemplate: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Applications<
|
export class Applications<
|
||||||
Props extends ApplicationProps,
|
Props extends ApplicationProps,
|
||||||
|
|
@ -1021,19 +1013,6 @@ export class Applications<
|
||||||
> extends Component<Props, State> {
|
> extends Component<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
|
||||||
startFromTemplate: false,
|
|
||||||
} as State;
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps: Readonly<Props>): void {
|
|
||||||
if (
|
|
||||||
prevProps.isReconnectModalOpen !== this.props.isReconnectModalOpen &&
|
|
||||||
this.props.isReconnectModalOpen
|
|
||||||
) {
|
|
||||||
this.setState({ startFromTemplate: false });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
@ -1057,10 +1036,6 @@ export class Applications<
|
||||||
this.props.searchApplications("");
|
this.props.searchApplications("");
|
||||||
}
|
}
|
||||||
|
|
||||||
handleStartFromTemplate() {
|
|
||||||
this.setState({ startFromTemplate: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
if (this.props.currentApplicationIdForCreateNewApp) {
|
if (this.props.currentApplicationIdForCreateNewApp) {
|
||||||
// FOR NEW USER
|
// FOR NEW USER
|
||||||
|
|
@ -1080,16 +1055,11 @@ export class Applications<
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ApplictionsMainPage
|
<ApplictionsMainPage
|
||||||
onStartFromTemplateClick={this.handleStartFromTemplate.bind(this)}
|
|
||||||
searchApplications={this.props.searchApplications}
|
searchApplications={this.props.searchApplications}
|
||||||
searchKeyword={this.props.searchKeyword}
|
searchKeyword={this.props.searchKeyword}
|
||||||
/>
|
/>
|
||||||
<CreateNewAppFromTemplatesWrapper
|
<CreateNewAppFromTemplatesWrapper
|
||||||
currentWorkspaceId={this.props.currentWorkspaceId}
|
currentWorkspaceId={this.props.currentWorkspaceId}
|
||||||
handleClose={() => {
|
|
||||||
this.setState({ startFromTemplate: false });
|
|
||||||
}}
|
|
||||||
isOpen={this.state.startFromTemplate}
|
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ const initialState: TemplatesReduxState = {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
isOpenFromCanvas: false,
|
isOpenFromCanvas: false,
|
||||||
},
|
},
|
||||||
|
isCreateAppFromTemplateModalOpen: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const templateReducer = createReducer(initialState, {
|
const templateReducer = createReducer(initialState, {
|
||||||
|
|
@ -264,6 +265,22 @@ const templateReducer = createReducer(initialState, {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
[ReduxActionTypes.SHOW_CREATE_APP_FROM_TEMPLATES_MODAL]: (
|
||||||
|
state: TemplatesReduxState,
|
||||||
|
) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isCreateAppFromTemplateModalOpen: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[ReduxActionTypes.HIDE_CREATE_APP_FROM_TEMPLATES_MODAL]: (
|
||||||
|
state: TemplatesReduxState,
|
||||||
|
) => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isCreateAppFromTemplateModalOpen: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
[ReduxActionTypes.GET_TEMPLATE_FILTERS_INIT]: (
|
[ReduxActionTypes.GET_TEMPLATE_FILTERS_INIT]: (
|
||||||
state: TemplatesReduxState,
|
state: TemplatesReduxState,
|
||||||
) => {
|
) => {
|
||||||
|
|
@ -313,6 +330,7 @@ export interface TemplatesReduxState {
|
||||||
isOpenFromCanvas: boolean;
|
isOpenFromCanvas: boolean;
|
||||||
};
|
};
|
||||||
loadingFilters: boolean;
|
loadingFilters: boolean;
|
||||||
|
isCreateAppFromTemplateModalOpen: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default templateReducer;
|
export default templateReducer;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import { getDefaultPageId } from "@appsmith/sagas/ApplicationSagas";
|
||||||
import { getDefaultPageId as selectDefaultPageId } from "sagas/selectors";
|
import { getDefaultPageId as selectDefaultPageId } from "sagas/selectors";
|
||||||
import {
|
import {
|
||||||
getAllTemplates,
|
getAllTemplates,
|
||||||
|
hideCreateAppFromTemplatesModal,
|
||||||
hideTemplatesModal,
|
hideTemplatesModal,
|
||||||
setTemplateNotificationSeenAction,
|
setTemplateNotificationSeenAction,
|
||||||
showStarterBuildingBlockDatasourcePrompt,
|
showStarterBuildingBlockDatasourcePrompt,
|
||||||
|
|
@ -65,6 +66,7 @@ import { isAirgapped } from "@appsmith/utils/airgapHelpers";
|
||||||
import { STARTER_BUILDING_BLOCKS } from "constants/TemplatesConstants";
|
import { STARTER_BUILDING_BLOCKS } from "constants/TemplatesConstants";
|
||||||
import urlBuilder from "@appsmith/entities/URLRedirect/URLAssembly";
|
import urlBuilder from "@appsmith/entities/URLRedirect/URLAssembly";
|
||||||
import { fetchJSLibraries } from "actions/JSLibraryActions";
|
import { fetchJSLibraries } from "actions/JSLibraryActions";
|
||||||
|
import { createAppFromTemplatesModalSelector } from "selectors/templatesSelectors";
|
||||||
|
|
||||||
const isAirgappedInstance = isAirgapped();
|
const isAirgappedInstance = isAirgapped();
|
||||||
|
|
||||||
|
|
@ -128,6 +130,12 @@ function* importTemplateToWorkspaceSaga(
|
||||||
history.push(pageURL);
|
history.push(pageURL);
|
||||||
}
|
}
|
||||||
yield put(getAllTemplates());
|
yield put(getAllTemplates());
|
||||||
|
const isCreateAppFromTemplateModal: boolean = yield select(
|
||||||
|
createAppFromTemplatesModalSelector,
|
||||||
|
);
|
||||||
|
if (isCreateAppFromTemplateModal) {
|
||||||
|
yield put(hideCreateAppFromTemplatesModal());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
yield put({
|
yield put({
|
||||||
|
|
|
||||||
|
|
@ -225,3 +225,6 @@ export const templatesCountSelector = (state: AppState) =>
|
||||||
|
|
||||||
export const activeLoadingTemplateId = (state: AppState) =>
|
export const activeLoadingTemplateId = (state: AppState) =>
|
||||||
state.ui.templates.activeLoadingTemplateId;
|
state.ui.templates.activeLoadingTemplateId;
|
||||||
|
|
||||||
|
export const createAppFromTemplatesModalSelector = (state: AppState) =>
|
||||||
|
state.ui.templates.isCreateAppFromTemplateModalOpen;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user