feat: style vendor form and list.

feat: items state selectors.
This commit is contained in:
Ahmed Bouhuolia
2020-11-21 19:58:02 +02:00
parent b9e61461ae
commit 9eebaf5a6e
19 changed files with 332 additions and 202 deletions

View File

@@ -27,6 +27,7 @@ const CLASSES = {
PAGE_FORM_PAYMENT_MADE: 'page-form--payment-made', PAGE_FORM_PAYMENT_MADE: 'page-form--payment-made',
PAGE_FORM_PAYMENT_RECEIVE: 'page-form--payment-receive', PAGE_FORM_PAYMENT_RECEIVE: 'page-form--payment-receive',
PAGE_FORM_CUSTOMER: 'page-form--customer', PAGE_FORM_CUSTOMER: 'page-form--customer',
PAGE_FORM_VENDOR: 'page-form--customer',
PAGE_FORM_ITEM: 'page-form--item', PAGE_FORM_ITEM: 'page-form--item',
FORM_GROUP_LIST_SELECT: 'form-group--select-list', FORM_GROUP_LIST_SELECT: 'form-group--select-list',

View File

@@ -38,6 +38,7 @@ export default function CustomerFormAfterPrimarySection({}) {
/> />
)} )}
</FastField> </FastField>
<FastField name={'personal_phone'}> <FastField name={'personal_phone'}>
{({ field, meta: { error, touched } }) => ( {({ field, meta: { error, touched } }) => (
<InputGroup <InputGroup

View File

@@ -23,7 +23,11 @@ import withSettings from 'containers/Settings/withSettings';
import { compose, transformToForm } from 'utils'; import { compose, transformToForm } from 'utils';
import { transitionItemTypeKeyToLabel } from './utils'; import { transitionItemTypeKeyToLabel } from './utils';
import { EditItemFormSchema, CreateItemFormSchema } from './ItemForm.schema'; import {
EditItemFormSchema,
CreateItemFormSchema,
transformItemFormData,
} from './ItemForm.schema';
const defaultInitialValues = { const defaultInitialValues = {
active: true, active: true,
@@ -99,7 +103,10 @@ function ItemForm({
* values such as `notes` come back from the API as null, so remove those * values such as `notes` come back from the API as null, so remove those
* as well. * as well.
*/ */
...transformToForm(itemDetail, defaultInitialValues), ...transformToForm(
transformItemFormData(itemDetail, defaultInitialValues),
defaultInitialValues,
),
}), }),
[ [
itemDetail, itemDetail,

View File

@@ -52,5 +52,14 @@ const Schema = Yup.object().shape({
purchasable: Yup.boolean().required(), purchasable: Yup.boolean().required(),
}); });
export const transformItemFormData = (item, defaultValue) => {
return {
...item,
sellable: item?.sellable ? Boolean(item.sellable) : defaultValue.sellable,
purchasable: item?.purchasable ? Boolean(item.purchasable) : defaultValue.purchasable,
};
}
export const CreateItemFormSchema = Schema; export const CreateItemFormSchema = Schema;
export const EditItemFormSchema = Schema; export const EditItemFormSchema = Schema;

View File

@@ -27,6 +27,8 @@ function ItemsDataTable({
itemsTableLoading, itemsTableLoading,
itemsCurrentPage, itemsCurrentPage,
itemsTableQuery, itemsTableQuery,
itemsCurrentViewId,
itemsPagination,
// #withItemsActions // #withItemsActions
addItemsTableQueries, addItemsTableQueries,
@@ -120,9 +122,7 @@ function ItemsDataTable({
<Tag minimal={true} round={true} intent={Intent.NONE}> <Tag minimal={true} round={true} intent={Intent.NONE}>
{formatMessage({ id: row.type })} {formatMessage({ id: row.type })}
</Tag> </Tag>
) : ( ) : (''),
''
),
className: 'item_type', className: 'item_type',
width: 120, width: 120,
}, },
@@ -184,11 +184,16 @@ function ItemsDataTable({
[onSelectedRowsChange], [onSelectedRowsChange],
); );
const showEmptyStatus = [
itemsCurrentPage.length === 0,
itemsCurrentViewId === -1,
].every((condition) => condition === true);
return ( return (
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}> <div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
<LoadingIndicator loading={itemsTableLoading && !isLoadedBefore}> <LoadingIndicator loading={itemsTableLoading && !isLoadedBefore}>
<Choose> <Choose>
<Choose.When condition={true}> <Choose.When condition={showEmptyStatus}>
<ItemsEmptyStatus /> <ItemsEmptyStatus />
</Choose.When> </Choose.When>
@@ -198,14 +203,14 @@ function ItemsDataTable({
data={itemsCurrentPage} data={itemsCurrentPage}
onFetchData={handleFetchData} onFetchData={handleFetchData}
noInitialFetch={true} noInitialFetch={true}
expandable={true}
selectionColumn={true} selectionColumn={true}
spinnerProps={{ size: 30 }} spinnerProps={{ size: 30 }}
onSelectedRowsChange={handleSelectedRowsChange} onSelectedRowsChange={handleSelectedRowsChange}
rowContextMenu={handleRowContextMenu} rowContextMenu={handleRowContextMenu}
expandable={false}
sticky={true} sticky={true}
pagination={true} pagination={true}
pagesCount={2} pagesCount={itemsPagination.pagesCount}
autoResetSortBy={false} autoResetSortBy={false}
autoResetPage={false} autoResetPage={false}
initialPageSize={itemsTableQuery.page_size} initialPageSize={itemsTableQuery.page_size}
@@ -219,10 +224,20 @@ function ItemsDataTable({
} }
export default compose( export default compose(
withItems(({ itemsCurrentPage, itemsTableLoading, itemsTableQuery }) => ({ withItems(
itemsCurrentPage, ({
itemsTableLoading, itemsCurrentPage,
itemsTableQuery, itemsTableLoading,
})), itemsTableQuery,
itemsCurrentViewId,
itemsPagination
}) => ({
itemsCurrentPage,
itemsTableLoading,
itemsTableQuery,
itemsCurrentViewId,
itemsPagination
}),
),
withItemsActions, withItemsActions,
)(ItemsDataTable); )(ItemsDataTable);

View File

@@ -65,8 +65,9 @@ function ItemsList({
); );
// Handle fetching the items table based on the given query. // Handle fetching the items table based on the given query.
const fetchItems = useQuery(['items-table', itemsTableQuery], () => const fetchItems = useQuery(
requestFetchItems({}), ['items-table', itemsTableQuery],
(key, _query) => requestFetchItems({ ..._query }),
); );
// Handle click delete item. // Handle click delete item.

View File

@@ -1,26 +1,29 @@
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import { import {
getResourceViews, getResourceViews,
getViewPages,
} from 'store/customViews/customViews.selectors' } from 'store/customViews/customViews.selectors'
import { import {
getCurrentPageResults getItemsCurrentPageFactory,
} from 'store/selectors'; getItemsPaginationMetaFactory,
getItemsTableQueryFactory,
getItemsCurrentViewIdFactory
} from 'store/items/items.selectors';
export default (mapState) => { export default (mapState) => {
const mapStateToProps = (state, props) => { const getItemsCurrentPage = getItemsCurrentPageFactory();
const viewPages = getViewPages(state.items.views, state.items.currentViewId); const getItemsPaginationMeta = getItemsPaginationMetaFactory();
const getItemsTableQuery = getItemsTableQueryFactory();
const getItemsCurrentViewId = getItemsCurrentViewIdFactory();
const mapStateToProps = (state, props) => {
const mapped = { const mapped = {
itemsViews: getResourceViews(state, props, 'items'), itemsViews: getResourceViews(state, props, 'items'),
itemsCurrentPage: getCurrentPageResults( itemsCurrentPage: getItemsCurrentPage(state, props),
state.items.items,
viewPages,
state.items.currentPage,
),
itemsBulkSelected: state.items.bulkActions, itemsBulkSelected: state.items.bulkActions,
itemsTableLoading: state.items.loading, itemsTableLoading: state.items.loading,
itemsTableQuery: state.items.tableQuery, itemsTableQuery: getItemsTableQuery(state, props),
itemsPagination: getItemsPaginationMeta(state, props),
itemsCurrentViewId: getItemsCurrentViewId(state, props),
}; };
return mapState ? mapState(mapped, state, props) : mapped; return mapState ? mapState(mapped, state, props) : mapped;
}; };

View File

@@ -2,6 +2,7 @@ import React, { useCallback } from 'react';
import { useParams, useHistory } from 'react-router-dom'; import { useParams, useHistory } from 'react-router-dom';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { DashboardCard } from 'components';
import VendorFrom from './VendorForm'; import VendorFrom from './VendorForm';
import DashboardInsider from 'components/Dashboard/DashboardInsider'; import DashboardInsider from 'components/Dashboard/DashboardInsider';
@@ -53,11 +54,13 @@ function Vendor({
} }
name={'vendor-form'} name={'vendor-form'}
> >
<VendorFrom <DashboardCard page>
onFormSubmit={handleFormSubmit} <VendorFrom
vendorId={id} onFormSubmit={handleFormSubmit}
onCancelForm={handleCancel} vendorId={id}
/> onCancelForm={handleCancel}
/>
</DashboardCard>
</DashboardInsider> </DashboardInsider>
); );
} }

View File

@@ -153,9 +153,18 @@ function VendorForm({
> >
{({ isSubmitting }) => ( {({ isSubmitting }) => (
<Form> <Form>
<VendorFormPrimarySection /> <div className={classNames(CLASSES.PAGE_FORM_HEADER_PRIMARY)}>
<VendorFormAfterPrimarySection /> <VendorFormPrimarySection />
<VendorTabs vendor={vendorId} /> </div>
<div className={'page-form__after-priamry-section'}>
<VendorFormAfterPrimarySection />
</div>
<div className={classNames(CLASSES.PAGE_FORM_TABS)}>
<VendorTabs vendor={vendorId} />
</div>
<VendorFloatingActions <VendorFloatingActions
isSubmitting={isSubmitting} isSubmitting={isSubmitting}
vendor={vendorId} vendor={vendorId}

View File

@@ -12,7 +12,7 @@ import { inputIntent } from 'utils';
*/ */
function VendorFormAfterPrimarySection() { function VendorFormAfterPrimarySection() {
return ( return (
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}> <div class="customer-form__after-primary-section-content">
{/*------------ Vendor email -----------*/} {/*------------ Vendor email -----------*/}
<FastField name={'email'}> <FastField name={'email'}>
{({ field, meta: { error, touched } }) => ( {({ field, meta: { error, touched } }) => (
@@ -27,6 +27,7 @@ function VendorFormAfterPrimarySection() {
</FormGroup> </FormGroup>
)} )}
</FastField> </FastField>
{/*------------ Phone number -----------*/} {/*------------ Phone number -----------*/}
<FormGroup <FormGroup
className={'form-group--phone-number'} className={'form-group--phone-number'}
@@ -54,6 +55,7 @@ function VendorFormAfterPrimarySection() {
</FastField> </FastField>
</ControlGroup> </ControlGroup>
</FormGroup> </FormGroup>
{/*------------ Vendor website -----------*/} {/*------------ Vendor website -----------*/}
<FastField name={'website'}> <FastField name={'website'}>
{({ field, meta: { error, touched } }) => ( {({ field, meta: { error, touched } }) => (

View File

@@ -18,105 +18,100 @@ import { inputIntent } from 'utils';
*/ */
function VendorFormPrimarySection() { function VendorFormPrimarySection() {
return ( return (
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}> <div className={'customer-form__primary-section-content'}>
<div className={classNames(CLASSES.PAGE_FORM_HEADER_PRIMARY)}> {/**----------- Vendor name -----------*/}
{/**----------- Vendor name -----------*/} <FormGroup
<FormGroup className={classNames('form-group--contact_name')}
className={classNames('form-group--contact_name')} label={<T id={'contact_name'} />}
label={<T id={'contact_name'} />} inline={true}
inline={true} >
> <ControlGroup>
<ControlGroup> <FastField name={'salutation'}>
<FastField name={'salutation'}> {({ form, field: { value }, meta: { error, touched } }) => (
{({ form, field: { value }, meta: { error, touched } }) => ( <SalutationList
<SalutationList onItemSelect={(salutation) => {
onItemSelect={(salutation) => { form.setFieldValue('salutation', salutation.label);
form.setFieldValue('salutation', salutation.label);
}}
selectedItem={value}
popoverProps={{ minimal: true }}
className={classNames(
CLASSES.FORM_GROUP_LIST_SELECT,
CLASSES.FILL,
'input-group--salutation-list',
'select-list--fill-button',
)}
/>
)}
</FastField>
<FastField name={'first_name'}>
{({ field, meta: { error, touched } }) => (
<InputGroup
placeholder={'First Name'}
intent={inputIntent({ error, touched })}
className={classNames('input-group--first-name')}
{...field}
/>
)}
</FastField>
<FastField name={'last_name'}>
{({ field, meta: { error, touched } }) => (
<InputGroup
placeholder={'Last Name'}
intent={inputIntent({ error, touched })}
className={classNames('input-group--last-name')}
{...field}
/>
)}
</FastField>
</ControlGroup>
</FormGroup>
{/*----------- Company Name -----------*/}
<FastField name={'company_name'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
className={classNames('form-group--company_name')}
label={<T id={'company_name'} />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'company_name'} />}
inline={true}
>
<InputGroup {...field} />
</FormGroup>
)}
</FastField>
{/*----------- Display Name -----------*/}
<Field name={'display_name'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
helperText={<ErrorMessage name={'display_name'} />}
intent={inputIntent({ error, touched })}
label={
<>
<T id={'display_name'} />
<FieldRequiredHint />
<Hint />
</>
}
className={classNames(
CLASSES.FORM_GROUP_LIST_SELECT,
CLASSES.FILL,
)}
inline={true}
>
<DisplayNameList
firstName={form.values.first_name}
lastName={form.values.last_name}
company={form.values.company_name}
salutation={form.values.salutation}
onItemSelect={(displayName) => {
form.setFieldValue('display_name', displayName.label);
}} }}
selectedItem={value} selectedItem={value}
popoverProps={{ minimal: true }} popoverProps={{ minimal: true }}
className={classNames(
CLASSES.FORM_GROUP_LIST_SELECT,
CLASSES.FILL,
'input-group--salutation-list',
'select-list--fill-button',
)}
/> />
</FormGroup> )}
)} </FastField>
</Field>
</div> <FastField name={'first_name'}>
{({ field, meta: { error, touched } }) => (
<InputGroup
placeholder={'First Name'}
intent={inputIntent({ error, touched })}
className={classNames('input-group--first-name')}
{...field}
/>
)}
</FastField>
<FastField name={'last_name'}>
{({ field, meta: { error, touched } }) => (
<InputGroup
placeholder={'Last Name'}
intent={inputIntent({ error, touched })}
className={classNames('input-group--last-name')}
{...field}
/>
)}
</FastField>
</ControlGroup>
</FormGroup>
{/*----------- Company Name -----------*/}
<FastField name={'company_name'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
className={classNames('form-group--company_name')}
label={<T id={'company_name'} />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'company_name'} />}
inline={true}
>
<InputGroup {...field} />
</FormGroup>
)}
</FastField>
{/*----------- Display Name -----------*/}
<Field name={'display_name'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
helperText={<ErrorMessage name={'display_name'} />}
intent={inputIntent({ error, touched })}
label={
<>
<T id={'display_name'} />
<FieldRequiredHint />
<Hint />
</>
}
className={classNames(CLASSES.FORM_GROUP_LIST_SELECT, CLASSES.FILL)}
inline={true}
>
<DisplayNameList
firstName={form.values.first_name}
lastName={form.values.last_name}
company={form.values.company_name}
salutation={form.values.salutation}
onItemSelect={(displayName) => {
form.setFieldValue('display_name', displayName.label);
}}
selectedItem={value}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</Field>
</div> </div>
); );
} }

View File

@@ -0,0 +1,37 @@
import React from 'react';
import { Button, Intent } from '@blueprintjs/core';
import { useHistory } from 'react-router-dom';
import { EmptyStatus } from 'components';
export default function VendorsEmptyStatus() {
const history = useHistory();
return (
<EmptyStatus
title={"Create and manage your organization's vendors."}
description={
<p>
Here a list of your organization products and services, to be used
when you create invoices or bills to your customers or vendors.
</p>
}
action={
<>
<Button
intent={Intent.PRIMARY}
large={true}
onClick={() => {
history.push('/vendors/new');
}}
>
New vendor
</Button>
<Button intent={Intent.NONE} large={true}>
Learn more
</Button>
</>
}
/>
);
}

View File

@@ -9,10 +9,12 @@ import {
Intent, Intent,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T, useIntl } from 'react-intl';
import classNames from 'classnames';
import { useIsValuePassed } from 'hooks'; import { useIsValuePassed } from 'hooks';
import LoadingIndicator from 'components/LoadingIndicator'; import VendorsEmptyStatus from './VendorsEmptyStatus';
import { DataTable, Icon, Money } from 'components'; import { DataTable, LoadingIndicator, Icon, Money, Choose } from 'components';
import { CLASSES } from 'common/classes';
import withVendors from './withVendors'; import withVendors from './withVendors';
import withVendorsActions from './withVendorActions'; import withVendorsActions from './withVendorActions';
@@ -34,8 +36,7 @@ function VendorsTable({
// #withVendorsActions // #withVendorsActions
addVendorsTableQueries, addVendorsTableQueries,
// #OwnProps // #ownProps
loading,
onEditVendor, onEditVendor,
onDeleteVendor, onDeleteVendor,
onSelectedRowsChange, onSelectedRowsChange,
@@ -182,29 +183,41 @@ function VendorsTable({
onDeleteVendor, onDeleteVendor,
}); });
console.log(vendorsCurrentPage, 'vendorsCurrentPage');
return ( return (
<LoadingIndicator loading={vendorsLoading && !isLoadedBefore} mount={false}> <div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
<DataTable <LoadingIndicator
noInitialFetch={true} loading={vendorsLoading && !isLoadedBefore}
columns={columns} mount={false}
data={vendorItems} >
onFetchData={handleFetchData} <Choose>
selectionColumn={true} <Choose.When condition={true}>
expandable={false} <VendorsEmptyStatus />
sticky={true} </Choose.When>
onSelectedRowsChange={handleSelectedRowsChange}
spinnerProps={{ size: 30 }} <Choose.Otherwise>
rowContextMenu={rowContextMenu} <DataTable
pagination={true} noInitialFetch={true}
manualSortBy={true} columns={columns}
pagesCount={vendorsPageination.pagesCount} data={vendorItems}
autoResetSortBy={false} onFetchData={handleFetchData}
autoResetPage={false} selectionColumn={true}
initialPageSize={vendorTableQuery.page_size} expandable={false}
initialPageIndex={vendorTableQuery.page - 1} sticky={true}
/> onSelectedRowsChange={handleSelectedRowsChange}
</LoadingIndicator> spinnerProps={{ size: 30 }}
rowContextMenu={rowContextMenu}
pagination={true}
manualSortBy={true}
pagesCount={vendorsPageination.pagesCount}
autoResetSortBy={false}
autoResetPage={false}
initialPageSize={vendorTableQuery.page_size}
initialPageIndex={vendorTableQuery.page - 1}
/>
</Choose.Otherwise>
</Choose>
</LoadingIndicator>
</div>
); );
} }

View File

@@ -43,35 +43,13 @@ export default createReducer(initialState, {
const viewId = customViewId || -1; const viewId = customViewId || -1;
const view = state.views[viewId] || {}; const view = state.views[viewId] || {};
const viewPages = getItemsViewPages(state.views, viewId);
items.forEach((item) => {
const stateItem = state.items[item.id];
const itemRelation = state.itemsRelation[stateItem.id];
if (typeof itemRelation === 'undefined') {
state.itemsRelation[item.id] = [];
}
const filteredRelation = state.itemsRelation[item.id].filter(
(relation) =>
relation.viewId === viewId &&
relation.pageNumber === paginationMeta.page,
);
filteredRelation.push({
viewId,
pageNumber: paginationMeta.page,
});
state.itemsRelation[item.id] = filteredRelation;
});
state.views[viewId] = { state.views[viewId] = {
...view, ...view,
pages: { pages: {
...viewPages, ...(state.views?.[viewId]?.pages || {}),
[paginationMeta.page]: { [paginationMeta.page]: {
ids: items.map((i) => i.id), ids: items.map((item) => item.id),
meta: paginationMeta,
}, },
}, },
}; };

View File

@@ -1,7 +1,69 @@
import { paginationLocationQuery } from "store/selectors";
import { createSelector } from 'reselect';
import {
pickItemsFromIds,
defaultPaginationMeta,
} from 'store/selectors';
const itemsTableQuerySelector = (state) => state.items.tableQuery;
const itemsCurrentPageSelector = (state, props) => {
const currentViewId = state.items.currentViewId;
const currentView = state.items.views?.[currentViewId];
const currentPageId = currentView?.paginationMeta?.page;
export const getItemsViewPages = (itemsViews, viewId) => { return currentView?.pages?.[currentPageId];
return itemsViews[viewId] ? };
itemsViews[viewId].pages : {}; const itemsDataSelector = (state) => state.items.items;
};
const itemsPaginationSelector = (state, props) => {
const viewId = state.items.currentViewId;
return state.items.views?.[viewId]?.paginationMeta;
};
const customersCurrentViewIdSelector = (state) => state.customers.currentViewId;
// Get items table query marged with location query.
export const getItemsTableQueryFactory = () =>
createSelector(
paginationLocationQuery,
itemsTableQuerySelector,
(locationQuery, tableQuery) => {
return {
...locationQuery,
...tableQuery,
}
},
);
// Retrieve items current page and view.
export const getItemsCurrentPageFactory = () =>
createSelector(
itemsDataSelector,
itemsCurrentPageSelector,
(items, itemsIdsCurrentPage) => {
return typeof itemsIdsCurrentPage === 'object'
? pickItemsFromIds(items, itemsIdsCurrentPage.ids) || []
: [];
},
);
// Retrieve items pagination meta.
export const getItemsPaginationMetaFactory = () =>
createSelector(
itemsPaginationSelector,
(itemsPagination) => {
return {
...defaultPaginationMeta(),
...itemsPagination,
};
}
);
// Retrieve items current view id.
export const getItemsCurrentViewIdFactory = () =>
createSelector(
customersCurrentViewIdSelector,
(currentViewId) => {
return currentViewId;
}
);

View File

@@ -5,12 +5,14 @@ import {
defaultPaginationMeta, defaultPaginationMeta,
} from 'store/selectors'; } from 'store/selectors';
const vendorsTableQuery = (state) => { const vendorsTableQuery = (state) => state.vendors.tableQuery;
return state.vendors.tableQuery; const vendorByIdSelector = (state, props) =>
}; state.vendors.items[props.vendorId];
const vendorsItemsSelector = (state) => state.vendors.items;
const vendorByIdSelector = (state, props) => { const vendorsPaginationSelector = (state, props) => {
return state.vendors.items[props.vendorId]; const viewId = state.vendors.currentViewId;
return state.vendors.views?.[viewId];
}; };
export const getVendorsTableQuery = createSelector( export const getVendorsTableQuery = createSelector(
@@ -28,11 +30,9 @@ const vendorsPageSelector = (state, props, query) => {
const viewId = state.vendors.currentViewId; const viewId = state.vendors.currentViewId;
const currentView = state.vendors.views?.[viewId]; const currentView = state.vendors.views?.[viewId];
const currentPageId = currentView?.pages; const currentPageId = currentView?.pages;
return currentView?.pages?.[currentPageId];
// return state.vendors.views?.[viewId]?.pages?.[query.page];
};
const vendorsItemsSelector = (state) => state.vendors.items; return currentView?.pages?.[currentPageId];
};
export const getVendorCurrentPageFactory = () => export const getVendorCurrentPageFactory = () =>
createSelector( createSelector(
@@ -45,11 +45,6 @@ export const getVendorCurrentPageFactory = () =>
}, },
); );
const vendorsPaginationSelector = (state, props) => {
const viewId = state.vendors.currentViewId;
return state.vendors.views?.[viewId];
};
export const getVendorsPaginationMetaFactory = () => export const getVendorsPaginationMetaFactory = () =>
createSelector(vendorsPaginationSelector, (vendorPage) => { createSelector(vendorsPaginationSelector, (vendorPage) => {
return { return {

View File

@@ -341,7 +341,7 @@
.datatable-empty-status{ .datatable-empty-status{
margin-top: auto; margin-top: auto;
margin-bottom: auto; margin-bottom: auto;
padding-bottom: 40px; padding-bottom: 20px;
} }
} }

View File

@@ -8,7 +8,7 @@
} }
#{$self}__primary-section{ #{$self}__primary-section{
overflow: hidden; overflow: hidden;
padding-top: 10px; padding-top: 5px;
margin-bottom: 20px; margin-bottom: 20px;
border-bottom: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea;
padding-bottom: 5px; padding-bottom: 5px;

View File

@@ -1,7 +1,6 @@
exports.up = function (knex) { exports.up = function (knex) {
return knex.schema.createTable('accounts', (table) => { return knex.schema.createTable('accounts', (table) => {
table.increments('id').comment('Auto-generated id');; table.increments('id').comment('Auto-generated id');
table.string('name').index(); table.string('name').index();
table.string('slug'); table.string('slug');
table.integer('account_type_id').unsigned().references('id').inTable('account_types'); table.integer('account_type_id').unsigned().references('id').inTable('account_types');