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:
Rahul Barwal 2024-02-16 16:04:35 +05:30 committed by GitHub
parent 712a28e059
commit d6fadc2dc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 54 additions and 42 deletions

View File

@ -118,3 +118,11 @@ export const setActiveLoadingTemplateId = (templateId: string) => ({
type: ReduxActionTypes.SET_ACTIVE_LOADING_TEMPLATE_ID,
payload: templateId,
});
export const showCreateAppFromTemplatesModal = () => ({
type: ReduxActionTypes.SHOW_CREATE_APP_FROM_TEMPLATES_MODAL,
});
export const hideCreateAppFromTemplatesModal = () => ({
type: ReduxActionTypes.HIDE_CREATE_APP_FROM_TEMPLATES_MODAL,
});

View File

@ -732,6 +732,8 @@ const ActionTypes = {
REMOVE_FROM_RECENTLY_ADDED_WIDGET: "REMOVE_FROM_RECENTLY_ADDED_WIDGET",
SHOW_TEMPLATES_MODAL: "SHOW_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_SUCCESS: "GET_TEMPLATE_FILTERS_SUCCESS",
INIT_TRIGGER_VALUES: "INIT_TRIGGER_VALUES",

View File

@ -1,24 +1,27 @@
import React from "react";
import CreateNewAppFromTemplatesModal from ".";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { useDispatch, useSelector } from "react-redux";
import { createAppFromTemplatesModalSelector } from "selectors/templatesSelectors";
import { hideCreateAppFromTemplatesModal } from "actions/templateActions";
interface Props {
currentWorkspaceId: string;
handleClose: () => void;
isOpen: boolean;
}
const CreateNewAppFromTemplatesWrapper = ({
currentWorkspaceId,
handleClose,
isOpen,
}: Props) => {
const CreateNewAppFromTemplatesWrapper = ({ currentWorkspaceId }: Props) => {
const isCreateAppFromTemplatesEnabled = useFeatureFlag(
"release_show_create_app_from_templates_enabled",
);
const isOpen = useSelector(createAppFromTemplatesModalSelector);
const dispatch = useDispatch();
if (!isCreateAppFromTemplatesEnabled) return null;
const handleClose = () => {
dispatch(hideCreateAppFromTemplatesModal());
};
return (
<CreateNewAppFromTemplatesModal
currentWorkSpaceId={currentWorkspaceId}

View File

@ -129,6 +129,7 @@ import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import CreateNewAppFromTemplatesWrapper from "./CreateNewAppFromTemplateModal/CreateNewAppFromTemplatesWrapper";
import AnalyticsUtil from "utils/AnalyticsUtil";
import ImportModal from "pages/common/ImportModal";
import { showCreateAppFromTemplatesModal } from "actions/templateActions";
export const { cloudHosting } = getAppsmithConfigs();
@ -494,14 +495,8 @@ export const WorkspaceSelectorWrapper = styled.div`
`;
export function ApplicationsSection(props: any) {
const {
activeWorkspaceId,
applications,
onStartFromTemplateClick,
packages,
workflows,
workspaces,
} = props;
const { activeWorkspaceId, applications, packages, workflows, workspaces } =
props;
const enableImportExport = true;
const dispatch = useDispatch();
const theme = useContext(ThemeContext);
@ -642,7 +637,7 @@ export function ApplicationsSection(props: any) {
const onCreateNewApplicationFromTemplate = () => {
AnalyticsUtil.logEvent("TEMPLATE_DROPDOWN_CLICK");
onStartFromTemplateClick();
dispatch(showCreateAppFromTemplatesModal());
};
function NoWorkspaceFound() {
@ -969,7 +964,6 @@ export const ApplictionsMainPage = (props: any) => {
<ApplicationsSection
activeWorkspaceId={activeWorkspaceId}
applications={fetchedApplications}
onStartFromTemplateClick={props.onStartFromTemplateClick}
packages={packagesOfWorkspace}
searchKeyword={searchKeyword}
workflows={workflowsOfWorkspace}
@ -1011,9 +1005,7 @@ export interface ApplicationProps {
isReconnectModalOpen: boolean;
}
export interface ApplicationState {
startFromTemplate: boolean;
}
export interface ApplicationState {}
export class Applications<
Props extends ApplicationProps,
@ -1021,19 +1013,6 @@ export class Applications<
> extends Component<Props, State> {
constructor(props: 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() {
@ -1057,10 +1036,6 @@ export class Applications<
this.props.searchApplications("");
}
handleStartFromTemplate() {
this.setState({ startFromTemplate: true });
}
public render() {
if (this.props.currentApplicationIdForCreateNewApp) {
// FOR NEW USER
@ -1080,16 +1055,11 @@ export class Applications<
return (
<>
<ApplictionsMainPage
onStartFromTemplateClick={this.handleStartFromTemplate.bind(this)}
searchApplications={this.props.searchApplications}
searchKeyword={this.props.searchKeyword}
/>
<CreateNewAppFromTemplatesWrapper
currentWorkspaceId={this.props.currentWorkspaceId}
handleClose={() => {
this.setState({ startFromTemplate: false });
}}
isOpen={this.state.startFromTemplate}
/>
</>
);

View File

@ -30,6 +30,7 @@ const initialState: TemplatesReduxState = {
isOpen: false,
isOpenFromCanvas: false,
},
isCreateAppFromTemplateModalOpen: false,
};
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]: (
state: TemplatesReduxState,
) => {
@ -313,6 +330,7 @@ export interface TemplatesReduxState {
isOpenFromCanvas: boolean;
};
loadingFilters: boolean;
isCreateAppFromTemplateModalOpen: boolean;
}
export default templateReducer;

View File

@ -28,6 +28,7 @@ import { getDefaultPageId } from "@appsmith/sagas/ApplicationSagas";
import { getDefaultPageId as selectDefaultPageId } from "sagas/selectors";
import {
getAllTemplates,
hideCreateAppFromTemplatesModal,
hideTemplatesModal,
setTemplateNotificationSeenAction,
showStarterBuildingBlockDatasourcePrompt,
@ -65,6 +66,7 @@ import { isAirgapped } from "@appsmith/utils/airgapHelpers";
import { STARTER_BUILDING_BLOCKS } from "constants/TemplatesConstants";
import urlBuilder from "@appsmith/entities/URLRedirect/URLAssembly";
import { fetchJSLibraries } from "actions/JSLibraryActions";
import { createAppFromTemplatesModalSelector } from "selectors/templatesSelectors";
const isAirgappedInstance = isAirgapped();
@ -128,6 +130,12 @@ function* importTemplateToWorkspaceSaga(
history.push(pageURL);
}
yield put(getAllTemplates());
const isCreateAppFromTemplateModal: boolean = yield select(
createAppFromTemplatesModalSelector,
);
if (isCreateAppFromTemplateModal) {
yield put(hideCreateAppFromTemplatesModal());
}
}
} catch (error) {
yield put({

View File

@ -225,3 +225,6 @@ export const templatesCountSelector = (state: AppState) =>
export const activeLoadingTemplateId = (state: AppState) =>
state.ui.templates.activeLoadingTemplateId;
export const createAppFromTemplatesModalSelector = (state: AppState) =>
state.ui.templates.isCreateAppFromTemplateModalOpen;