chrone: sperate client and server to different repos.

This commit is contained in:
a.bouhuolia
2021-09-21 17:13:53 +02:00
parent e011b2a82b
commit 18df5530c7
10015 changed files with 17686 additions and 97524 deletions

View File

@@ -0,0 +1,145 @@
import React, { useCallback, useState, useMemo } from 'react';
import {
NavbarGroup,
NavbarDivider,
Button,
Classes,
Intent,
Popover,
Position,
PopoverInteractionKind,
Alignment,
} from '@blueprintjs/core';
import classNames from 'classnames';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { connect } from 'react-redux';
import { If } from 'components';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import Icon from 'components/Icon';
import { useRefreshExchangeRate } from 'hooks/query/exchangeRates';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withResourceDetail from 'containers/Resources/withResourceDetails';
import withExchangeRatesActions from './withExchangeRatesActions';
import { compose } from 'utils';
/**
* Exchange rate actions bar.
*/
function ExchangeRateActionsBar({
// #withDialogActions.
openDialog,
// #withResourceDetail
resourceFields,
//#withExchangeRatesActions
addExchangeRatesTableQueries,
// #ownProps
selectedRows = [],
onDeleteExchangeRate,
onFilterChanged,
onBulkDelete,
}) {
const [filterCount, setFilterCount] = useState(0);
const onClickNewExchangeRate = () => {
openDialog('exchangeRate-form', {});
};
// Exchange rates refresh action.
const { refresh } = useRefreshExchangeRate();
// Handle click a refresh sale estimates
const handleRefreshBtnClick = () => {
refresh();
};
const hasSelectedRows = useMemo(
() => selectedRows.length > 0,
[selectedRows],
);
const handelBulkDelete = useCallback(() => {
onBulkDelete && onBulkDelete(selectedRows.map((r) => r.id));
}, [onBulkDelete, selectedRows]);
return (
<DashboardActionsBar>
<NavbarGroup>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="plus" />}
text={<T id={'new_exchange_rate'} />}
onClick={onClickNewExchangeRate}
/>
<NavbarDivider />
<Popover
minimal={true}
// content={filterDropdown}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
>
<Button
className={classNames(Classes.MINIMAL, 'button--filter')}
text={
filterCount <= 0 ? (
<T id={'filter'} />
) : (
`${filterCount} ${intl.get('filters_applied')}`
)
}
icon={<Icon icon="filter-16" iconSize={16} />}
/>
</Popover>
<If condition={hasSelectedRows}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="trash-16" iconSize={16} />}
text={<T id={'delete'} />}
intent={Intent.DANGER}
onClick={handelBulkDelete}
/>
</If>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="file-import-16" iconSize={16} />}
text={<T id={'import'} />}
/>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="file-export-16" iconSize={16} />}
text={<T id={'export'} />}
/>
</NavbarGroup>
<NavbarGroup align={Alignment.RIGHT}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="refresh-16" iconSize={14} />}
onClick={handleRefreshBtnClick}
/>
</NavbarGroup>
</DashboardActionsBar>
);
}
const mapStateToProps = (state, props) => ({
resourceName: '',
});
const withExchangeRateActionBar = connect(mapStateToProps);
export default compose(
withExchangeRateActionBar,
withDialogActions,
withResourceDetail(({ resourceFields }) => ({
resourceFields,
})),
withExchangeRatesActions,
)(ExchangeRateActionsBar);

View File

