Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade React Router to 6.14.2 and use upstream usePrompt #4505

Merged
merged 18 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
c41f766
Upgrade to react router 6.13 and use upstream usePrompt
bufke Jun 20, 2023
1790aaa
Add better types for react router legacy utils.
bufke Jun 22, 2023
47cd995
Merge from beta and resolve package-lock.json conflicts, by…
p2edwards Jul 5, 2023
ccbae1b
Merge branch 'beta' into react-router-6-13
p2edwards Jul 11, 2023
bd1015f
Change `router?.navigate(…)` to `router!.navigate(…)`
p2edwards Jul 11, 2023
5bd385b
Pin exact version of react-router-dom (to 6.14.1)
p2edwards Jul 12, 2023
0057e0e
Fix a crash on data downloads and a typo in an old route check
p2edwards Jul 17, 2023
53a7d27
Fix language selector focus outline and click height
p2edwards Jul 20, 2023
5195f7c
Remove /forms/:uid/settings/kobocat
p2edwards Jul 21, 2023
be3a9b6
(auto/format) Apply automated eslint and prettier to map.es6
p2edwards Jul 21, 2023
01b00c0
(mark auto/format commit in .git-blame-ignore-revs)
p2edwards Jul 21, 2023
16f242b
Apply manual ESLint fixes to map.es6
p2edwards Jul 21, 2023
bcdbaf0
Fix a map screen crash due to translations not being an array
p2edwards Jul 21, 2023
019e386
Merge branch 'beta' into react-router-6-13
p2edwards Jul 21, 2023
9cacb3f
Retain the FORM_RESET route for now (/forms/:uid/reset) #3925
p2edwards Jul 21, 2023
b2f6160
Update React Router from 6.14.1 to 6.14.2 (patch)
p2edwards Jul 21, 2023
968da59
Fix a problem where error traces were shown instead of fallback routes
p2edwards Jul 21, 2023
d2f2f3b
Use "react-router-dom": "~6.14.2", unpinning the patch version.
bufke Jul 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# .git-blame-ignore-revs

