Skip to content

Commit 9386e19

Browse files
committed
feat: query params during project creation forms are treated as different projects
- if query params are changed: ask user if he want to continue editing previous form and start from scratch - if user want to start from scratch keep new query params and clear previous ones - if user want to continue where left, also have restore previous query params
1 parent 312da78 commit 9386e19

File tree

3 files changed

+61
-8
lines changed

3 files changed

+61
-8
lines changed

src/config/constants.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,13 @@ export const MAINTENANCE_MODE = process.env.MAINTENANCE_MODE
701701

702702
export const LS_INCOMPLETE_PROJECT = 'incompleteProject'
703703
export const LS_INCOMPLETE_WIZARD = 'incompleteWizard'
704+
export const LS_INCOMPLETE_PROJECT_QUERY_PARAMS = 'incompleteProjectQueryParams'
704705

706+
/**
707+
* These query params are special during project creating wizard.
708+
* They have some special code to handle them.
709+
*/
710+
export const SPECIAL_QUERY_PARAMS = ['returnUrl', 'refCode']
705711

706712
export const PROJECTS_API_URL = process.env.PROJECTS_API_URL || TC_API_URL
707713
export const CONNECT_MESSAGE_API_URL = process.env.CONNECT_MESSAGE_API_URL || TC_API_URL

src/projects/create/components/ProjectWizard.jsx

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ import ProjectSubmitted from './ProjectSubmitted'
1414