@@ -0,0 +1,107 @@
import React, { useCallback } from 'react';
import { DataTable } from 'components';
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
import { useExchangeRatesContext } from './ExchangeRatesProvider';
import { useExchangeRatesTableColumns, ActionMenuList } from './components';
import withExchangeRates from './withExchangeRates';
import withExchangeRatesActions from './withExchangeRatesActions';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withAlertActions from 'containers/Alert/withAlertActions';
import { compose } from 'utils';
/**
* Exchange rates table.
*/
function ExchangeRateTable({
// #ownProps
tableProps,
// #withDialogActions.
openDialog,
// #withAlertActions
openAlert,
// #withExchangeRatesActions
setExchangeRateTableState,
// #withExchangeRates
exchangeRatesTableState,
}) {
const {
isExchangeRatesFetching,
isExchangeRatesLoading,
exchangesRates,
pagination,
} = useExchangeRatesContext();
// Table columns.
const columns = useExchangeRatesTableColumns();
// Handle delete exchange rate.
const handleDeleteExchangeRate = ({ id }) => {
openAlert('exchange-rate-delete', { exchangeRateId: id });
};
// Handle Edit exchange rate.
const handelEditExchangeRate = (exchangeRate) => {
openDialog('exchangeRate-form', {
action: 'edit',
exchangeRate: exchangeRate,
});
};
const handleFetchData = useCallback(
({ pageSize, pageIndex, sortBy }) => {
setExchangeRateTableState({
pageIndex,
pageSize,
sortBy,
});
},
[setExchangeRateTableState],
);
return (
<DataTable
noInitialFetch={true}
columns={columns}
data={exchangesRates}
initialState={exchangeRatesTableState}
loading={isExchangeRatesLoading}
headerLoading={isExchangeRatesLoading}
progressBarLoading={isExchangeRatesFetching}
selectionColumn={true}
expandable={true}
sticky={true}
manualSortBy={true}
onFetchData={handleFetchData}
pagination={true}
manualPagination={true}
pagesCount={pagination.pagesCount}
TableLoadingRenderer={TableSkeletonRows}
TableHeaderSkeletonRenderer={TableSkeletonHeader}
ContextMenu={ActionMenuList}
payload={{
onDeleteExchangeRate: handleDeleteExchangeRate,
onEditExchangeRate: handelEditExchangeRate,
}}
{...tableProps}
/>
);
}
export default compose(
withDialogActions,
withAlertActions,
withExchangeRates(({ exchangeRatesTableState }) => ({
exchangeRatesTableState,
})),
withExchangeRatesActions,
)(ExchangeRateTable);

View File

@@ -0,0 +1,12 @@
import React from 'react';
import ExchangeRateDeleteAlert from 'containers/Alerts/ExchangeRates/ExchangeRateDeleteAlert';
// import ExchangeRateBulkDeleteAlert from 'containers/Alerts/ExchangeRates/ExchangeRateBulkDeleteAlert';
export default function ExchangeRatesAlerts() {
return (
<div>
<ExchangeRateDeleteAlert name={'exchange-rate-delete'} />
</div>
);
}

View File

@@ -0,0 +1,40 @@
import React from 'react';
import { compose } from 'utils';
import { DashboardContentTable, DashboardPageContent } from 'components';
import ExchangeRateTable from './ExchangeRateTable';
import ExchangeRateActionsBar from './ExchangeRateActionsBar';
import { ExchangeRatesProvider } from './ExchangeRatesProvider';
import ExchangeRatesAlerts from './ExchangeRatesAlerts';
import withExchangeRates from './withExchangeRates';
import { transformTableStateToQuery } from 'utils';
/**
* Exchange Rates list.
*/
function ExchangeRatesList({
// #withExchangeRates
exchangeRatesTableState,
}) {
return (
<ExchangeRatesProvider
query={transformTableStateToQuery(exchangeRatesTableState)}
>
<ExchangeRateActionsBar />
<DashboardPageContent>
<DashboardContentTable>
<ExchangeRateTable />
</DashboardContentTable>
</DashboardPageContent>
<ExchangeRatesAlerts />
</ExchangeRatesProvider>
);
}
export default compose(
withExchangeRates(({ exchangeRatesTableState }) => ({
exchangeRatesTableState,
})),
)(ExchangeRatesList);

View File

