mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
Config With Seacrh
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {useHistory} from 'react-router';
|
||||
import { connect } from 'react-redux';
|
||||
import { useHistory } from 'react-router';
|
||||
import {
|
||||
Navbar,
|
||||
NavbarGroup,
|
||||
@@ -14,59 +14,79 @@ import {
|
||||
import DashboardBreadcrumbs from 'components/Dashboard/DashboardBreadcrumbs';
|
||||
import DashboardTopbarUser from 'components/Dashboard/TopbarUser';
|
||||
import Icon from 'components/Icon';
|
||||
import Search from 'containers/Dashboard/GeneralSearch/Search';
|
||||
|
||||
function DashboardTopbar({
|
||||
pageTitle,
|
||||
pageSubtitle,
|
||||
editViewId,
|
||||
}) {
|
||||
function DashboardTopbar({ pageTitle, pageSubtitle, editViewId }) {
|
||||
const history = useHistory();
|
||||
|
||||
const handlerClickEditView = () => {
|
||||
history.push(`/dashboard/custom_views/${editViewId}/edit`)
|
||||
}
|
||||
history.push(`/dashboard/custom_views/${editViewId}/edit`);
|
||||
};
|
||||
|
||||
const maybleRenderPageSubtitle = pageSubtitle && (<h3>{ pageSubtitle }</h3>);
|
||||
const maybeRenderEditViewBtn = (pageSubtitle && editViewId) && (
|
||||
const maybleRenderPageSubtitle = pageSubtitle && <h3>{pageSubtitle}</h3>;
|
||||
const maybeRenderEditViewBtn = pageSubtitle && editViewId && (
|
||||
<Button
|
||||
className={Classes.MINIMAL + ' button--view-edit'}
|
||||
icon={<Icon icon="pen" iconSize={13} />}
|
||||
onClick={handlerClickEditView} />
|
||||
icon={<Icon icon='pen' iconSize={13} />}
|
||||
onClick={handlerClickEditView}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<div class="dashboard__topbar">
|
||||
<div class="dashboard__topbar-left">
|
||||
<div class="dashboard__topbar-sidebar-toggle">
|
||||
<div class='dashboard__topbar'>
|
||||
<div class='dashboard__topbar-left'>
|
||||
<div class='dashboard__topbar-sidebar-toggle'>
|
||||
<Button>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" role="img" focusable="false">
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
width='20'
|
||||
height='20'
|
||||
viewBox='0 0 20 20'
|
||||
role='img'
|
||||
focusable='false'
|
||||
>
|
||||
<title>Menu</title>
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="5" stroke-width="2" d="M4 7h15M4 12h15M4 17h15"></path>
|
||||
<path
|
||||
stroke='currentColor'
|
||||
stroke-linecap='round'
|
||||
stroke-miterlimit='5'
|
||||
stroke-width='2'
|
||||
d='M4 7h15M4 12h15M4 17h15'
|
||||
></path>
|
||||
</svg>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="dashboard__title">
|
||||
<h1>{ pageTitle }</h1>
|
||||
<div class='dashboard__title'>
|
||||
<h1>{pageTitle}</h1>
|
||||
{maybleRenderPageSubtitle}
|
||||
{maybeRenderEditViewBtn}
|
||||
</div>
|
||||
|
||||
<div class="dashboard__breadcrumbs">
|
||||
<div class='dashboard__breadcrumbs'>
|
||||
<DashboardBreadcrumbs />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dashboard__topbar-right">
|
||||
<Navbar class="dashboard__topbar-navbar">
|
||||
<div class='dashboard__topbar-right'>
|
||||
<Navbar class='dashboard__topbar-navbar'>
|
||||
<NavbarGroup>
|
||||
<Button className={Classes.MINIMAL} icon="home" text="Search" />
|
||||
<Button className={Classes.MINIMAL} icon="document" text="Filters" />
|
||||
<Button className={Classes.MINIMAL} icon="document" text="Add order" />
|
||||
<Button className={Classes.MINIMAL} icon="document" text="More" />
|
||||
{/* <Button className={Classes.MINIMAL} icon="home" text="Search" /> */}
|
||||
<Search className />
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon='document'
|
||||
text='Filters'
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon='document'
|
||||
text='Add order'
|
||||
/>
|
||||
<Button className={Classes.MINIMAL} icon='document' text='More' />
|
||||
</NavbarGroup>
|
||||
</Navbar>
|
||||
|
||||
<div class="dashboard__topbar-user">
|
||||
<div class='dashboard__topbar-user'>
|
||||
<DashboardTopbarUser />
|
||||
</div>
|
||||
</div>
|
||||
@@ -77,7 +97,7 @@ function DashboardTopbar({
|
||||
const mapStateToProps = (state) => ({
|
||||
pageTitle: state.dashboard.pageTitle,
|
||||
pageSubtitle: state.dashboard.pageSubtitle,
|
||||
editViewId: state.dashboard.topbarEditViewId,
|
||||
editViewId: state.dashboard.topbarEditViewId,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(DashboardTopbar);
|
||||
export default connect(mapStateToProps)(DashboardTopbar);
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Popover,
|
||||
Menu,
|
||||
MenuItem,
|
||||
MenuDivider,
|
||||
Position,
|
||||
Checkbox
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
GridComponent,
|
||||
ColumnsDirective,
|
||||
ColumnDirective,
|
||||
Inject,
|
||||
Sort
|
||||
} from '@syncfusion/ej2-react-grids';
|
||||
import LoadingIndicator from 'components/LoadingIndicator';
|
||||
import DashboardConnect from 'connectors/Dashboard.connector';
|
||||
import ItemFormDialogConnect from 'connectors/ItemFormDialog.connect';
|
||||
import Icon from 'components/Icon';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { handleBooleanChange, compose } from 'utils';
|
||||
import DataTable from 'components/DataTable';
|
||||
const categoryList = ({ categories }) => {
|
||||
const columns = [
|
||||
{
|
||||
field: 'name',
|
||||
headerText: 'Name'
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
headerText: 'Description'
|
||||
}
|
||||
];
|
||||
return (
|
||||
<LoadingIndicator>
|
||||
<GridComponent
|
||||
allowSorting={true}
|
||||
dataSource={columns}
|
||||
enableVirtualization={true}
|
||||
>
|
||||
<ColumnsDirective>
|
||||
<ColumnDirective type='checkbox'></ColumnDirective>
|
||||
{/* {columns.map(column => {
|
||||
return (
|
||||
<ColumnDirective
|
||||
field={column.field}
|
||||
headerText={column.headerText}
|
||||
allowSorting={true}
|
||||
/>
|
||||
);
|
||||
})} */}
|
||||
</ColumnsDirective>
|
||||
</GridComponent>
|
||||
</LoadingIndicator>
|
||||
);
|
||||
};
|
||||
|
||||
export default compose(DashboardConnect, ItemFormDialogConnect)(categoryList);
|
||||
@@ -18,7 +18,6 @@ import { useUpdateEffect } from 'hooks';
|
||||
|
||||
function ManualJournalsViewTabs({
|
||||
views,
|
||||
manualJournals,
|
||||
setTopbarEditView,
|
||||
customViewChanged,
|
||||
addManualJournalsTableQueries,
|
||||
@@ -51,8 +50,6 @@ function ManualJournalsViewTabs({
|
||||
}, [customViewId]);
|
||||
|
||||
const tabs = views.map((view) => {
|
||||
//FIXME: dashboard/accounting/make-journal-entry
|
||||
|
||||
const baseUrl = '/dashboard/accounting/manual-journals';
|
||||
const link = (
|
||||
<Link
|
||||
|
||||
13
client/src/connectors/Search.connect.js
Normal file
13
client/src/connectors/Search.connect.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { connect } from 'react-redux';
|
||||
import t from 'store/types';
|
||||
import { generalSearch } from 'store/search/search.actions';
|
||||
|
||||
export const mapStateToProps = (state, props) => ({
|
||||
resultSearch: state.GeneralSearch,
|
||||
});
|
||||
|
||||
export const mapDispatchToProps = (dispatch) => ({
|
||||
generalSearch: (result) => dispatch(generalSearch(result)),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps);
|
||||
74
client/src/containers/Dashboard/GeneralSearch/Search.js
Normal file
74
client/src/containers/Dashboard/GeneralSearch/Search.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Omnibar } from '@blueprintjs/select';
|
||||
import { MenuItem, Button, Classes } from '@blueprintjs/core';
|
||||
import { useAsync } from 'react-use';
|
||||
import * as Yup from 'yup';
|
||||
import { useFormik } from 'formik';
|
||||
import Icon from 'components/Icon';
|
||||
import { compose } from 'utils';
|
||||
import SearchConnect from 'connectors/Search.connect';
|
||||
|
||||
function Search({}) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const items = [
|
||||
{ title: 'The Shawshank Redemption', year: 1994 },
|
||||
{ title: 'The Godfather', year: 1972 },
|
||||
{ title: 'The Godfather: Part II', year: 1974 },
|
||||
];
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
name: Yup.string().required(),
|
||||
});
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
validationSchema: validationSchema,
|
||||
initialValues: {},
|
||||
});
|
||||
const renderSearch = (search, { handleClick, modifiers }) => (
|
||||
<MenuItem
|
||||
active={modifiers.active}
|
||||
key={search.id}
|
||||
text={search.name}
|
||||
label={search.name}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
);
|
||||
|
||||
const filterSearch = (query, search, _index, exactMatch) => {
|
||||
// const normalizedTitle = search.toLowerCase();
|
||||
// const normalizedQuery = query.toLowerCase();
|
||||
// if (exactMatch) {
|
||||
// return normalizedTitle === normalizedQuery;
|
||||
// } else {
|
||||
// return `${search} ${normalizedTitle}`.indexOf(normalizedQuery) >= 0;
|
||||
// }
|
||||
return search;
|
||||
};
|
||||
const handleClick = () => setIsOpen(true);
|
||||
const handleClose = () => setIsOpen(false);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon='home'
|
||||
text='Search'
|
||||
onClick={handleClick}
|
||||
/>
|
||||
<Omnibar
|
||||
isOpen={isOpen}
|
||||
noResults={<MenuItem disabled={true} text='No results.' />}
|
||||
onClose={handleClose}
|
||||
resetOnSelect={true}
|
||||
itemRenderer={renderSearch}
|
||||
items={items}
|
||||
// onItemSelect={}
|
||||
itemListPredicate={filterSearch}
|
||||
// style={{ position: 'absolute', canter: '50%' }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(SearchConnect)(Search);
|
||||
@@ -2,7 +2,7 @@ import ApiService from 'services/ApiService';
|
||||
import t from 'store/types';
|
||||
|
||||
export const submitItemCategory = ({ form }) => {
|
||||
return dispatch => {
|
||||
return (dispatch) => {
|
||||
return ApiService.post('item_categories', { ...form });
|
||||
};
|
||||
};
|
||||
@@ -11,53 +11,53 @@ export const fetchItemCategories = () => {
|
||||
return (dispatch, getState) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.get('item_categories')
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.ITEMS_CATEGORY_LIST_SET,
|
||||
categories: response.data.categories
|
||||
categories: response.data.categories,
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const editItemCategory = (id, form) => {
|
||||
return dispatch =>
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.post(`item_categories/${id}`, form)
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
dispatch({ type: t.CLEAR_CATEGORY_FORM_ERRORS });
|
||||
resolve(response);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
const { response } = error;
|
||||
const { data } = response;
|
||||
const { errors } = data;
|
||||
|
||||
dispatch({ type: t.CLEAR_CATEGORY_FORM_ERRORS });
|
||||
if (errors) {
|
||||
dispatch({ type: t.CATEGORY_FORM_ERRORS, errors });
|
||||
dispatch({ type: t.CLEAR_CATEGORY_FORM_ERRORS, errors });
|
||||
}
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteItemCategory = id => {
|
||||
return dispatch =>
|
||||
export const deleteItemCategory = (id) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.delete(`item_categories/${id}`)
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.CATEGORY_DELETE,
|
||||
id
|
||||
id,
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,6 +14,7 @@ import financialStatements from './financialStatement/financialStatements.reduce
|
||||
import itemCategories from './itemCategories/itemsCategory.reducer';
|
||||
import settings from './settings/settings.reducer';
|
||||
import manualJournals from './manualJournals/manualJournals.reducers';
|
||||
import search from './search/search.reducer';
|
||||
|
||||
export default combineReducers({
|
||||
authentication,
|
||||
@@ -30,4 +31,5 @@ export default combineReducers({
|
||||
items,
|
||||
itemCategories,
|
||||
settings,
|
||||
search,
|
||||
});
|
||||
|
||||
8
client/src/store/search/search.actions.js
Normal file
8
client/src/store/search/search.actions.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export function generalSearch(name, result) {
|
||||
return {
|
||||
type: t.SEARCH_SUCCESS,
|
||||
result,
|
||||
};
|
||||
}
|
||||
33
client/src/store/search/search.reducer.js
Normal file
33
client/src/store/search/search.reducer.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import t from 'store/types';
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
|
||||
const initialState = {
|
||||
searches: {},
|
||||
searchTitle: 'Title',
|
||||
isOpen: false,
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
[t.SEARCH_SUCCESS]: (state, action) => {
|
||||
const _result = {};
|
||||
|
||||
action.searches.forEach((search) => {
|
||||
_result[search.id] = search;
|
||||
});
|
||||
|
||||
state.searches = {
|
||||
...state.searches,
|
||||
..._result,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
// return state = action.result;
|
||||
// if (typeof state === 'undefined') {
|
||||
// return initialState;
|
||||
// }
|
||||
|
||||
// state.search[action.name] = {
|
||||
// isOpen: true,
|
||||
// payload: action.payload || {},
|
||||
// };
|
||||
5
client/src/store/search/search.type.js
Normal file
5
client/src/store/search/search.type.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
SEARCH_SUCCESS: 'SEARCH_SUCCESS',
|
||||
SEARCH_FAILURE: 'SEARCH_FAILURE',
|
||||
SEARCH_REQUEST: 'SEARCH_REQUEST',
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import authentication from './authentication/authentication.types';
|
||||
import accounts from './accounts/accounts.types';
|
||||
import accounting from './manualJournals/manualJournals.types'
|
||||
import accounting from './manualJournals/manualJournals.types';
|
||||
import currencies from './currencies/currencies.types';
|
||||
import customFields from './customFields/customFields.types';
|
||||
import customViews from './customViews/customViews.types';
|
||||
@@ -13,7 +13,7 @@ import users from './users/users.types';
|
||||
import financialStatements from './financialStatement/financialStatements.types';
|
||||
import itemCategories from './itemCategories/itemsCategory.type';
|
||||
import settings from './settings/settings.type';
|
||||
|
||||
import search from './search/search.type';
|
||||
export default {
|
||||
...authentication,
|
||||
...accounts,
|
||||
@@ -30,4 +30,5 @@ export default {
|
||||
...itemCategories,
|
||||
...settings,
|
||||
...accounting,
|
||||
...search,
|
||||
};
|
||||
|
||||
@@ -15,30 +15,40 @@ export default {
|
||||
|
||||
router.use(JWTAuth);
|
||||
|
||||
router.post('/:id',
|
||||
router.post(
|
||||
'/:id',
|
||||
// permit('create', 'edit'),
|
||||
this.editCategory.validation,
|
||||
asyncMiddleware(this.editCategory.handler));
|
||||
asyncMiddleware(this.editCategory.handler)
|
||||
);
|
||||
|
||||
router.post('/',
|
||||
router.post(
|
||||
'/',
|
||||
// permit('create'),
|
||||
this.newCategory.validation,
|
||||
asyncMiddleware(this.newCategory.handler));
|
||||
asyncMiddleware(this.newCategory.handler)
|
||||
);
|
||||
|
||||
router.delete('/:id',
|
||||
router.delete(
|
||||
'/:id',
|
||||
// permit('create', 'edit', 'delete'),
|
||||
this.deleteItem.validation,
|
||||
asyncMiddleware(this.deleteItem.handler));
|
||||
asyncMiddleware(this.deleteItem.handler)
|
||||
);
|
||||
|
||||
router.get('/:id',
|
||||
router.get(
|
||||
'/:id',
|
||||
// permit('view'),
|
||||
this.getCategory.validation,
|
||||
asyncMiddleware(this.getCategory.handler));
|
||||
asyncMiddleware(this.getCategory.handler)
|
||||
);
|
||||
|
||||
router.get('/',
|
||||
router.get(
|
||||
'/',
|
||||
// permit('view'),
|
||||
this.getList.validation,
|
||||
asyncMiddleware(this.getList.handler));
|
||||
asyncMiddleware(this.getList.handler)
|
||||
);
|
||||
|
||||
return router;
|
||||
},
|
||||
@@ -48,16 +58,26 @@ export default {
|
||||
*/
|
||||
newCategory: {
|
||||
validation: [
|
||||
check('name').exists().trim().escape(),
|
||||
check('parent_category_id').optional().isNumeric().toInt(),
|
||||
check('description').optional().trim().escape(),
|
||||
check('name')
|
||||
.exists()
|
||||
.trim()
|
||||
.escape(),
|
||||
check('parent_category_id')
|
||||
.optional({ nullable: true, checkFalsy: true })
|
||||
.isNumeric()
|
||||
.toInt(),
|
||||
check('description')
|
||||
.optional()
|
||||
.trim()
|
||||
.escape()
|
||||
],
|
||||
async handler(req, res) {
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
code: 'validation_error',
|
||||
...validationErrors
|
||||
});
|
||||
}
|
||||
|
||||
@@ -66,20 +86,21 @@ export default {
|
||||
|
||||
if (form.parent_category_id) {
|
||||
const foundParentCategory = await ItemCategory.query()
|
||||
.where('id', form.parent_category_id).first();
|
||||
.where('id', form.parent_category_id)
|
||||
.first();
|
||||
|
||||
if (!foundParentCategory) {
|
||||
return res.boom.notFound('The parent category ID is not found.', {
|
||||
errors: [{ type: 'PARENT_CATEGORY_NOT_FOUND', code: 100 }],
|
||||
errors: [{ type: 'PARENT_CATEGORY_NOT_FOUND', code: 100 }]
|
||||
});
|
||||
}
|
||||
}
|
||||
const category = await ItemCategory.query().insert({
|
||||
...form,
|
||||
user_id: user.id,
|
||||
user_id: user.id
|
||||
});
|
||||
return res.status(200).send({ category });
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -88,9 +109,18 @@ export default {
|
||||
editCategory: {
|
||||
validation: [
|
||||
param('id').toInt(),
|
||||
check('name').exists().trim().escape(),
|
||||
check('parent_category_id').optional().isNumeric().toInt(),
|
||||
check('description').optional().trim().escape(),
|
||||
check('name')
|
||||
.exists()
|
||||
.trim()
|
||||
.escape(),
|
||||
check('parent_category_id')
|
||||
.optional({ nullable: true, checkFalsy: true })
|
||||
.isNumeric()
|
||||
.toInt(),
|
||||
check('description')
|
||||
.optional()
|
||||
.trim()
|
||||
.escape()
|
||||
],
|
||||
async handler(req, res) {
|
||||
const { id } = req.params;
|
||||
@@ -98,33 +128,41 @@ export default {
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
code: 'validation_error',
|
||||
...validationErrors
|
||||
});
|
||||
}
|
||||
|
||||
const form = { ...req.body };
|
||||
const itemCategory = await ItemCategory.query().where('id', id).first()
|
||||
const itemCategory = await ItemCategory.query()
|
||||
.where('id', id)
|
||||
.first();
|
||||
|
||||
if (!itemCategory) {
|
||||
return res.boom.notFound({
|
||||
errors: [{ type: 'ITEM_CATEGORY.NOT.FOUND', code: 100 }],
|
||||
errors: [{ type: 'ITEM_CATEGORY.NOT.FOUND', code: 100 }]
|
||||
});
|
||||
}
|
||||
if (form.parent_category_id
|
||||
&& form.parent_category_id !== itemCategory.parent_category_id) {
|
||||
if (
|
||||
form.parent_category_id &&
|
||||
form.parent_category_id !== itemCategory.parent_category_id
|
||||
) {
|
||||
const foundParentCategory = await ItemCategory.query()
|
||||
.where('id', form.parent_category_id).first();
|
||||
.where('id', form.parent_category_id)
|
||||
.first();
|
||||
|
||||
if (!foundParentCategory) {
|
||||
return res.boom.notFound('The parent category ID is not found.', {
|
||||
errors: [{ type: 'PARENT_CATEGORY_NOT_FOUND', code: 100 }],
|
||||
errors: [{ type: 'PARENT_CATEGORY_NOT_FOUND', code: 100 }]
|
||||
});
|
||||
}
|
||||
}
|
||||
const updateItemCategory = await ItemCategory.query().where('id', id).update({ ...form });
|
||||
const updateItemCategory = await ItemCategory.query()
|
||||
.where('id', id)
|
||||
.update({ ...form });
|
||||
|
||||
return res.status(200).send({ id: updateItemCategory });
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -132,20 +170,26 @@ export default {
|
||||
*/
|
||||
deleteItem: {
|
||||
validation: [
|
||||
param('id').exists().toInt(),
|
||||
param('id')
|
||||
.exists()
|
||||
.toInt()
|
||||
],
|
||||
async handler(req, res) {
|
||||
const { id } = req.params;
|
||||
const itemCategory = await ItemCategory.query().where('id', id).first();
|
||||
const itemCategory = await ItemCategory.query()
|
||||
.where('id', id)
|
||||
.first();
|
||||
|
||||
if (!itemCategory) {
|
||||
return res.boom.notFound();
|
||||
}
|
||||
|
||||
await ItemCategory.query().where('id', itemCategory.id).delete();
|
||||
await ItemCategory.query()
|
||||
.where('id', itemCategory.id)
|
||||
.delete();
|
||||
|
||||
return res.status(200).send();
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -157,27 +201,25 @@ export default {
|
||||
const categories = await ItemCategory.query();
|
||||
|
||||
return res.status(200).send({ categories });
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve details of the given category.
|
||||
*/
|
||||
getCategory: {
|
||||
validation: [
|
||||
param('category_id').toInt(),
|
||||
],
|
||||
validation: [param('category_id').toInt()],
|
||||
async handler(req, res) {
|
||||
const { category_id: categoryId } = req.params;
|
||||
const item = await ItemCategory.where('id', categoryId).fetch();
|
||||
|
||||
if (!item) {
|
||||
return res.boom.notFound(null, {
|
||||
errors: [{ type: 'CATEGORY_NOT_FOUND', code: 100 }],
|
||||
errors: [{ type: 'CATEGORY_NOT_FOUND', code: 100 }]
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).send({ category: item.toJSON() });
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user