1515
import update from 'react-addons-update'
1616
import {
17-
LS_INCOMPLETE_PROJECT, PROJECT_REF_CODE_MAX_LENGTH, LS_INCOMPLETE_WIZARD, PROJECT_ATTACHMENTS_FOLDER
17+
LS_INCOMPLETE_PROJECT,
18+
LS_INCOMPLETE_WIZARD,
19+
LS_INCOMPLETE_PROJECT_QUERY_PARAMS,
20+
SPECIAL_QUERY_PARAMS,
21+
PROJECT_REF_CODE_MAX_LENGTH,
22+
PROJECT_ATTACHMENTS_FOLDER,
1823
} from '../../../config/constants'
1924
import {
2025
buildProjectUpdateQueryByQueryParamSelectCondition,
@@ -81,8 +86,20 @@ class ProjectWizard extends Component {
8186
const projectTemplate = getProjectTemplateByAlias(projectTemplates, params.project)
8287

8388
if (projectTemplate) {
84-
// load project details page directly
85-
if (projectTemplate.key === incompleteProjectTemplate.key) {
89+
const incompleteProjectQueryParamsStr = window.localStorage.getItem(LS_INCOMPLETE_PROJECT_QUERY_PARAMS)
90+
const incompleteQueryParams = incompleteProjectQueryParamsStr ? JSON.parse(incompleteProjectQueryParamsStr) : {}
91+
const queryParams = qs.parse(window.location.search)
92+
// find out if the query params are different in the saved incomplete project and now
93+
// if query params are different, then we would treat such form as different and wouldn't
94+
// continue editing, we would propose user to start from scratch or continue with old query params
95+
const isQueryParamsChanged = !_.isEqual(
96+
_.omit(queryParams, SPECIAL_QUERY_PARAMS),
97+
_.omit(incompleteQueryParams, SPECIAL_QUERY_PARAMS)
98+
)
99+
100+
// load incomplete project if the current URL is for the same Project Template
101+
// and query params which could be used to prefill project data are not changed
102+
if (projectTemplate.key === incompleteProjectTemplate.key && !isQueryParamsChanged) {
86103
console.info(`Creating project (restored from local storage) using Project Template (id: "${incompleteProjectTemplate.id}", key: "${incompleteProjectTemplate.key}", alias: "${incompleteProjectTemplate.aliases[0]}").`)
87104
wizardStep = WZ_STEP_FILL_PROJ_DETAILS
88105
updateQuery = {$merge : incompleteProject}
@@ -127,13 +144,18 @@ class ProjectWizard extends Component {
127144
// get `templateId` from update query which has been updated above by calling `this.loadProjectFromURL`
128145
const templateId = _.get(updateQuery, 'templateId.$set')
129146
const projectTemplate = _.find(projectTemplates, { id: templateId })
130-
const queryParams = _.omit(qs.parse(window.location.search), 'refCode')
131-
if (projectTemplate && projectTemplate.scope) {
147+
// during evaluation we do use `SPECIAL_QUERY_PARAMS`, and we don't store special params
148+
const queryParams = _.omit(qs.parse(window.location.search), SPECIAL_QUERY_PARAMS)
149+
// always store query params in local storage
150+
// if later they are changed for incomplete project we would know that probably user open another link and we have to reset project
151+
window.localStorage.setItem(LS_INCOMPLETE_PROJECT_QUERY_PARAMS, JSON.stringify(queryParams))
152+
if (projectTemplate) {
132153
console.info(`Creating project (from scratch) using Project Template (id: "${projectTemplate.id}", key: "${projectTemplate.key}", alias: "${projectTemplate.aliases[0]}").`)
133154
// if we already know project template, and there are some query params,
134155
// then pre-populate project data using `queryParamSelectCondition` from template
135-
if (!_.isEmpty(queryParams)) {
136-
const prefillProjectQuery = buildProjectUpdateQueryByQueryParamSelectCondition(projectTemplate.scope, queryParams)
156+
if (!_.isEmpty(queryParams) && projectTemplate.scope) {
157+
// during evaluation we do use `SPECIAL_QUERY_PARAMS`
158+
const prefillProjectQuery = buildProjectUpdateQueryByQueryParamSelectCondition(projectTemplate.scope, _.omit(queryParams, SPECIAL_QUERY_PARAMS))
137159
projectState = update(projectState, prefillProjectQuery)
138160
dirtyProjectState = update(dirtyProjectState, prefillProjectQuery)
139161
}
@@ -242,6 +264,7 @@ class ProjectWizard extends Component {
242264
if (projectTemplate) {
243265
console.info(`Creating project (confirmed: restored from local storage) using Project Template (id: "${projectTemplate.id}", key: "${projectTemplate.key}", alias: "${projectTemplate.aliases[0]}").`)
244266
}
267+
245268
this.setState({
246269
project: update(this.state.project, { $merge : incompleteProject }),
247270
dirtyProject: update(this.state.dirtyProject, { $merge : incompleteProject }),
@@ -270,12 +293,23 @@ class ProjectWizard extends Component {
270293
const projectTemplateId = _.get(this.state.project, 'templateId')
271294
let wizardStep = WZ_STEP_SELECT_PROJ_TYPE
272295
let project = null
296+
// during evaluation we do use `SPECIAL_QUERY_PARAMS`, and we don't store special params
297+
const queryParams = _.omit(qs.parse(window.location.search), SPECIAL_QUERY_PARAMS)
298+
// always store query params in local storage
299+
// if later they are changed for incomplete project we would know that probably user open another link and we have to reset project
300+
window.localStorage.setItem(LS_INCOMPLETE_PROJECT_QUERY_PARAMS, JSON.stringify(queryParams))
273301
if (projectTemplateId) {
274302
project = { type: projectType, templateId: projectTemplateId, details: {} }
275303
wizardStep = WZ_STEP_FILL_PROJ_DETAILS
276304
const projectTemplate = _.find(projectTemplates, { id: projectTemplateId })
277305
if (projectTemplate) {
278306
console.info(`Creating project (confirmed: from scratch) using Project Template (id: "${projectTemplate.id}", key: "${projectTemplate.key}", alias: "${projectTemplate.aliases[0]}").`)
307+
// if we already know project template, and there are some query params,
308+
// then pre-populate project data using `queryParamSelectCondition` from template
309+
if (!_.isEmpty(queryParams) && projectTemplate.scope) {
310+
const prefillProjectQuery = buildProjectUpdateQueryByQueryParamSelectCondition(projectTemplate.scope, queryParams)
311+
project = update(project, prefillProjectQuery)
312+
}
279313
}
280314
}
281315
const refCode = this.getRefCodeFromURL()

src/projects/create/containers/CreateContainer.jsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import {
2424
CREATE_PROJECT_FAILURE,
2525
LS_INCOMPLETE_PROJECT,
2626
LS_INCOMPLETE_WIZARD,
27+
LS_INCOMPLETE_PROJECT_QUERY_PARAMS,
28+
SPECIAL_QUERY_PARAMS,
2729
PROJECT_STATUS_IN_REVIEW,
2830
ACCOUNTS_APP_REGISTER_URL,
2931
NEW_PROJECT_PATH,
@@ -332,7 +334,18 @@ class CreateContainer extends React.Component {
332334
}
333335

334336
if (typeAlias && templateAlias && wizardStep === ProjectWizard.Steps.WZ_STEP_FILL_PROJ_DETAILS) {
335-
this.props.history.push(NEW_PROJECT_PATH + '/' + templateAlias + window.location.search)
337+
const incompleteProjectQueryParamsStr = window.localStorage.getItem(LS_INCOMPLETE_PROJECT_QUERY_PARAMS)
338+
const incompleteQueryParams = incompleteProjectQueryParamsStr ? JSON.parse(incompleteProjectQueryParamsStr) : {}
339+
const queryParams = qs.parse(window.location.search)
340+
const isQueryParamsChanged = !_.isEqual(
341+
_.omit(queryParams, SPECIAL_QUERY_PARAMS),
342+
_.omit(incompleteQueryParams, SPECIAL_QUERY_PARAMS)
343+
)
344+
// if we are coming to the details step and we see that query params has been changed
345+
// since we left incomplete project, this mean that we chose continue incomplete project
346+
// when we changed URL and started again, so we should restore the query params of incomplete project
347+
const queryParamsToApply = isQueryParamsChanged ? '?' + qs.stringify(incompleteQueryParams) : window.location.search
348+
this.props.history.push(NEW_PROJECT_PATH + '/' + templateAlias + queryParamsToApply)
336349
}
337350

338351
if (typeAlias && templateAlias && wizardStep === ProjectWizard.Steps.WZ_STEP_PROJECT_SUBMITTED) {

0 commit comments

Comments
 (0)