@@ -0,0 +1,41 @@
import React, { createContext } from 'react';
import { transformTableQueryToParams } from 'utils';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { useExchangeRates } from 'hooks/query';
const ExchangesRatesContext = createContext();
/**
* Exchanges rates list provider.
*/
function ExchangeRatesProvider({ query, ...props }) {
const {
data: { exchangesRates, pagination, filterMeta },
isFetching: isExchangeRatesFetching,
isLoading: isExchangeRatesLoading,
} = useExchangeRates(
{
...transformTableQueryToParams(query),
},
{ keepPreviousData: true },
);
const state = {
isExchangeRatesFetching,
isExchangeRatesLoading,
exchangesRates,
pagination,
};
return (
<DashboardInsider name={'exchange-rate'}>
<ExchangesRatesContext.Provider value={state} {...props} />
</DashboardInsider>
);
}
const useExchangeRatesContext = () => React.useContext(ExchangesRatesContext);
export { ExchangeRatesProvider, useExchangeRatesContext };

View File

@@ -0,0 +1,94 @@
import React, { useMemo } from 'react';
import {
Menu,
Popover,
Button,
Position,
MenuItem,
MenuDivider,
Intent,
} from '@blueprintjs/core';
import intl from 'react-intl-universal';
import { Icon, Money } from 'components';
import moment from 'moment';
import { safeCallback } from 'utils';
/**
* Row actions menu list.
*/
export function ActionMenuList({
row: { original },
payload: { onEditExchangeRate, onDeleteExchangeRate },
}) {
return (
<Menu>
<MenuItem
icon={<Icon icon="pen-18" />}
text={intl.get('edit_exchange_rate')}
onClick={safeCallback(onEditExchangeRate, original)}
/>
<MenuDivider />
<MenuItem
text={intl.get('delete_exchange_rate')}
intent={Intent.DANGER}
onClick={safeCallback(onDeleteExchangeRate, original)}
icon={<Icon icon="trash-16" iconSize={16} />}
/>
</Menu>
);
}
/**
* Table actions cell.
*/
export function TableActionsCell(props) {
return (
<Popover
content={<ActionMenuList {...props} />}
position={Position.RIGHT_TOP}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
);
}
export function useExchangeRatesTableColumns() {
return useMemo(
() => [
{
id: 'date',
Header: intl.get('date'),
accessor: (r) => moment(r.date).format('YYYY MMM DD'),
width: 150,
},
{
id: 'currency_code',
Header: intl.get('currency_code'),
accessor: 'currency_code',
className: 'currency_code',
width: 150,
},
{
id: 'exchange_rate',
Header: intl.get('exchange_rate'),
accessor: (r) => (
<Money amount={r.exchange_rate} currency={r.currency_code} />
),
className: 'exchange_rate',
width: 150,
},
{
id: 'actions',
Header: '',
Cell: TableActionsCell,
className: 'actions',
width: 50,
},
],
[],
);
}

View File

@@ -0,0 +1,8 @@
import { connect } from 'react-redux';
import { getExchangeRateById } from 'store/ExchangeRate/exchange.selector';
const mapStateToProps = (state, props) => ({
exchangeRate: getExchangeRateById(state, props),
});
export default connect(mapStateToProps);

View File

@@ -0,0 +1,15 @@
import { connect } from 'react-redux';
import { getExchangeRatesTableStateFactory } from 'store/ExchangeRate/exchange.selector';
export default (mapState) => {
const getExchangeRatesTableState = getExchangeRatesTableStateFactory();
const mapStateToProps = (state, props) => {
const mapped = {
exchangeRatesTableState: getExchangeRatesTableState(state, props),
};
return mapState ? mapState(mapped, state, props) : mapped;
};
return connect(mapStateToProps);
};

View File

@@ -0,0 +1,9 @@
import { connect } from 'react-redux';
import { setExchangeRateTableState } from 'store/ExchangeRate/exchange.actions';
export const mapDispatchToProps = (dispatch) => ({
setExchangeRateTableState: (queries) =>
dispatch(setExchangeRateTableState(queries)),
});
export default connect(null, mapDispatchToProps);