Skip to content

Commit

Permalink
Merge pull request #4505 from kobotoolbox/react-router-6-13
Browse files Browse the repository at this point in the history
Upgrade React Router to 6.14.2 and use upstream usePrompt
  • Loading branch information
bufke authored Jul 24, 2023
2 parents 0999bbf + d2f2f3b commit a8d26d1
Show file tree
Hide file tree
Showing 43 changed files with 1,133 additions and 990 deletions.
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
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.
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
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
File renamed without changes.
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

0 comments on commit a8d26d1

Please sign in to comment.