# Applied automated eslint autofixes and prettier to map.es6
be3a9b6041e451b02c671220be50b5ca33cae1a8
bufke marked this conversation as resolved.
Show resolved Hide resolved
10 changes: 5 additions & 5 deletions jsapp/js/account/accountSettingsRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, {useEffect, useState} from 'react';
import {observer} from 'mobx-react';
import {unstable_usePrompt as usePrompt} from 'react-router-dom';
import bem, {makeBem} from 'js/bem';
import {usePrompt} from 'js/router/promptBlocker';
import sessionStore from 'js/stores/session';
import './accountSettings.scss';
import Checkbox from '../components/common/checkbox';
Expand Down Expand Up @@ -134,10 +134,10 @@ const AccountSettings = observer(() => {
});
}
}, [sessionStore.isPending]);
usePrompt(
t('You have unsaved changes. Leave settings without saving?'),
!form.isPristine
);
usePrompt({
when: !form.isPristine,
message: t('You have unsaved changes. Leave settings without saving?'),
});
const updateProfile = () => {
// To patch correctly with recent changes to the backend,
// ensure that we send empty strings if the field is left blank.
Expand Down
44 changes: 26 additions & 18 deletions jsapp/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import DocumentTitle from 'react-document-title';
import { Outlet } from "react-router-dom";
import {Outlet} from 'react-router-dom';
import reactMixin from 'react-mixin';
import Reflux from 'reflux';
import {stores} from 'js/stores';
Expand All @@ -20,9 +20,8 @@ import PermValidator from 'js/components/permissions/permValidator';
import {assign} from 'utils';
import BigModal from 'js/components/bigModal/bigModal';
import {Toaster} from 'react-hot-toast';
import { withRouter, routerGetAssetId } from './router/legacy';
import { history } from "./router/historyRouter";

import {withRouter, routerGetAssetId, router} from './router/legacy';
import {Tracking} from './router/useTracking';

class App extends React.Component {
constructor(props) {
Expand All @@ -33,7 +32,7 @@ class App extends React.Component {
}

componentDidMount() {
history.listen(this.onRouteChange.bind(this));
router.subscribe(this.onRouteChange.bind(this));
}

onRouteChange() {
Expand Down Expand Up @@ -66,33 +65,42 @@ class App extends React.Component {
};

if (typeof this.state.pageState.modal === 'object') {
pageWrapperModifiers[`is-modal-${this.state.pageState.modal.type}`] = true;
pageWrapperModifiers[
`is-modal-${this.state.pageState.modal.type}`
] = true;
}

return (
<DocumentTitle title='KoboToolbox'>
<React.Fragment>
<PermValidator/>
<div className='header-stretch-bg'/>
<bem.PageWrapper m={pageWrapperModifiers} className='mdl-layout mdl-layout--fixed-header'>
{ this.state.pageState.modal &&
<Tracking />
<PermValidator />
<div className='header-stretch-bg' />
<bem.PageWrapper
m={pageWrapperModifiers}
className='mdl-layout mdl-layout--fixed-header'
>
{this.state.pageState.modal && (
<BigModal params={this.state.pageState.modal} />
}
)}

{ !this.isFormBuilder() &&
{!this.isFormBuilder() && (
<React.Fragment>
<MainHeader assetid={assetid}/>
<Drawer/>
<MainHeader assetid={assetid} />
<Drawer />
</React.Fragment>
}
)}

<bem.PageWrapper__content className='mdl-layout__content' m={pageWrapperContentModifiers}>
{ !this.isFormBuilder() &&
<bem.PageWrapper__content
className='mdl-layout__content'
m={pageWrapperContentModifiers}
>
{!this.isFormBuilder() && (
<React.Fragment>
<FormViewTabs type={'top'} show={this.isFormSingle()} />
<FormViewTabs type={'side'} show={this.isFormSingle()} />
</React.Fragment>
}
)}
<Outlet />
</bem.PageWrapper__content>
</bem.PageWrapper>
Expand Down
7 changes: 2 additions & 5 deletions jsapp/js/components/drawer.es6
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import {ROUTES} from 'js/router/routerConstants';
import {assign} from 'utils';
import SidebarFormsList from '../lists/sidebarForms';
import envStore from 'js/envStore';
import {history} from 'js/router/historyRouter';
import { routerIsActive, withRouter } from '../router/legacy';
import { router, routerIsActive, withRouter } from '../router/legacy';

const AccountSidebar = lazy(() => import("js/account/accountSidebar"));

Expand Down Expand Up @@ -51,9 +50,7 @@ const FormSidebar = observer(class FormSidebar extends Reflux.Component {
autoBind(this);
}
componentDidMount() {
this.unlisteners.push(
history.listen(this.onRouteChange.bind(this))
);
router.subscribe(this.onRouteChange.bind(this));
}
componentWillUnmount() {
this.unlisteners.forEach((clb) => {clb();});
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,6 @@ export class FormSubScreens extends React.Component {
hookUid={this.props.params.hookUid}
/>
);
case ROUTES.FORM_KOBOCAT.replace(':uid', this.state.uid):
iframeUrl = deployment__identifier + '/form_settings';
break;
case ROUTES.FORM_RESET.replace(':uid', this.state.uid):
return this.renderReset();
}
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions jsapp/js/components/formViewTabs.es6
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class FormViewTabs extends Reflux.Component {

triggerRefresh(evt) {
if ($(evt.target).hasClass('active')) {
// ROUTES.FORM_RESET
bufke marked this conversation as resolved.
Show resolved Hide resolved
this.props.router.navigate(`/forms/${this.state.asset.uid}/reset`);

var path = evt.target.getAttribute('data-path');
Expand Down
File renamed without changes.
13 changes: 8 additions & 5 deletions jsapp/js/components/header/searchBoxStore.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import Reflux from 'reflux';
import type {RouterState} from '@remix-run/router';
import {
getCurrentPath,
isMyLibraryRoute,
isPublicCollectionsRoute,
} from 'js/router/routerUtils';
import {history} from 'js/router/historyRouter';
import {router} from 'js/router/legacy';

const DEFAULT_SEARCH_PHRASE = '';

type SearchBoxContextName = 'MY_LIBRARY' | 'PUBLIC_COLLECTIONS';

export const SEARCH_CONTEXTS: {
[name in SearchBoxContextName]: SearchBoxContextName
[name in SearchBoxContextName]: SearchBoxContextName;
} = {
MY_LIBRARY: 'MY_LIBRARY',
PUBLIC_COLLECTIONS: 'PUBLIC_COLLECTIONS',
Expand All @@ -30,13 +31,15 @@ class SearchBoxStore extends Reflux.Store {
};

init() {
history.listen(this.onRouteChange.bind(this));
setTimeout(() => router!.subscribe(this.onRouteChange.bind(this)));
this.resetContext();
}

// manages clearing search when switching main routes
onRouteChange(data: any) {
if (this.previousPath.split('/')[1] !== data.location.pathname.split('/')[1]) {
onRouteChange(data: RouterState) {
if (
this.previousPath.split('/')[1] !== data.location.pathname.split('/')[1]
) {
this.clear();
}
this.previousPath = data.location.pathname;
Expand Down
4 changes: 4 additions & 0 deletions jsapp/js/components/languages/languageSelector.scss
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
padding: 0 sizes.$x40;
margin: 0;
background: transparent;
line-height: sizes.$x40;
}

.language-selector__selected-language-label {
Expand All @@ -115,6 +116,9 @@
opacity: 1;
color: colors.$kobo-gray-55;
}
&:focus {
outline: none;
}
}

.language-selector__clear-selected-language,
Expand Down
112 changes: 71 additions & 41 deletions jsapp/js/components/library/myLibraryStore.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import debounce from 'lodash.debounce';
import Reflux from 'reflux';
import type {Location} from 'history';
import searchBoxStore from '../header/searchBoxStore';
import assetUtils from 'js/assetUtils';
import {
getCurrentPath,
isAnyLibraryRoute,
} from 'js/router/routerUtils';
import {getCurrentPath, isAnyLibraryRoute} from 'js/router/routerUtils';
import {actions} from 'js/actions';
import {
ORDER_DIRECTIONS,
ASSETS_TABLE_COLUMNS,
} from 'js/components/assetsTable/assetsTableConstants';
import type {OrderDirection} from 'js/projects/projectViews/constants';
import type {RouterState} from '@remix-run/router';
import {ROUTES} from 'js/router/routerConstants';
import { history } from "js/router/historyRouter";
import {router} from 'js/router/legacy';
import type {
AssetResponse,
AssetsResponse,
Expand Down Expand Up @@ -76,34 +73,66 @@ class MyLibraryStore extends Reflux.Store {

this.setDefaultColumns();

history.listen(this.onRouteChange.bind(this));
setTimeout(() => router!.subscribe(this.onRouteChange.bind(this)));
searchBoxStore.listen(this.searchBoxStoreChanged, this);
actions.library.moveToCollection.completed.listen(this.onMoveToCollectionCompleted.bind(this));
actions.library.subscribeToCollection.completed.listen(this.fetchData.bind(this, true));
actions.library.unsubscribeFromCollection.completed.listen(this.fetchData.bind(this, true));
actions.library.searchMyLibraryAssets.started.listen(this.onSearchStarted.bind(this));
actions.library.searchMyLibraryAssets.completed.listen(this.onSearchCompleted.bind(this));
actions.library.searchMyLibraryAssets.failed.listen(this.onSearchFailed.bind(this));
actions.library.searchMyLibraryMetadata.completed.listen(this.onSearchMetadataCompleted.bind(this));
actions.resources.loadAsset.completed.listen(this.onAssetChanged.bind(this));
actions.resources.updateAsset.completed.listen(this.onAssetChanged.bind(this));
actions.resources.cloneAsset.completed.listen(this.onAssetCreated.bind(this));
actions.resources.createResource.completed.listen(this.onAssetCreated.bind(this));
actions.resources.deleteAsset.completed.listen(this.onDeleteAssetCompleted.bind(this));
actions.library.moveToCollection.completed.listen(
this.onMoveToCollectionCompleted.bind(this)
);
actions.library.subscribeToCollection.completed.listen(
this.fetchData.bind(this, true)
);
actions.library.unsubscribeFromCollection.completed.listen(
this.fetchData.bind(this, true)
);
actions.library.searchMyLibraryAssets.started.listen(
this.onSearchStarted.bind(this)
);
actions.library.searchMyLibraryAssets.completed.listen(
this.onSearchCompleted.bind(this)
);
actions.library.searchMyLibraryAssets.failed.listen(
this.onSearchFailed.bind(this)
);
actions.library.searchMyLibraryMetadata.completed.listen(
this.onSearchMetadataCompleted.bind(this)
);
actions.resources.loadAsset.completed.listen(
this.onAssetChanged.bind(this)
);
actions.resources.updateAsset.completed.listen(
this.onAssetChanged.bind(this)
);
actions.resources.cloneAsset.completed.listen(
this.onAssetCreated.bind(this)
);
actions.resources.createResource.completed.listen(
this.onAssetCreated.bind(this)
);
actions.resources.deleteAsset.completed.listen(
this.onDeleteAssetCompleted.bind(this)
);
// TODO Improve reaction to uploads being finished after task is done:
// https://github.com/kobotoolbox/kpi/issues/476
actions.resources.createImport.completed.listen(this.fetchDataDebounced.bind(this, true));
actions.resources.createImport.completed.listen(
this.fetchDataDebounced.bind(this, true)
);

// startup store after config is ready
actions.permissions.getConfig.completed.listen(this.startupStore.bind(this));
actions.permissions.getConfig.completed.listen(
this.startupStore.bind(this)
);
}

/**
* Only makes a call to BE when loaded app on a library route
* otherwise wait until route changes to a library (see `onRouteChange`)
*/
startupStore() {
if (!this.isInitialised && isAnyLibraryRoute() && !this.data.isFetchingData) {
if (
!this.isInitialised &&
isAnyLibraryRoute() &&
!this.data.isFetchingData
) {
this.fetchData(true);
}
}
Expand Down Expand Up @@ -154,23 +183,26 @@ class MyLibraryStore extends Reflux.Store {
params.metadata = needsMetadata;

const orderColumn = ASSETS_TABLE_COLUMNS[this.data.orderColumnId];
const direction = this.data.orderValue === ORDER_DIRECTIONS.ascending ? '' : '-';
const direction =
this.data.orderValue === ORDER_DIRECTIONS.ascending ? '' : '-';
params.ordering = `${direction}${orderColumn.orderBy}`;

actions.library.searchMyLibraryAssets(params);
}

onRouteChange(data: any) {
if (!this.isInitialised && isAnyLibraryRoute() && !this.data.isFetchingData) {
onRouteChange(data: RouterState) {
if (
!this.isInitialised &&
isAnyLibraryRoute() &&
!this.data.isFetchingData
) {
this.fetchData(true);
} else if (
(
// coming from outside of library
this.previousPath.split('/')[1] !== 'library' ||
// coming from outside of library
(this.previousPath.split('/')[1] !== 'library' ||
// public-collections is a special case that is kinda in library, but
// actually outside of it
this.previousPath.startsWith(ROUTES.PUBLIC_COLLECTIONS)
) &&
this.previousPath.startsWith(ROUTES.PUBLIC_COLLECTIONS)) &&
isAnyLibraryRoute()
) {
// refresh data when navigating into library from other place
Expand Down Expand Up @@ -210,7 +242,10 @@ class MyLibraryStore extends Reflux.Store {
}
this.data.totalSearchAssets = response.count;
// update total count for the first time and the ones that will get a full count
if (this.data.totalUserAssets === null || searchBoxStore.getSearchPhrase() === '') {
if (
this.data.totalUserAssets === null ||
searchBoxStore.getSearchPhrase() === ''
) {
this.data.totalUserAssets = this.data.totalSearchAssets;
}
this.data.isFetchingData = false;
Expand Down Expand Up @@ -253,12 +288,10 @@ class MyLibraryStore extends Reflux.Store {
const loopAsset = this.data.assets[i];
if (
loopAsset.uid === asset.uid &&
(
// if the changed asset didn't change (e.g. was just loaded)
// let's not cause it to fetchMetadata
loopAsset.date_modified !== asset.date_modified ||
loopAsset.version_id !== asset.version_id
)
// if the changed asset didn't change (e.g. was just loaded)
// let's not cause it to fetchMetadata
(loopAsset.date_modified !== asset.date_modified ||
loopAsset.version_id !== asset.version_id)
) {
this.data.assets[i] = asset;
wasUpdated = true;
Expand All @@ -273,10 +306,7 @@ class MyLibraryStore extends Reflux.Store {
}

onAssetCreated(asset: AssetResponse) {
if (
assetUtils.isLibraryAsset(asset.asset_type) &&
asset.parent === null
) {
if (assetUtils.isLibraryAsset(asset.asset_type) && asset.parent === null) {
if (this.data.totalUserAssets !== null) {
this.data.totalUserAssets++;
}
Expand Down
Loading