Hook up import/totals endpoint to Historical Data Import screen (https://github.com/woocommerce/woocommerce-admin/pull/2208)
* Hook up import/totals endpoint to Historical Data Import screen * Remove getImportTotalsError and isGetImportTotalsRequesting selectors which were not used * Remove duplicate style import * Fix RTL displays
This commit is contained in:
parent
7a6c7add9e
commit
a382fd6143
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
import { Component, Fragment } from '@wordpress/element';
|
import { Component } from '@wordpress/element';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,13 +15,8 @@ import { stringifyQuery } from '@woocommerce/navigation';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import HistoricalDataActions from './actions';
|
import { formatParams } from './utils';
|
||||||
import HistoricalDataPeriodSelector from './period-selector';
|
import HistoricalDataLayout from './layout';
|
||||||
import HistoricalDataProgress from './progress';
|
|
||||||
import HistoricalDataStatus from './status';
|
|
||||||
import HistoricalDataSkipCheckbox from './skip-checkbox';
|
|
||||||
import withSelect from 'wc-api/with-select';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class HistoricalData extends Component {
|
class HistoricalData extends Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -78,23 +73,7 @@ class HistoricalData extends Component {
|
||||||
this.setState( {
|
this.setState( {
|
||||||
inProgress: true,
|
inProgress: true,
|
||||||
} );
|
} );
|
||||||
const params = {};
|
const path = '/wc/v4/reports/import' + stringifyQuery( formatParams( period, skipChecked ) );
|
||||||
if ( skipChecked ) {
|
|
||||||
params.skip_existing = true;
|
|
||||||
}
|
|
||||||
if ( period.label !== 'all' ) {
|
|
||||||
if ( period.label === 'custom' ) {
|
|
||||||
const daysDifference = moment().diff(
|
|
||||||
moment( period.date, this.dateFormat ),
|
|
||||||
'days',
|
|
||||||
true
|
|
||||||
);
|
|
||||||
params.days = Math.ceil( daysDifference );
|
|
||||||
} else {
|
|
||||||
params.days = parseInt( period.label, 10 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const path = '/wc/v4/reports/import' + stringifyQuery( params );
|
|
||||||
const errorMessage = __(
|
const errorMessage = __(
|
||||||
'There was a problem rebuilding your report data.',
|
'There was a problem rebuilding your report data.',
|
||||||
'woocommerce-admin'
|
'woocommerce-admin'
|
||||||
|
@ -138,120 +117,24 @@ class HistoricalData extends Component {
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatus() {
|
|
||||||
const { customersProgress, customersTotal, ordersProgress, ordersTotal } = this.props;
|
|
||||||
const { inProgress } = this.state;
|
|
||||||
|
|
||||||
if ( inProgress ) {
|
|
||||||
if ( customersProgress < customersTotal ) {
|
|
||||||
return 'customers';
|
|
||||||
}
|
|
||||||
if ( ordersProgress < ordersTotal ) {
|
|
||||||
return 'orders';
|
|
||||||
}
|
|
||||||
return 'finalizing';
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
( customersTotal > 0 || ordersTotal > 0 ) &&
|
|
||||||
customersProgress === customersTotal &&
|
|
||||||
ordersProgress === ordersTotal
|
|
||||||
) {
|
|
||||||
return 'finished';
|
|
||||||
}
|
|
||||||
return 'ready';
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
|
||||||
customersProgress,
|
|
||||||
customersTotal,
|
|
||||||
hasImportedData,
|
|
||||||
importDate,
|
|
||||||
ordersProgress,
|
|
||||||
ordersTotal,
|
|
||||||
} = this.props;
|
|
||||||
const { inProgress, period, skipChecked } = this.state;
|
const { inProgress, period, skipChecked } = this.state;
|
||||||
const hasImportedAllData =
|
|
||||||
! inProgress &&
|
|
||||||
hasImportedData &&
|
|
||||||
customersProgress === customersTotal &&
|
|
||||||
ordersProgress === ordersTotal;
|
|
||||||
// @todo When the import status endpoint is hooked up,
|
|
||||||
// this bool should be removed and assume it's true.
|
|
||||||
const showImportStatus = false;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<HistoricalDataLayout
|
||||||
<div className="woocommerce-setting">
|
dateFormat={ this.dateFormat }
|
||||||
<div className="woocommerce-setting__label" id="import-historical-data-label">
|
inProgress={ inProgress }
|
||||||
{ __( 'Import Historical Data:', 'woocommerce-admin' ) }
|
onPeriodChange={ this.onPeriodChange }
|
||||||
</div>
|
onDateChange={ this.onDateChange }
|
||||||
<div className="woocommerce-setting__input">
|
onSkipChange={ this.onSkipChange }
|
||||||
<span className="woocommerce-setting__help">
|
onDeletePreviousData={ this.onDeletePreviousData }
|
||||||
{ __(
|
onStartImport={ this.onStartImport }
|
||||||
'This tool populates historical analytics data by processing customers ' +
|
onStopImport={ this.onStopImport }
|
||||||
'and orders created prior to activating WooCommerce Admin.',
|
period={ period }
|
||||||
'woocommerce-admin'
|
skipChecked={ skipChecked }
|
||||||
) }
|
/>
|
||||||
</span>
|
|
||||||
{ ! hasImportedAllData && (
|
|
||||||
<Fragment>
|
|
||||||
<HistoricalDataPeriodSelector
|
|
||||||
dateFormat={ this.dateFormat }
|
|
||||||
disabled={ inProgress }
|
|
||||||
onPeriodChange={ this.onPeriodChange }
|
|
||||||
onDateChange={ this.onDateChange }
|
|
||||||
value={ period }
|
|
||||||
/>
|
|
||||||
<HistoricalDataSkipCheckbox
|
|
||||||
disabled={ inProgress }
|
|
||||||
checked={ skipChecked }
|
|
||||||
onChange={ this.onSkipChange }
|
|
||||||
/>
|
|
||||||
{ showImportStatus && (
|
|
||||||
<Fragment>
|
|
||||||
<HistoricalDataProgress
|
|
||||||
label={ __( 'Registered Customers', 'woocommerce-admin' ) }
|
|
||||||
progress={ customersProgress }
|
|
||||||
total={ customersTotal }
|
|
||||||
/>
|
|
||||||
<HistoricalDataProgress
|
|
||||||
label={ __( 'Orders', 'woocommerce-admin' ) }
|
|
||||||
progress={ ordersProgress }
|
|
||||||
total={ ordersTotal }
|
|
||||||
/>
|
|
||||||
</Fragment>
|
|
||||||
) }
|
|
||||||
</Fragment>
|
|
||||||
) }
|
|
||||||
{ showImportStatus && (
|
|
||||||
<HistoricalDataStatus importDate={ importDate } status={ this.getStatus() } />
|
|
||||||
) }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<HistoricalDataActions
|
|
||||||
customersProgress={ customersProgress }
|
|
||||||
customersTotal={ customersTotal }
|
|
||||||
hasImportedData={ hasImportedData }
|
|
||||||
inProgress={ inProgress }
|
|
||||||
onDeletePreviousData={ this.onDeletePreviousData }
|
|
||||||
onStartImport={ this.onStartImport }
|
|
||||||
onStopImport={ this.onStopImport }
|
|
||||||
ordersProgress={ ordersProgress }
|
|
||||||
ordersTotal={ ordersTotal }
|
|
||||||
/>
|
|
||||||
</Fragment>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withSelect( () => {
|
export default HistoricalData;
|
||||||
return {
|
|
||||||
customersProgress: 0,
|
|
||||||
customersTotal: 0,
|
|
||||||
hasImportedData: false,
|
|
||||||
importDate: '2019-04-01',
|
|
||||||
ordersProgress: 0,
|
|
||||||
ordersTotal: 0,
|
|
||||||
};
|
|
||||||
} )( HistoricalData );
|
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
/** @format */
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { Component, Fragment } from '@wordpress/element';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { formatParams } from './utils';
|
||||||
|
import HistoricalDataActions from './actions';
|
||||||
|
import HistoricalDataPeriodSelector from './period-selector';
|
||||||
|
import HistoricalDataProgress from './progress';
|
||||||
|
import HistoricalDataStatus from './status';
|
||||||
|
import HistoricalDataSkipCheckbox from './skip-checkbox';
|
||||||
|
import withSelect from 'wc-api/with-select';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
class HistoricalDataLayout extends Component {
|
||||||
|
getStatus() {
|
||||||
|
const {
|
||||||
|
customersProgress,
|
||||||
|
customersTotal,
|
||||||
|
inProgress,
|
||||||
|
ordersProgress,
|
||||||
|
ordersTotal,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
if ( inProgress ) {
|
||||||
|
if ( customersProgress < customersTotal ) {
|
||||||
|
return 'customers';
|
||||||
|
}
|
||||||
|
if ( ordersProgress < ordersTotal ) {
|
||||||
|
return 'orders';
|
||||||
|
}
|
||||||
|
return 'finalizing';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
( customersTotal > 0 || ordersTotal > 0 ) &&
|
||||||
|
customersProgress === customersTotal &&
|
||||||
|
ordersProgress === ordersTotal
|
||||||
|
) {
|
||||||
|
return 'finished';
|
||||||
|
}
|
||||||
|
return 'ready';
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
customersProgress,
|
||||||
|
customersTotal,
|
||||||
|
dateFormat,
|
||||||
|
hasImportedData,
|
||||||
|
importDate,
|
||||||
|
inProgress,
|
||||||
|
onPeriodChange,
|
||||||
|
onDateChange,
|
||||||
|
onSkipChange,
|
||||||
|
onDeletePreviousData,
|
||||||
|
onStartImport,
|
||||||
|
onStopImport,
|
||||||
|
ordersProgress,
|
||||||
|
ordersTotal,
|
||||||
|
period,
|
||||||
|
skipChecked,
|
||||||
|
} = this.props;
|
||||||
|
const hasImportedAllData =
|
||||||
|
! inProgress &&
|
||||||
|
hasImportedData &&
|
||||||
|
customersProgress === customersTotal &&
|
||||||
|
ordersProgress === ordersTotal;
|
||||||
|
// @todo When the import status endpoint is hooked up,
|
||||||
|
// this bool should be removed and assume it's true.
|
||||||
|
const showImportStatus = false;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<div className="woocommerce-setting">
|
||||||
|
<div className="woocommerce-setting__label" id="import-historical-data-label">
|
||||||
|
{ __( 'Import Historical Data:', 'woocommerce-admin' ) }
|
||||||
|
</div>
|
||||||
|
<div className="woocommerce-setting__input">
|
||||||
|
<span className="woocommerce-setting__help">
|
||||||
|
{ __(
|
||||||
|
'This tool populates historical analytics data by processing customers ' +
|
||||||
|
'and orders created prior to activating WooCommerce Admin.',
|
||||||
|
'woocommerce-admin'
|
||||||
|
) }
|
||||||
|
</span>
|
||||||
|
{ ! hasImportedAllData && (
|
||||||
|
<Fragment>
|
||||||
|
<HistoricalDataPeriodSelector
|
||||||
|
dateFormat={ dateFormat }
|
||||||
|
disabled={ inProgress }
|
||||||
|
onPeriodChange={ onPeriodChange }
|
||||||
|
onDateChange={ onDateChange }
|
||||||
|
value={ period }
|
||||||
|
/>
|
||||||
|
<HistoricalDataSkipCheckbox
|
||||||
|
disabled={ inProgress }
|
||||||
|
checked={ skipChecked }
|
||||||
|
onChange={ onSkipChange }
|
||||||
|
/>
|
||||||
|
{ showImportStatus && (
|
||||||
|
<Fragment>
|
||||||
|
<HistoricalDataProgress
|
||||||
|
label={ __( 'Registered Customers', 'woocommerce-admin' ) }
|
||||||
|
progress={ customersProgress }
|
||||||
|
total={ customersTotal }
|
||||||
|
/>
|
||||||
|
<HistoricalDataProgress
|
||||||
|
label={ __( 'Orders', 'woocommerce-admin' ) }
|
||||||
|
progress={ ordersProgress }
|
||||||
|
total={ ordersTotal }
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
) }
|
||||||
|
</Fragment>
|
||||||
|
) }
|
||||||
|
{ showImportStatus && (
|
||||||
|
<HistoricalDataStatus importDate={ importDate } status={ this.getStatus() } />
|
||||||
|
) }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<HistoricalDataActions
|
||||||
|
customersProgress={ customersProgress }
|
||||||
|
customersTotal={ customersTotal }
|
||||||
|
hasImportedData={ hasImportedData }
|
||||||
|
inProgress={ inProgress }
|
||||||
|
onDeletePreviousData={ onDeletePreviousData }
|
||||||
|
onStartImport={ onStartImport }
|
||||||
|
onStopImport={ onStopImport }
|
||||||
|
ordersProgress={ ordersProgress }
|
||||||
|
ordersTotal={ ordersTotal }
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withSelect( ( select, props ) => {
|
||||||
|
const { getImportTotals } = select( 'wc-api' );
|
||||||
|
const { period, skipChecked } = props;
|
||||||
|
|
||||||
|
const { customers: customersTotal, orders: ordersTotal } = getImportTotals(
|
||||||
|
formatParams( period, skipChecked )
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
customersProgress: 0,
|
||||||
|
customersTotal,
|
||||||
|
hasImportedData: false,
|
||||||
|
importDate: '2019-04-01',
|
||||||
|
ordersProgress: 0,
|
||||||
|
ordersTotal,
|
||||||
|
};
|
||||||
|
} )( HistoricalDataLayout );
|
|
@ -3,20 +3,29 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __, sprintf } from '@wordpress/i18n';
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
|
import { isNil } from 'lodash';
|
||||||
|
|
||||||
function HistoricalDataProgress( { label, progress, total } ) {
|
function HistoricalDataProgress( { label, progress, total } ) {
|
||||||
|
const labelText = sprintf( __( 'Imported %(label)s', 'woocommerce-admin' ), {
|
||||||
|
label,
|
||||||
|
} );
|
||||||
|
|
||||||
|
const labelCounters =
|
||||||
|
! isNil( progress ) && ! isNil( total )
|
||||||
|
? sprintf( __( '%(progress)s of %(total)s', 'woocommerce-admin' ), {
|
||||||
|
progress,
|
||||||
|
total,
|
||||||
|
} )
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="woocommerce-settings-historical-data__progress">
|
<div className="woocommerce-settings-historical-data__progress">
|
||||||
<span className="woocommerce-settings-historical-data__progress-label">
|
<span className="woocommerce-settings-historical-data__progress-label">{ labelText }</span>
|
||||||
{ sprintf( __( 'Imported %(label)s', 'woocommerce-admin' ), {
|
{ labelCounters && (
|
||||||
label,
|
<span className="woocommerce-settings-historical-data__progress-label">
|
||||||
} ) +
|
{ labelCounters }
|
||||||
' ' +
|
</span>
|
||||||
sprintf( __( '%(progress)s of %(total)s', 'woocommerce-admin' ), {
|
) }
|
||||||
progress,
|
|
||||||
total,
|
|
||||||
} ) }
|
|
||||||
</span>
|
|
||||||
<progress
|
<progress
|
||||||
className="woocommerce-settings-historical-data__progress-bar"
|
className="woocommerce-settings-historical-data__progress-bar"
|
||||||
max={ total }
|
max={ total }
|
||||||
|
|
|
@ -50,10 +50,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-settings-historical-data__progress-label {
|
.woocommerce-settings-historical-data__progress-label {
|
||||||
display: block;
|
display: inline-block;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-bottom: $gap-small;
|
margin-bottom: $gap-small;
|
||||||
margin-top: $gap-large;
|
margin-top: $gap-large;
|
||||||
|
|
||||||
|
& + & {
|
||||||
|
margin-left: 0.25em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-settings-historical-data__progress-bar {
|
.woocommerce-settings-historical-data__progress-bar {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/** @format */
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
export const formatParams = ( period, skipChecked ) => {
|
||||||
|
const params = {};
|
||||||
|
if ( skipChecked ) {
|
||||||
|
params.skip_existing = true;
|
||||||
|
}
|
||||||
|
if ( period.label !== 'all' ) {
|
||||||
|
if ( period.label === 'custom' ) {
|
||||||
|
const daysDifference = moment().diff( moment( period.date, this.dateFormat ), 'days', true );
|
||||||
|
params.days = Math.ceil( daysDifference );
|
||||||
|
} else {
|
||||||
|
params.days = parseInt( period.label, 10 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
|
@ -0,0 +1,11 @@
|
||||||
|
/** @format */
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import operations from './operations';
|
||||||
|
import selectors from './selectors';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
operations,
|
||||||
|
selectors,
|
||||||
|
};
|
|
@ -0,0 +1,43 @@
|
||||||
|
/** @format */
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WooCommerce dependencies
|
||||||
|
*/
|
||||||
|
import { stringifyQuery } from '@woocommerce/navigation';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { isResourcePrefix, getResourceIdentifier } from '../utils';
|
||||||
|
import { NAMESPACE } from '../constants';
|
||||||
|
|
||||||
|
function read( resourceNames, fetch = apiFetch ) {
|
||||||
|
const filteredNames = resourceNames.filter( name => isResourcePrefix( name, 'import-totals' ) );
|
||||||
|
|
||||||
|
return filteredNames.map( async resourceName => {
|
||||||
|
const query = getResourceIdentifier( resourceName );
|
||||||
|
const fetchArgs = {
|
||||||
|
parse: false,
|
||||||
|
path: NAMESPACE + '/reports/import/totals' + stringifyQuery( query ),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch( fetchArgs );
|
||||||
|
const totals = await response.json();
|
||||||
|
|
||||||
|
return {
|
||||||
|
[ resourceName ]: totals,
|
||||||
|
};
|
||||||
|
} catch ( error ) {
|
||||||
|
return { [ resourceName ]: { error } };
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
read,
|
||||||
|
};
|
|
@ -0,0 +1,19 @@
|
||||||
|
/** @format */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { getResourceName } from '../utils';
|
||||||
|
import { DEFAULT_REQUIREMENT } from '../constants';
|
||||||
|
|
||||||
|
const getImportTotals = ( getResource, requireResource ) => (
|
||||||
|
query = {},
|
||||||
|
requirement = DEFAULT_REQUIREMENT
|
||||||
|
) => {
|
||||||
|
const resourceName = getResourceName( 'import-totals', query );
|
||||||
|
return requireResource( requirement, resourceName ) || { customers: null, orders: null };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getImportTotals,
|
||||||
|
};
|
|
@ -4,6 +4,7 @@
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import items from './items';
|
import items from './items';
|
||||||
|
import imports from './imports';
|
||||||
import notes from './notes';
|
import notes from './notes';
|
||||||
import reportItems from './reports/items';
|
import reportItems from './reports/items';
|
||||||
import reportStats from './reports/stats';
|
import reportStats from './reports/stats';
|
||||||
|
@ -21,6 +22,7 @@ function createWcApiSpec() {
|
||||||
...user.mutations,
|
...user.mutations,
|
||||||
},
|
},
|
||||||
selectors: {
|
selectors: {
|
||||||
|
...imports.selectors,
|
||||||
...items.selectors,
|
...items.selectors,
|
||||||
...notes.selectors,
|
...notes.selectors,
|
||||||
...reportItems.selectors,
|
...reportItems.selectors,
|
||||||
|
@ -32,6 +34,7 @@ function createWcApiSpec() {
|
||||||
operations: {
|
operations: {
|
||||||
read( resourceNames ) {
|
read( resourceNames ) {
|
||||||
return [
|
return [
|
||||||
|
...imports.operations.read( resourceNames ),
|
||||||
...items.operations.read( resourceNames ),
|
...items.operations.read( resourceNames ),
|
||||||
...notes.operations.read( resourceNames ),
|
...notes.operations.read( resourceNames ),
|
||||||
...reportItems.operations.read( resourceNames ),
|
...reportItems.operations.read( resourceNames ),
|
||||||
|
@ -43,6 +46,7 @@ function createWcApiSpec() {
|
||||||
},
|
},
|
||||||
update( resourceNames, data ) {
|
update( resourceNames, data ) {
|
||||||
return [
|
return [
|
||||||
|
...imports.operations.update( resourceNames, data ),
|
||||||
...items.operations.update( resourceNames, data ),
|
...items.operations.update( resourceNames, data ),
|
||||||
...notes.operations.update( resourceNames, data ),
|
...notes.operations.update( resourceNames, data ),
|
||||||
...settings.operations.update( resourceNames, data ),
|
...settings.operations.update( resourceNames, data ),
|
||||||
|
|
Loading…
Reference in New Issue