From a174c255c8020dde0b3c7ee667f103e2759e6f4c Mon Sep 17 00:00:00 2001 From: batmnkh2344 <143669110+batmnkh2344@users.noreply.github.com> Date: Wed, 20 Dec 2023 15:28:04 +0800 Subject: [PATCH] perf(assets): fix layout and some refactor --- .../team/components/common/BlockList.tsx | 2 +- .../team/components/unit/MainList.tsx | 1 + packages/core/src/data/resolvers/units.ts | 7 + packages/core/src/data/schema/structure.ts | 1 + .../collapsibleList/CollapsibleList.tsx | 37 +- .../erxes-ui/src/components/filter/Filter.tsx | 11 + .../src/components/filter/createChipText.tsx | 6 + packages/erxes-ui/src/team/graphql/queries.ts | 1 + packages/erxes-ui/src/team/types.ts | 1 + .../src/asset/category/components/List.tsx | 212 ---------- .../category/components/StatusFilter.tsx | 69 ---- .../src/asset/category/graphql/index.ts | 4 - .../src/asset/category/graphql/mutations.ts | 27 -- .../src/asset/category/graphql/queries.ts | 69 ---- .../components/{Form.tsx => AssetForm.tsx} | 337 ++++++++------- .../src/asset/components/AssignArticles.tsx | 292 ------------- .../Form.tsx => components/CategoryForm.tsx} | 122 +++--- .../src/asset/components/List.tsx | 389 +++++++++--------- .../src/asset/components/Merge.tsx | 212 ---------- .../src/asset/components/Row.tsx | 171 ++++---- .../src/asset/components/SideBar.tsx | 28 -- .../src/asset/components/Sidebar.tsx | 90 ++++ .../components/actions/Assign/Article.tsx | 56 +++ .../components/actions/Assign/Assign.tsx | 101 +++++ .../components/actions/Assign/Category.tsx | 118 ++++++ .../asset/components/actions/Assign/Topic.tsx | 107 +++++ .../src/asset/components/actions/Merge.tsx | 193 +++++++++ .../detail}/BasicInfo.tsx | 197 +++++---- .../src/asset/components/detail/Detail.tsx | 63 +++ .../asset/components/detail/LeftSidebar.tsx | 35 ++ .../components/filters/CategoryFilter.tsx | 116 ++++++ .../asset/components/filters/StatusFilter.tsx | 55 +++ .../knowledgebaseFilter/ArticleFilter.tsx | 70 ++++ .../knowledgebaseFilter/AssignmentFilter.tsx | 48 +++ .../KnowledgebaseFilter.tsx | 152 +++++++ .../containers/{Form.tsx => AssetForm.tsx} | 56 ++- .../Form.tsx => containers/CategoryForm.tsx} | 36 +- .../src/asset/containers/List.tsx | 109 +++-- .../List.tsx => containers/Sidebar.tsx} | 78 ++-- .../Assign.tsx} | 59 +-- .../detail}/BasicInfo.tsx | 2 +- .../detail}/CustomFieldSection.tsx | 0 .../detail}/Detail.tsx | 2 +- .../containers/filters/ArticleFilter.tsx | 42 ++ .../filters/KnowledgebaseFilter.tsx | 64 +++ .../src/asset/detail/components/Details.tsx | 59 --- .../asset/detail/components/LeftSideBar.tsx | 39 -- .../src/asset/graphql/mutations.ts | 30 +- .../src/asset/graphql/queries.ts | 75 +++- .../plugin-assets-ui/src/common/constant.ts | 1 + .../plugin-assets-ui/src/common/utils.tsx | 15 +- .../src/movements/containers/Chooser.tsx | 2 +- packages/plugin-assets-ui/src/routes.tsx | 4 +- packages/plugin-assets-ui/src/style.ts | 46 ++- .../productCategory/CategoryList.tsx | 11 +- 55 files changed, 2261 insertions(+), 1869 deletions(-) delete mode 100644 packages/plugin-assets-ui/src/asset/category/components/List.tsx delete mode 100644 packages/plugin-assets-ui/src/asset/category/components/StatusFilter.tsx delete mode 100644 packages/plugin-assets-ui/src/asset/category/graphql/index.ts delete mode 100644 packages/plugin-assets-ui/src/asset/category/graphql/mutations.ts delete mode 100644 packages/plugin-assets-ui/src/asset/category/graphql/queries.ts rename packages/plugin-assets-ui/src/asset/components/{Form.tsx => AssetForm.tsx} (54%) delete mode 100644 packages/plugin-assets-ui/src/asset/components/AssignArticles.tsx rename packages/plugin-assets-ui/src/asset/{category/components/Form.tsx => components/CategoryForm.tsx} (50%) delete mode 100644 packages/plugin-assets-ui/src/asset/components/Merge.tsx delete mode 100644 packages/plugin-assets-ui/src/asset/components/SideBar.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/Sidebar.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/actions/Assign/Article.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/actions/Assign/Assign.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/actions/Assign/Category.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/actions/Assign/Topic.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/actions/Merge.tsx rename packages/plugin-assets-ui/src/asset/{detail/components => components/detail}/BasicInfo.tsx (53%) create mode 100644 packages/plugin-assets-ui/src/asset/components/detail/Detail.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/detail/LeftSidebar.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/filters/CategoryFilter.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/filters/StatusFilter.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/filters/knowledgebaseFilter/ArticleFilter.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/filters/knowledgebaseFilter/AssignmentFilter.tsx create mode 100644 packages/plugin-assets-ui/src/asset/components/filters/knowledgebaseFilter/KnowledgebaseFilter.tsx rename packages/plugin-assets-ui/src/asset/containers/{Form.tsx => AssetForm.tsx} (70%) rename packages/plugin-assets-ui/src/asset/{category/containers/Form.tsx => containers/CategoryForm.tsx} (64%) rename packages/plugin-assets-ui/src/asset/{category/containers/List.tsx => containers/Sidebar.tsx} (54%) rename packages/plugin-assets-ui/src/asset/containers/{AssignArticles.tsx => actions/Assign.tsx} (50%) rename packages/plugin-assets-ui/src/asset/{detail/containers => containers/detail}/BasicInfo.tsx (97%) rename packages/plugin-assets-ui/src/asset/{detail/containers => containers/detail}/CustomFieldSection.tsx (100%) rename packages/plugin-assets-ui/src/asset/{detail/containers => containers/detail}/Detail.tsx (96%) create mode 100644 packages/plugin-assets-ui/src/asset/containers/filters/ArticleFilter.tsx create mode 100644 packages/plugin-assets-ui/src/asset/containers/filters/KnowledgebaseFilter.tsx delete mode 100644 packages/plugin-assets-ui/src/asset/detail/components/Details.tsx delete mode 100644 packages/plugin-assets-ui/src/asset/detail/components/LeftSideBar.tsx mode change 100755 => 100644 packages/plugin-assets-ui/src/routes.tsx diff --git a/packages/core-ui/src/modules/settings/team/components/common/BlockList.tsx b/packages/core-ui/src/modules/settings/team/components/common/BlockList.tsx index 0cdea6c7bf5..47f2e53e4ca 100644 --- a/packages/core-ui/src/modules/settings/team/components/common/BlockList.tsx +++ b/packages/core-ui/src/modules/settings/team/components/common/BlockList.tsx @@ -118,11 +118,11 @@ export default function BlockList(props: Props) { onClick={onClick} queryParams={queryParams} queryParamName={`${linkToText}Id`} - isTeam={true} treeView={true} icon={renderIcon()} editAction={renderEditAction} removeAction={renderRemoveAction} + keyCount="userCount" /> diff --git a/packages/core-ui/src/modules/settings/team/components/unit/MainList.tsx b/packages/core-ui/src/modules/settings/team/components/unit/MainList.tsx index 52f61633ed9..ea4fa70b511 100644 --- a/packages/core-ui/src/modules/settings/team/components/unit/MainList.tsx +++ b/packages/core-ui/src/modules/settings/team/components/unit/MainList.tsx @@ -146,6 +146,7 @@ class MainList extends React.Component { {__(unit?.supervisor?.email)} {__(unit?.department?.title || '')} {unit.userIds?.length || 0} + {unit.userCount} void; @@ -115,45 +115,40 @@ class CollapsibleList extends React.Component { }; renderItemName = (item: any) => { - const { isProductCategory, isTeam } = this.props; + const { keyCount } = this.props; - if (isProductCategory || isTeam) { + if (keyCount) { return ( - {item.code} - {isTeam ? item.title : item.name} - - {isTeam ? item.users.length : item.productCount} - + {item.code} - {item.title || item.name} + {item[keyCount]} ); } - return item.name || '[undefined]'; + return item.title || item.name || '[undefined]'; }; renderItemText = (item: any) => { - const { linkToText } = this.props; + const { onClick } = this.props; - if (linkToText) { - return ( - {this.renderItemName(item)} - ); - } - - return {this.renderItemName(item)}; + return ( + onClick(item._id) : (undefined as any)} + > + {this.renderItemName(item)} + + ); }; renderItem = (item: any, hasChildren: boolean) => { - const { onClick, icon } = this.props; + const { icon } = this.props; const { key } = this.state; const isOpen = this.state.parentIds[item._id] || !!key; return ( - onClick(item._id) : (undefined as any)} - > + {icon && } {this.renderIcons(item, hasChildren, isOpen)} {this.renderItemText(item)} diff --git a/packages/erxes-ui/src/components/filter/Filter.tsx b/packages/erxes-ui/src/components/filter/Filter.tsx index 6431df172ca..6901e0052b8 100644 --- a/packages/erxes-ui/src/components/filter/Filter.tsx +++ b/packages/erxes-ui/src/components/filter/Filter.tsx @@ -173,6 +173,17 @@ function Filter({ queryParams = {}, filterTitle, history }: IProps) { {renderFilterParam('type', false, filterTitle)} {renderFilterParam('action', false, filterTitle)} {renderFilterWithData('userId', 'user', 'details{fullName}, email')} + {renderFilterWithData( + 'assetCategoryId', + 'assetCategory', + '_id, code, name' + )} + {renderFilterWithData( + 'knowledgebaseCategoryId', + 'knowledgeBaseCategory', + '_id, title' + )} + {renderFilterWithData('assetId', 'asset', '_id, code, name')} ); } diff --git a/packages/erxes-ui/src/components/filter/createChipText.tsx b/packages/erxes-ui/src/components/filter/createChipText.tsx index cfbbf234100..bc9caf91422 100644 --- a/packages/erxes-ui/src/components/filter/createChipText.tsx +++ b/packages/erxes-ui/src/components/filter/createChipText.tsx @@ -17,6 +17,9 @@ const ChipText = (props: any) => { const department = query.departmentDetail; const unit = query.unitDetail; const productCategory = query.productCategoryDetail; + const assetCategory = query.assetCategoryDetail; + const asset = query.assetDetail; + const knowledgeBaseCategory = query.knowledgeBaseCategoryDetail; const user = query.userDetail; return ( @@ -30,6 +33,9 @@ const ChipText = (props: any) => { (department && department.title) || (unit && unit.title) || (productCategory && `${productCategory.code} - ${productCategory.name}`) || + (assetCategory && `${assetCategory.code} - ${assetCategory.name}`) || + (asset && `${asset.code} - ${asset.name}`) || + (knowledgeBaseCategory && knowledgeBaseCategory.title) || (user && user.details.fullName) || user.email ); diff --git a/packages/erxes-ui/src/team/graphql/queries.ts b/packages/erxes-ui/src/team/graphql/queries.ts index 8fa886f3d7c..0e4e298372c 100644 --- a/packages/erxes-ui/src/team/graphql/queries.ts +++ b/packages/erxes-ui/src/team/graphql/queries.ts @@ -201,6 +201,7 @@ export const unitField = ` } code userIds + userCount users { _id details { diff --git a/packages/erxes-ui/src/team/types.ts b/packages/erxes-ui/src/team/types.ts index 420161c0179..646aa0b09a0 100644 --- a/packages/erxes-ui/src/team/types.ts +++ b/packages/erxes-ui/src/team/types.ts @@ -99,6 +99,7 @@ export interface IUnit extends IStructureCommon { department: IDepartment; description: string; userIds: string[]; + userCount: number; users: IUser[]; } diff --git a/packages/plugin-assets-ui/src/asset/category/components/List.tsx b/packages/plugin-assets-ui/src/asset/category/components/List.tsx deleted file mode 100644 index abc3113a3f6..00000000000 --- a/packages/plugin-assets-ui/src/asset/category/components/List.tsx +++ /dev/null @@ -1,212 +0,0 @@ -import { SidebarListItem, ActionButtons } from '@erxes/ui-settings/src/styles'; -import { - Box, - Button, - DataWithLoader, - Icon, - ModalTrigger, - SidebarList, - Spinner, - Tip, - __ -} from '@erxes/ui/src'; -import React from 'react'; -import { IAssetCategoryTypes } from '../../../common/types'; -import { ContainerBox } from '../../../style'; -import Form from '../containers/Form'; -import { Link } from 'react-router-dom'; -import AssetStatusFilter from './StatusFilter'; -import { router } from '@erxes/ui/src/utils/core'; - -type Props = { - assetCategories: IAssetCategoryTypes[]; - totalCount: number; - loading: boolean; - remove: (_id) => any; - refetchAssetCategories: () => void; - queryParams: any; - history: any; -}; - -class List extends React.Component { - addFormTrigger = ( - - ); - - renderFormContent = props => { - const { refetchAssetCategories, assetCategories } = this.props; - - const updatedProps = { - ...props, - refetchAssetCategories, - categories: assetCategories - }; - - return
; - }; - - renderAddForm() { - return ( - - ); - } - - renderEditAction(category) { - const trigger = ( - - ); - - const content = props => { - const { refetchAssetCategories, assetCategories } = this.props; - - const updatedProps = { - ...props, - refetchAssetCategories, - category, - categories: assetCategories - }; - - return ; - }; - - return ( - - ); - } - - renderRemoveAction(_id) { - const { remove } = this.props; - - return ( - - ); - } - isActive = (id: string) => { - const { queryParams } = this.props; - const currentCategory = queryParams.categoryId || ''; - - return currentCategory === id; - }; - - renderContent() { - const { assetCategories, loading } = this.props; - - if (loading) { - return ; - } - - const result: React.ReactNode[] = []; - - for (const category of assetCategories) { - const order = category.order; - - const m = order.match(/[/]/gi); - - let space = ''; - - if (m) { - space = '\u00a0\u00a0'.repeat(m.length); - } - const name = category.isRoot ? ( - `${category.name} (${category.assetCount})` - ) : ( - - {category.name} ({category.assetCount}) - - ); - - result.push( - - - {space} - {name} - - - {this.renderEditAction(category)} - {this.renderRemoveAction(category._id)} - - - ); - } - return result; - } - - renderCategoryList() { - const { totalCount, loading } = this.props; - - return ( - - - - ); - } - - clearCategoryFilter = () => { - router.setParams(this.props.history, { categoryId: null }); - }; - - clearSelectedCategoryButton = ( - - ); - - renderAssetCategories() { - return ( - - {this.renderCategoryList()} - - ); - } - - render() { - return ( - - {this.renderAddForm()} - {this.renderAssetCategories()} - - - ); - } -} - -export default List; diff --git a/packages/plugin-assets-ui/src/asset/category/components/StatusFilter.tsx b/packages/plugin-assets-ui/src/asset/category/components/StatusFilter.tsx deleted file mode 100644 index f09f1a2fd79..00000000000 --- a/packages/plugin-assets-ui/src/asset/category/components/StatusFilter.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React from 'react'; -import { withRouter } from 'react-router-dom'; - -import Box from '@erxes/ui/src/components/Box'; -import Icon from '@erxes/ui/src/components/Icon'; -import { FieldStyle, SidebarList } from '@erxes/ui/src/layout/styles'; -import { IRouterProps } from '@erxes/ui/src/types'; -import { router, __ } from '@erxes/ui/src/utils'; -import { assetStatusChoises } from '../../../common/utils'; - -interface IProps extends IRouterProps { - searchable?: boolean; -} - -class AssetStatusFilter extends React.Component { - render() { - const { history } = this.props; - - const onClear = () => { - router.setParams(history, { status: null }); - }; - - const extraButtons = router.getParam(history, 'status') && ( - - - - ); - - const paramKey = 'status'; - - const onClick = (key, value) => { - router.setParams(history, { [key]: value }); - router.setParams(history, { assetId: null }); - }; - - return ( - - - {assetStatusChoises(__).map( - ({ value, label }: { value: string; label: string }) => { - return ( -
  • - - {label} - -
  • - ); - } - )} -
    -
    - ); - } -} - -export default withRouter(AssetStatusFilter); diff --git a/packages/plugin-assets-ui/src/asset/category/graphql/index.ts b/packages/plugin-assets-ui/src/asset/category/graphql/index.ts deleted file mode 100644 index 710d7cb02c9..00000000000 --- a/packages/plugin-assets-ui/src/asset/category/graphql/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import mutations from './mutations'; -import queries from './queries'; - -export { mutations, queries }; diff --git a/packages/plugin-assets-ui/src/asset/category/graphql/mutations.ts b/packages/plugin-assets-ui/src/asset/category/graphql/mutations.ts deleted file mode 100644 index 68a2c2793b3..00000000000 --- a/packages/plugin-assets-ui/src/asset/category/graphql/mutations.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { - assetCategoryParamsDef, - assetCategoryParams -} from '../../../common/graphql/assetCategory'; - -const assetCategoryAdd = ` - mutation assetCategoryAdd(${assetCategoryParamsDef}) { - assetCategoryAdd(${assetCategoryParams}) { - _id - } - } -`; - -const assetCategoryEdit = ` - mutation assetCategoryEdit($_id: String!, ${assetCategoryParamsDef}) { - assetCategoryEdit(_id: $_id, ${assetCategoryParams}) { - _id - } - } -`; -const assetCategoryRemove = ` - mutation assetCategoryRemove($_id: String!) { - assetCategoryRemove(_id: $_id) - } -`; - -export default { assetCategoryAdd, assetCategoryEdit, assetCategoryRemove }; diff --git a/packages/plugin-assets-ui/src/asset/category/graphql/queries.ts b/packages/plugin-assets-ui/src/asset/category/graphql/queries.ts deleted file mode 100644 index 2d734d57779..00000000000 --- a/packages/plugin-assets-ui/src/asset/category/graphql/queries.ts +++ /dev/null @@ -1,69 +0,0 @@ -const assetCategory = ` - query assetCategories($status: String) { - assetCategories(status: $status) { - _id - name - order - code - parentId - description - status - attachment { - name - url - type - size - } - isRoot - assetCount - } - } -`; - -const assetCategoryDetail = ` - query assetCategoryDetail($_id: String) { - assetCategoryDetail(_id: $_id) { - _id - name - assetCount - } - } -`; - -const assetCategoriesTotalCount = ` - query assetCategoriesTotalCount { - assetCategoriesTotalCount - } -`; - -const knowledgeBaseTopics = ` - query knowledgeBaseTopics { - knowledgeBaseTopics { - _id - title - categories { - _id - title - numOfArticles - parentCategoryId - } - } - } -`; -const knowledgeBaseArticles = ` - query knowledgeBaseArticles($categoryIds: [String],$perPage:Int) { - knowledgeBaseArticles(categoryIds: $categoryIds,perPage:$perPage) { - _id - title - categoryId - } - } -`; - -export default { - assetCategory, - assetCategoryDetail, - assetCategoriesTotalCount, - knowledgeBaseArticles, - knowledgeBaseTopics -}; diff --git a/packages/plugin-assets-ui/src/asset/components/Form.tsx b/packages/plugin-assets-ui/src/asset/components/AssetForm.tsx similarity index 54% rename from packages/plugin-assets-ui/src/asset/components/Form.tsx rename to packages/plugin-assets-ui/src/asset/components/AssetForm.tsx index e6df0e162a6..c5da5699e74 100644 --- a/packages/plugin-assets-ui/src/asset/components/Form.tsx +++ b/packages/plugin-assets-ui/src/asset/components/AssetForm.tsx @@ -1,33 +1,41 @@ -import SelectCompanies from '@erxes/ui-contacts/src/companies/containers/SelectCompanies'; import { Button, - ControlLabel, - extractAttachment, Form as CommonForm, + ControlLabel, + FlexContent, + FlexItem, FormControl, FormGroup, ModalTrigger, - Tabs, TabTitle, - Uploader + Tabs, + Uploader, + extractAttachment } from '@erxes/ui/src'; -import EditorCK from '@erxes/ui/src/components/EditorCK'; import { - FormColumn, + CommonFormGroup, + SelectWithAssetCategory, + SelectWithAssets +} from '../../common/utils'; +import { FormColumn, ModalFooter } from '@erxes/ui/src/styles/main'; +import { FormWrapper, - ModalFooter -} from '@erxes/ui/src/styles/main'; + TabContainer, + TabContent, + TriggerTabs +} from '../../style'; +import { IAsset, IAssetCategoryTypes } from '../../common/types'; import { IAttachment, IButtonMutateProps, IFormProps } from '@erxes/ui/src/types'; -import { isEnabled } from '@erxes/ui/src/utils/core'; + +import CategoryForm from '../containers/CategoryForm'; +import EditorCK from '@erxes/ui/src/components/EditorCK'; import React from 'react'; -import { IAsset, IAssetCategoryTypes } from '../../common/types'; -import { SelectWithAssetCategory, SelectWithAssets } from '../../common/utils'; -import { TabContainer, TabContent, TriggerTabs } from '../../style'; -import CategoryForm from '../category/containers/Form'; +import SelectCompanies from '@erxes/ui-contacts/src/companies/containers/SelectCompanies'; +import { isEnabled } from '@erxes/ui/src/utils/core'; type Props = { asset?: IAsset; @@ -36,76 +44,57 @@ type Props = { queryParams: any; renderButton: (props: IButtonMutateProps) => JSX.Element; closeModal: () => void; + loading: boolean; }; -type State = { - assetCount: number; - minimiumCount: number; - attachment?: IAttachment; - attachmentMore?: IAttachment[]; - vendorId: string; - parentId: string; - categoryId: string; - description: string; - currentTab: string; -}; -class Form extends React.Component { - constructor(props) { - super(props); - const asset = props.asset || ({} as IAsset); - const { - attachment, - attachmentMore, - assetCount, - minimiumCount, - vendorId, - parentId, - categoryId, - description - } = asset; - - this.state = { - assetCount: assetCount ? assetCount : 0, - minimiumCount: minimiumCount ? minimiumCount : 0, - attachment: attachment ? attachment : undefined, - attachmentMore: attachmentMore ? attachmentMore : undefined, - vendorId: vendorId ? vendorId : '', - categoryId: categoryId ? categoryId : '', - parentId: parentId ? parentId : '', - description: description ? description : '', - currentTab: parentId ? 'Parent' : 'Category' - }; - this.renderContent = this.renderContent.bind(this); - } +function AssetForm({ + asset, + categories, + queryParams, + renderButton, + closeModal +}: Props) { + const [assetCount, setAssetCount] = React.useState(0); + const [minimiumCount, setMinimiumCount] = React.useState(0); + const [attachment, setAttachment] = React.useState( + undefined + ); + const [attachmentMore, setAttachmentMore] = React.useState< + IAttachment[] | undefined + >(undefined); + const [vendorId, setVendorId] = React.useState(''); + const [parentId, setParentId] = React.useState(''); + const [categoryId, setCategoryId] = React.useState(''); + const [description, setDescription] = React.useState(''); + const [currentTab, setCurrentTab] = React.useState('Category'); + + React.useEffect(() => { + if (asset) { + setAssetCount(asset ? asset.assetCount : 0); + setMinimiumCount(asset ? asset.minimiumCount : 0); + setAttachment(asset ? asset.attachment : undefined); + setAttachmentMore(asset ? asset.attachmentMore : undefined); + setVendorId(asset ? asset.vendorId! : ''); + setParentId(asset ? asset.parentId : ''); + setCategoryId(asset ? asset.categoryId : ''); + setDescription(asset ? asset.description : ''); + setCurrentTab(asset ? (asset.parentId ? 'Parent' : 'Category') : ''); + } + }, []); - generateDoc = (values: { + const generateDoc = (values: { _id?: string; - attachment?: IAttachment; - attachmentMore?: IAttachment[]; assetCount: number; minimiumCount: number; vendorId: string; description: string; }) => { - const { asset } = this.props; const finalValues = values; - const { - attachment, - attachmentMore, - assetCount, - minimiumCount, - vendorId, - description, - parentId, - categoryId - } = this.state; if (asset) { finalValues._id = asset._id; } - finalValues.attachment = attachment; - return { ...finalValues, attachment, @@ -119,9 +108,9 @@ class Form extends React.Component { }; }; - renderFormTrigger(trigger: React.ReactNode) { + const renderFormTrigger = (trigger: React.ReactNode) => { const content = props => ( - + ); return ( @@ -131,48 +120,38 @@ class Form extends React.Component { content={content} /> ); - } - onChangeDescription = e => { - this.setState({ description: e.editor.getData() }); }; - onComboEvent = (variable: string, e) => { - let value = ''; - - switch (variable) { - case 'vendorId': - value = e; - break; - default: - value = e.target.value; - } + const onChangeDescription = e => { + setDescription(e.editor.getData()); + }; - this.setState({ [variable]: value } as any); + const onComboEvent = (variable: string, e) => { + setVendorId(e); }; - onChangeAttachment = (files: IAttachment[]) => { - this.setState({ attachment: files.length ? files[0] : undefined }); + + const onChangeAttachment = (files: IAttachment[]) => { + setAttachment(files.length ? files[0] : undefined); }; - onChangeAttachmentMore = (files: IAttachment[]) => { - this.setState({ attachmentMore: files ? files : undefined }); + const onChangeAttachmentMore = (files: IAttachment[]) => { + setAttachmentMore(files ? files : undefined); }; - onChangeCurrentTab = selecteTab => { + const onChangeCurrentTab = selecteTab => { switch (selecteTab) { case 'Parent': - this.setState({ categoryId: '', currentTab: selecteTab }); + setCategoryId(''); + setCurrentTab(selecteTab); break; case 'Category': - this.setState({ parentId: '', currentTab: selecteTab }); + setParentId(''); + setCurrentTab(selecteTab); break; } }; - renderContent(formProps: IFormProps) { - const { asset, queryParams, closeModal, renderButton } = this.props; - - const { description, vendorId } = this.state; - + const renderContent = (formProps: IFormProps) => { const { values, isSubmitted } = formProps; const object = asset || ({} as IAsset); @@ -190,10 +169,15 @@ class Form extends React.Component { ); const currentTabItem = () => { - const { currentTab } = this.state; - const handleSelect = (value, name) => { - this.setState({ [name]: value } as Pick); + switch (name) { + case 'parentId': + setParentId(value); + break; + case 'categoryId': + setCategoryId(value); + break; + } }; if (currentTab === 'Parent') { @@ -226,17 +210,15 @@ class Form extends React.Component { Category - - - - {this.renderFormTrigger(addCategoryTrigger)} + + {renderFormTrigger(addCategoryTrigger)} ); @@ -256,24 +238,44 @@ class Form extends React.Component { required={true} /> + + + Code +

    + Depending on your business type, you may type in a barcode or + any other UPC (Universal Asset Code). If you don't use UPC, type + in any numeric value to differentiate your assets. +

    + +
    + + Vendor + - Unit price -

    - Please ensure you have set the default currency in the{' '} - {'General Settings'} of the - System Configuration. -

    +
    + Unit price +

    + Please ensure you have set the default currency in the{' '} + {'General Settings'} of the + System Configuration. +

    +
    { />
    - - - Code -

    - Depending on your business type, you may type in a barcode or - any other UPC (Universal Asset Code). If you don't use UPC, type - in any numeric value to differentiate your assets. -

    - -
    -
    + - + {['Category', 'Parent'].map(item => ( {item} @@ -317,52 +304,56 @@ class Form extends React.Component { {currentTabItem()} + + + Description + + + + + - - - Description - - - Featured image + + Secondary Images @@ -382,7 +373,7 @@ class Form extends React.Component { {renderButton({ text: 'asset and movements', - values: this.generateDoc(values), + values: generateDoc(values), isSubmitted, callback: closeModal, object: asset @@ -390,11 +381,9 @@ class Form extends React.Component { ); - } + }; - render() { - return ; - } + return ; } -export default Form; +export default AssetForm; diff --git a/packages/plugin-assets-ui/src/asset/components/AssignArticles.tsx b/packages/plugin-assets-ui/src/asset/components/AssignArticles.tsx deleted file mode 100644 index 1938debc6b5..00000000000 --- a/packages/plugin-assets-ui/src/asset/components/AssignArticles.tsx +++ /dev/null @@ -1,292 +0,0 @@ -import Button from '@erxes/ui/src/components/Button'; -import { Column, FormWrapper, ModalFooter } from '@erxes/ui/src/styles/main'; -import { __, categories } from '@erxes/ui/src/utils'; -import React from 'react'; -import { IAsset } from '../../common/types'; -import { - KbArticles, - KbArticlesContainer, - KbCategories, - SelectAssignType, - TriggerTabs -} from '../../style'; -import { - ControlLabel, - EmptyState, - FormControl, - TabTitle, - Tabs -} from '@erxes/ui/src'; -import { ContainerBox } from '../../style'; - -type Props = { - objects?: IAsset[]; - kbTopics: any[]; - loadArticles: (categoryId: string) => void; - loadedArticles: any[]; - save: (doc: { ids: string[]; data: any; callback: () => void }) => void; - closeModal: () => void; - selectedArticleIds?: string[]; -}; - -type State = { - action: string; - topicId: string; - categoriesToShow: string[]; - selectedArticleIds: string[]; -}; - -class AssignArticles extends React.Component { - constructor(props) { - super(props); - - this.state = { - action: 'add', - topicId: '', - categoriesToShow: [], - selectedArticleIds: props?.selectedArticleIds || [] - }; - } - - componentDidMount() { - if (!this.state?.topicId && this.props?.kbTopics?.length) { - const topic = this.props?.kbTopics[0] || {}; - this.selectTopic(topic); - } - } - - save = (e: React.FormEvent) => { - e.preventDefault(); - - const { selectedArticleIds, action } = this.state; - const { objects } = this.props; - - this.props.save({ - ids: (objects || []).map(asset => asset._id), - data: { - action, - articleIds: selectedArticleIds - }, - callback: () => { - this.setState({ - action, - selectedArticleIds: this.props.selectedArticleIds || [] - }); - this.props.closeModal(); - } - }); - }; - - selectTopic(topic) { - const { loadArticles } = this.props; - - const categoryIds = (topic?.categories || []).map(category => category._id); - - loadArticles(categoryIds); - - this.setState({ topicId: topic._id }); - } - - renderCategories() { - const { topicId, selectedArticleIds, categoriesToShow } = this.state; - const { kbTopics, loadedArticles } = this.props; - - if (!topicId) { - return; - } - - const { categories } = kbTopics.find(topic => topic._id === topicId) || {}; - - if (!categories?.length) { - return ( - - ); - } - - const selectAllArticles = categoryId => { - const articleIds = loadedArticles - .filter(article => article.categoryId === categoryId) - .map(article => article._id); - - if ( - articleIds.every(articleId => selectedArticleIds.includes(articleId)) - ) { - const updatedSelectedArticleIds = selectedArticleIds.filter( - articleId => !articleIds.includes(articleId) - ); - return this.setState({ selectedArticleIds: updatedSelectedArticleIds }); - } - - this.setState({ - selectedArticleIds: [...selectedArticleIds, ...articleIds] - }); - }; - - return categories.map(cat => { - const onClick = () => { - if (categoriesToShow.includes(cat._id)) { - const updateCategoryIds = categoriesToShow.filter( - categoryId => categoryId !== cat._id - ); - return this.setState({ categoriesToShow: updateCategoryIds }); - } - - this.setState({ categoriesToShow: [...categoriesToShow, cat._id] }); - }; - - const articleIds = loadedArticles - .filter(article => article.categoryId === cat._id) - .map(article => article._id); - - const checked = - !!articleIds?.length && - articleIds.every(articleId => selectedArticleIds.includes(articleId)); - - const countArticles = - articleIds.filter(articleId => selectedArticleIds.includes(articleId)) - ?.length || 0; - - return ( - <> - - - - - -
    {cat.title}
    -
    -
    -

    {`${countArticles}/${cat.numOfArticles}`}

    -
    -
    - {categoriesToShow.includes(cat._id) && - this.renderLoadedArticles(cat._id)} - - ); - }); - } - - renderTopics() { - const { kbTopics } = this.props; - const { topicId } = this.state; - return ( - <> - - - {kbTopics.map(topic => ( - - {topic.title} - - ))} - - - {this.renderCategories()} - - ); - } - - renderLoadedArticles(categoryId) { - const { loadedArticles } = this.props; - - const articles = loadedArticles.filter( - article => article.categoryId === categoryId - ); - - if (!articles?.length) { - return ( - - ); - } - - return ( - - {articles.map(article => { - const { selectedArticleIds } = this.state; - const onClick = () => { - const articleId = article._id; - - if (selectedArticleIds.includes(articleId)) { - const index = selectedArticleIds.indexOf(articleId); - selectedArticleIds.splice(index, 1); - } else { - selectedArticleIds.push(articleId); - } - - this.setState({ selectedArticleIds }); - }; - - return ( - - - - {article.title} - - - ); - })} - - ); - } - - render() { - const { closeModal, objects, selectedArticleIds } = this.props; - - const onChangeAction = e => { - const { value } = e.currentTarget as HTMLInputElement; - - this.setState({ action: value }); - }; - - return ( - - {this.renderTopics()} - - - - {!!objects?.length && !selectedArticleIds?.length && ( - - - - - )} - - - - - - - - - - - ); - } -} - -export default AssignArticles; diff --git a/packages/plugin-assets-ui/src/asset/category/components/Form.tsx b/packages/plugin-assets-ui/src/asset/components/CategoryForm.tsx similarity index 50% rename from packages/plugin-assets-ui/src/asset/category/components/Form.tsx rename to packages/plugin-assets-ui/src/asset/components/CategoryForm.tsx index fde55ce795f..890a442b26f 100644 --- a/packages/plugin-assets-ui/src/asset/category/components/Form.tsx +++ b/packages/plugin-assets-ui/src/asset/components/CategoryForm.tsx @@ -1,23 +1,22 @@ -import { Button, FormControl, Uploader } from '@erxes/ui/src'; -import CommonForm from '@erxes/ui/src/components/form/Form'; +import { Button, FormControl, Uploader, __ } from '@erxes/ui/src'; +import { CommonFormGroup, SelectWithAssetCategory } from '../../common/utils'; import { FormColumn, FormWrapper, ModalFooter } from '@erxes/ui/src/styles/main'; +import { IAssetCategory, IAssetCategoryTypes } from '../../common/types'; import { IAttachment, IButtonMutateProps, IFormProps } from '@erxes/ui/src/types'; -import { extractAttachment } from '@erxes/ui/src/utils/core'; + +import { ASSET_CATEGORY_STATUSES } from '../../common/constant'; +import CommonForm from '@erxes/ui/src/components/form/Form'; import React from 'react'; -import { ASSET_CATEGORY_STATUSES } from '../../../common/constant'; -import { IAssetCategory, IAssetCategoryTypes } from '../../../common/types'; -import { - CommonFormGroup, - generateCategoryOptions -} from '../../../common/utils'; +import Select from 'react-select-plus'; +import { extractAttachment } from '@erxes/ui/src/utils/core'; type Props = { renderButton: (props: IButtonMutateProps) => JSX.Element; @@ -26,36 +25,41 @@ type Props = { categories: IAssetCategoryTypes[]; }; -class Form extends React.Component { - constructor(props) { - super(props); - - const category = props.category || ({} as IAssetCategory); - const attachment = category.attachment || undefined; - this.state = { - attachment - }; - - this.renderForm = this.renderForm.bind(this); - } - - generateDocs(values) { - const { category } = this.props; +function CategoryForm({ + renderButton, + closeModal, + category, + categories +}: Props) { + const [attachment, setAttachment] = React.useState( + undefined + ); + const [status, setStatus] = React.useState(''); + const [parentId, setParentId] = React.useState(''); + + React.useEffect(() => { + if (category) { + setStatus(category.status || ''); + setParentId(category.parentId || ''); + } + }, []); + const generateDocs = values => { const finalValues = values; if (category) { finalValues._id = category._id; } - return { ...finalValues }; - } + return { ...finalValues, attachment, status, parentId }; + }; - onChangeAttachment = (files: IAttachment[]) => { - this.setState({ attachment: files ? files[0] : undefined }); + const onChangeAttachment = (files: IAttachment[]) => { + const file = files ? files[0] : undefined; + setAttachment(file); }; - renderForm(formProps: IFormProps) { - const { renderButton, closeModal, category, categories } = this.props; + + const renderForm = (formProps: IFormProps) => { const { isSubmitted, values } = formProps; const object = category || ({} as IAssetCategory); @@ -65,20 +69,22 @@ class Form extends React.Component { return ( <> - + - + @@ -93,37 +99,37 @@ class Form extends React.Component { - setStatus(option.value)} + {...formProps} /> - - + setParentId(value as string)} + customOption={{ value: '', label: 'Choose Asset Category' }} + {...formProps} /> - - - + + @@ -133,7 +139,7 @@ class Form extends React.Component { {renderButton({ text: 'Asset Category', - values: this.generateDocs(values), + values: generateDocs(values), isSubmitted, callback: closeModal, object: category @@ -141,11 +147,9 @@ class Form extends React.Component { ); - } + }; - render() { - return ; - } + return ; } -export default Form; +export default CategoryForm; diff --git a/packages/plugin-assets-ui/src/asset/components/List.tsx b/packages/plugin-assets-ui/src/asset/components/List.tsx index 4d499f5645d..7d9d015c94b 100644 --- a/packages/plugin-assets-ui/src/asset/components/List.tsx +++ b/packages/plugin-assets-ui/src/asset/components/List.tsx @@ -1,30 +1,28 @@ +import { BarItems, Wrapper } from '@erxes/ui/src/layout'; +import React from 'react'; +import { IAsset, IAssetCategory } from '../../common/types'; +import { breadcrumb } from '../../common/constant'; +import { FlexItem, InputBar, Title } from '@erxes/ui-settings/src/styles'; import { - BarItems, - Button, - FormControl, - ModalTrigger, - router, - Table, __, + router, confirm, - Alert, - Tip, - Icon + Table, + FormControl, + Pagination, + DataWithLoader, + Button, + ModalTrigger, + Icon, + Alert } from '@erxes/ui/src'; -import React from 'react'; -import { IAsset, IAssetCategory } from '../../common/types'; -import { DefaultWrapper } from '../../common/utils'; -import Form from '../containers/Form'; import Row from './Row'; -import SideBar from './SideBar'; import { Link } from 'react-router-dom'; -import * as _loadash from 'lodash'; -import MergeAsset from './Merge'; -import { breadcrumb } from '../../common/constant'; -import { Title } from '@erxes/ui/src/styles/main'; -import { ContainerBox } from '../../style'; -import AssignArticles from '../containers/AssignArticles'; +import AssetForm from '../containers/AssetForm'; import { isEnabled } from '@erxes/ui/src/utils/core'; +import MergeAssets from './actions/Merge'; +import AssignArticles from '../containers/actions/Assign'; +import Sidebar from '../containers/Sidebar'; type Props = { assets: IAsset[]; @@ -49,95 +47,81 @@ type Props = { mergeAssetLoading; }; -type State = { - searchValue?: string; -}; - -class List extends React.Component { - private timer?: NodeJS.Timer; +function List(props: Props) { + const { + assets, + assetsCount, + history, + queryParams, + isAllSelected, + bulk, + emptyBulk, + remove, + assignKbArticles, + toggleBulk, + toggleAll, + loading, + searchValue, + currentCategory, + currentParent, + mergeAssets, + mergeAssetLoading + } = props; + + const [search, setSearch] = React.useState(searchValue); + const timerRef = React.useRef(null); + + React.useEffect(() => { + emptyBulk(); + }, [assets.length]); + + const handleSearch = e => { + if (timerRef.current) { + clearTimeout(timerRef.current); + } - constructor(props) { - super(props); - this.state = { - searchValue: this.props.searchValue - }; - } + const value = e.target.value; + setSearch(value); - renderRightActionBarTrigger = ( - - ); + timerRef.current = window.setTimeout(() => { + router.setParams(history, { searchValue: value }); + router.removeParams(history, 'page'); + }, 500); + }; - renderFormContent = props => { - return
    ; + const handleSelectAllChange = () => { + toggleAll(assets, 'assets'); }; - renderRightActionBar = ( - - ); + const moveCursorAtTheEnd = e => { + const tmpValue = e.target.value; - renderRow() { - const { assets, history, toggleBulk, bulk, assignKbArticles } = this.props; + e.target.value = ''; + e.target.value = tmpValue; + }; + const renderRow = () => { return assets.map(asset => ( )); - } - - onChange = () => { - const { toggleAll, assets } = this.props; - toggleAll(assets, 'assets'); }; - renderContent = () => { - const { isAllSelected } = this.props; - - return ( - - - - - - - - - - - - - {this.renderRow()} -
    - - {__('Code')}{__('Name')}{__('Category')}{__('Parent')}{__('Unit Price')}{__('Actions')}
    - ); + const renderFormContent = formProps => { + return ; }; - assetsMerge = props => { - const { bulk, mergeAssets, mergeAssetLoading } = this.props; - + const assetsMerge = assetsProps => { return ( - { ); }; - assignArticles = props => { - const { bulk, assignKbArticles } = this.props; - - return ; - }; - - search = e => { - if (this.timer) { - clearTimeout(this.timer); - } - - const { history } = this.props; - const searchValue = e.target.value; - - this.setState({ searchValue }); - - this.timer = setTimeout(() => { - router.removeParams(history, 'page'); - router.setParams(history, { searchValue }); - }, 500); - }; - - moveCursorAtTheEnd(e) { - const tmpValue = e.target.value; - - e.target.value = ''; - e.target.value = tmpValue; - } - - removeAssets = assets => { - const assetIds: string[] = []; - - assets.forEach(asset => { - assetIds.push(asset._id); - }); - - this.props.remove({ assetIds }, this.props.emptyBulk); + const assignArticles = articlesProps => { + return ( + + ); }; - assignKbArticles = assets => { + const removeAssets = selectedAssets => { const assetIds: string[] = []; - assets.forEach(asset => { - assetIds.push(asset._id); + selectedAssets.forEach(selectedAsset => { + assetIds.push(selectedAsset._id); }); - this.props.assignKbArticles({ assetIds }, this.props.emptyBulk); + remove({ assetIds }, emptyBulk); }; - render() { - const { - bulk, - queryParams, - assetsCount, - currentCategory, - currentParent, - history - } = this.props; - - let rightActionBar = ( - - - - - - - - {this.renderRightActionBar} - - ); - + const rightActionBar = () => { if (bulk.length > 0) { const onClick = () => { confirm() .then(() => { - this.removeAssets(bulk); + removeAssets(bulk); }) .catch(error => { Alert.error(error.message); @@ -237,85 +162,141 @@ class List extends React.Component { }; const mergeButton = ( - ); const assignButton = ( - ); - rightActionBar = ( + return ( {bulk.length === 2 && ( )} - - {isEnabled('knowledgebase') && ( )} + + ); } - const handleClearParams = type => { - router.setParams(history, { [`${type}Id`]: null }); - }; + return ( + + + + + + + - const clearButton = type => ( - - ); + + + - const leftActionBar = ( - - - {currentCategory.name || currentParent.name || 'All Assets'} - - {!_loadash.isEmpty(currentCategory) && clearButton('category')} - {!_loadash.isEmpty(currentParent) && clearButton('parent')} - + + Add Assets + + } + content={renderFormContent} + autoOpenKey="showListFormModal" + dialogClassName="transform" + size="lg" + /> + ); + }; + + const content = ( + + + + + + + + + + + + + {renderRow()} +
    + + {__('Code')}{__('Name')}{__('Category')}{__('Parent')}{__('Unit Price')}{__('Actions')}
    + ); - const updatedProps = { - title: 'List Assets', - rightActionBar, - leftActionBar, - content: this.renderContent(), - sidebar: , - totalCount: assetsCount, - breadcrumb: breadcrumb - }; + const sidebar = ; - return ; - } + const leftActionBar = ( + {`${currentCategory.name || + currentParent.name || + 'All Assets'} (${assetsCount})`} + ); + + return ( + + } + actionBar={ + + } + content={ + + } + leftSidebar={sidebar} + transparent={true} + hasBorder={true} + footer={} + /> + ); } export default List; diff --git a/packages/plugin-assets-ui/src/asset/components/Merge.tsx b/packages/plugin-assets-ui/src/asset/components/Merge.tsx deleted file mode 100644 index 7731013eb42..00000000000 --- a/packages/plugin-assets-ui/src/asset/components/Merge.tsx +++ /dev/null @@ -1,212 +0,0 @@ -import Button from '@erxes/ui/src/components/Button'; -import { SmallLoader } from '@erxes/ui/src/components/ButtonMutate'; -import Icon from '@erxes/ui/src/components/Icon'; -import { Column, Columns, Title } from '@erxes/ui/src/styles/chooser'; -import { ModalFooter } from '@erxes/ui/src/styles/main'; -import { __ } from '@erxes/ui/src/utils'; -import React from 'react'; -import { ASSET_INFO } from '../../common/constant'; -import { InfoDetail } from '../../style'; -import { Info, InfoTitle } from '@erxes/ui/src/styles/main'; -import { IAsset, IAssetDoc as IAssetDocc } from '../../common/types'; - -type IAssetDoc = IAssetDocc & {}; - -type Props = { - objects: IAsset[]; - mergeAssetLoading: boolean; - save: (doc: { ids: string[]; data: any; callback: () => void }) => void; - closeModal: () => void; -}; - -type State = { - selectedValues: any; -}; - -class AssetsMerge extends React.Component { - constructor(props) { - super(props); - - this.state = { - selectedValues: {} - }; - } - - save = (e: React.FormEvent) => { - e.preventDefault(); - const { objects } = this.props; - const selectedValues = { ...this.state.selectedValues }; - - if (selectedValues.category) { - selectedValues.categoryId = selectedValues.category._id; - } - - if (selectedValues.parent) { - selectedValues.parentId = selectedValues.parent._id; - } - - if (selectedValues.vendor) { - selectedValues.vendorId = selectedValues.vendor._id; - } - - this.props.save({ - ids: objects.map(asset => asset._id), - data: { ...selectedValues }, - callback: () => { - this.props.closeModal(); - } - }); - }; - - handleChange = (type: string, key: string, value: string) => { - const selectedValues = { ...this.state.selectedValues }; - - if (type === 'plus-1') { - if (key === 'parent') { - delete selectedValues.category; - } - if (key === 'category') { - delete selectedValues.parent; - } - - selectedValues[key] = value; - - if (key === 'links') { - const links = Object.assign( - { ...this.state.selectedValues.links }, - value - ); - selectedValues[key] = links; - } - } else { - delete selectedValues[key]; - } - - this.setState({ selectedValues }); - }; - - renderAsset = (asset: IAssetDoc, icon: string) => { - const properties = ASSET_INFO.ALL; - - return ( - - {asset.name} -
      - {properties.map(info => { - const key = info.field; - - if (!asset[key]) { - return null; - } - - return this.renderAssetProperties(key, asset[key], icon); - })} -
    -
    - ); - }; - - renderAssetProperties(key: string, value: string, icon: string) { - return ( -
  • - {this.renderTitle(key)} - {this.renderValue(key, value)} - -
  • - ); - } - - renderTitle(key: string) { - const title = ASSET_INFO[key]; - - return {title}:; - } - - renderValue(field: string, value: any) { - switch (field) { - case 'category': - return this.renderCategoryInfo(value); - - case 'parent': - return this.renderParentInfo(value); - - case 'vendor': - return this.renderVendorInfo(value); - - default: - return {value}; - } - } - - renderCategoryInfo(value) { - return ( - - {__('Name')}: - {value.name} - - ); - } - - renderParentInfo(value) { - return ( - - {__('Name')} - {value.name} - - ); - } - - renderVendorInfo(value) { - return ( - - {__('Info')}: - - {value.primaryName || - value.primaryEmail || - value.primaryPhone || - value.code} - - - ); - } - - render() { - const { selectedValues } = this.state; - const { objects, closeModal, mergeAssetLoading } = this.props; - - const [asset1, asset2] = objects; - - return ( - - - - {this.renderAsset(asset1, 'plus-1')} - - - - {this.renderAsset(asset2, 'plus-1')} - - - {this.renderAsset(selectedValues, 'times')} - - - - - - - - ); - } -} - -export default AssetsMerge; diff --git a/packages/plugin-assets-ui/src/asset/components/Row.tsx b/packages/plugin-assets-ui/src/asset/components/Row.tsx index 4e7663a9ed2..42a4a7486b1 100644 --- a/packages/plugin-assets-ui/src/asset/components/Row.tsx +++ b/packages/plugin-assets-ui/src/asset/components/Row.tsx @@ -1,17 +1,20 @@ import React from 'react'; +import { IAsset } from '../../common/types'; import { - ModalTrigger, - Icon, - FormControl, Button, + FormControl, + Icon, + ModalTrigger, Tip, - router + router, + __, + ActionButtons } from '@erxes/ui/src'; -import { IAsset } from '../../common/types'; -import AssetForm from '../containers/Form'; -import { MoreContainer, Badge, ContainerBox } from '../../style'; -import AssignArticles from '../containers/AssignArticles'; +import { Badge, ContainerBox, MoreContainer } from '../../style'; import { isEnabled } from '@erxes/ui/src/utils/core'; +import AssetForm from '../containers/AssetForm'; +import AssignArticles from '../containers/actions/Assign'; + type Props = { asset: IAsset; history: any; @@ -24,17 +27,22 @@ type Props = { ) => void; }; -class Row extends React.Component { - constructor(props) { - super(props); - } +function Row(props: Props) { + const { + asset, + history, + queryParams, + isChecked, + toggleBulk, + assignKbArticles + } = props; - renderKbAssignForm() { - const { asset, assignKbArticles, queryParams } = this.props; + const { code, name, category, parent, childAssetCount, unitPrice } = asset; - const content = props => ( + const renderKbAssignForm = () => { + const articleContent = articleProps => ( { /> ); - const trigger = ; + const trigger = ( + + ); return ( { size="lg" dialogClassName="modal-1000w" trigger={trigger} - content={content} + content={articleContent} /> ); - } - render() { - const { asset, history, queryParams, toggleBulk, isChecked } = this.props; - - const onChange = e => { - if (toggleBulk) { - toggleBulk(asset, e.target.checked); - } - }; + }; - const onClick = e => { - e.stopPropagation(); - }; + const onRowClick = () => { + history.push(`/settings/assets/detail/${asset._id}`); + }; - const onTrClick = () => { - history.push(`/settings/assets/detail/${asset._id}`); - }; + const onCellClick = e => { + e.stopPropagation(); + }; - const handleParent = () => { - if (queryParams.categoryId) { - router.removeParams(history, 'categoryId'); - } - router.setParams(history, { parentId: this.props.asset._id }); - }; + const onChange = e => { + if (toggleBulk) { + toggleBulk(asset, e.target.checked); + } + }; - const content = props => ; + const handleParent = () => { + if (queryParams.categoryId) { + router.removeParams(history, 'categoryId'); + } + router.setParams(history, { assetId: asset._id }); + }; - const { code, name, category, parent, childAssetCount, unitPrice } = asset; + const content = formProps => ; - return ( - - - + + + + {code} + {name} + {category ? category.name : ''} + {parent ? parent.name : ''} + {(unitPrice || 0).toLocaleString()} + + + {childAssetCount > 0 && ( + + )} + {isEnabled('knowledgebase') && renderKbAssignForm()} + + + + + + } + size="lg" + content={content} /> - - {code} - {name} - {category ? category.name : ''} - {parent ? parent.name : ''} - {(unitPrice || 0).toLocaleString()} - - - {childAssetCount > 0 && ( - - - {childAssetCount} - - )} - {isEnabled('knowledgebase') && this.renderKbAssignForm()} - } - enforceFocus={false} - size="lg" - content={content} - /> - - - - ); - } + + + + ); } + export default Row; diff --git a/packages/plugin-assets-ui/src/asset/components/SideBar.tsx b/packages/plugin-assets-ui/src/asset/components/SideBar.tsx deleted file mode 100644 index c0eec3dc01c..00000000000 --- a/packages/plugin-assets-ui/src/asset/components/SideBar.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { Sidebar as CommonSideBar } from '@erxes/ui/src'; -import React from 'react'; -import { ContainerBox } from '../../style'; -import CategoryListContainer from '../category/containers/List'; -import SelectKbArticles from '../../common/SectionKB'; -import { isEnabled } from '@erxes/ui/src/utils/core'; -type Props = { - queryParams: any; - history: any; -}; - -class SideBar extends React.Component { - constructor(props) { - super(props); - } - - render() { - return ( - - - - {isEnabled('knowledgebase') && } - - - ); - } -} -export default SideBar; diff --git a/packages/plugin-assets-ui/src/asset/components/Sidebar.tsx b/packages/plugin-assets-ui/src/asset/components/Sidebar.tsx new file mode 100644 index 00000000000..62e1bd6f7a4 --- /dev/null +++ b/packages/plugin-assets-ui/src/asset/components/Sidebar.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { Wrapper } from '@erxes/ui/src/layout'; +import Button from '@erxes/ui/src/components/Button'; +import { Header } from '@erxes/ui-settings/src/styles'; +import ModalTrigger from '@erxes/ui/src/components/ModalTrigger'; +import StatusFilter from './filters/StatusFilter'; +import KnowledgebaseFilter from '../containers/filters/KnowledgebaseFilter'; +import { isEnabled } from '@erxes/ui/src/utils/core'; +import CategoryForm from '../containers/CategoryForm'; +import { IAssetCategoryTypes } from '../../common/types'; +import CategoryFilter from './filters/CategoryFilter'; + +type Props = { + assetCategories: IAssetCategoryTypes[]; + totalCount: number; + loading: boolean; + remove: (_id) => any; + refetchAssetCategories: () => void; + queryParams: any; + history: any; +}; + +function Sidebar({ + assetCategories, + totalCount, + loading, + remove, + refetchAssetCategories, + queryParams, + history +}: Props) { + const trigger = ( + + ); + + const content = props => { + const updatedProps = { + ...props, + refetchAssetCategories, + categories: assetCategories + }; + + return ; + }; + + const header = ( +
    + +
    + ); + + const renderCategoryFilter = () => { + const updatedProps = { + assetCategories, + totalCount, + loading, + remove, + refetchAssetCategories, + queryParams, + history + }; + + return ; + }; + + const renderStatusFilter = () => { + return ; + }; + + const renderKnowledgebaseFilter = () => { + return ; + }; + + return ( + + {renderCategoryFilter()} + {renderStatusFilter()} + {isEnabled('knowledgebase') && renderKnowledgebaseFilter()} + + ); +} + +export default Sidebar; diff --git a/packages/plugin-assets-ui/src/asset/components/actions/Assign/Article.tsx b/packages/plugin-assets-ui/src/asset/components/actions/Assign/Article.tsx new file mode 100644 index 00000000000..2435512e654 --- /dev/null +++ b/packages/plugin-assets-ui/src/asset/components/actions/Assign/Article.tsx @@ -0,0 +1,56 @@ +import { __ } from '@erxes/ui/src/utils'; +import React from 'react'; +import { IAsset } from '../../../../common/types'; +import { KbArticles } from '../../../../style'; +import { FormControl } from '@erxes/ui/src'; +import { ContainerBox } from '../../../../style'; + +type Props = { + objects?: IAsset[]; + kbTopics: any[]; + loadArticles: (categoryId: string) => void; + loadedArticles: any[]; + save: (doc: { ids: string[]; data: any; callback: () => void }) => void; + closeModal: () => void; + selectedArticleIds?: string[]; + article: any; + selectedArticles: string[]; + setSelectedArticles: (articleIds: string[]) => void; +}; + +function Article({ + objects, + article, + selectedArticles, + setSelectedArticles +}: Props) { + const handleArticleSelect = articleId => { + const newSelectedArticles = [...selectedArticles]; + + if (newSelectedArticles.includes(articleId)) { + const index = newSelectedArticles.indexOf(articleId); + newSelectedArticles.splice(index, 1); + } else { + newSelectedArticles.push(articleId); + } + + setSelectedArticles(newSelectedArticles); + }; + + return ( + + + + handleArticleSelect(article._id)} + /> + {article.title} + + + + ); +} + +export default Article; diff --git a/packages/plugin-assets-ui/src/asset/components/actions/Assign/Assign.tsx b/packages/plugin-assets-ui/src/asset/components/actions/Assign/Assign.tsx new file mode 100644 index 00000000000..8307b9cb67d --- /dev/null +++ b/packages/plugin-assets-ui/src/asset/components/actions/Assign/Assign.tsx @@ -0,0 +1,101 @@ +import Button from '@erxes/ui/src/components/Button'; +import { Column, FormWrapper, ModalFooter } from '@erxes/ui/src/styles/main'; +import { __ } from '@erxes/ui/src/utils'; +import React from 'react'; +import { IAsset } from '../../../../common/types'; +import Select from 'react-select-plus'; +import Topic from './Topic'; +import { Formgroup } from '@erxes/ui/src/components/form/styles'; +import { SelectAssignType } from '../../../../style'; + +export const ASSIGN_TYPE = [ + { label: 'Add', value: 'add' }, + { label: 'Subtract', value: 'subtract' } +]; + +type Props = { + objects?: IAsset[]; + kbTopics: any[]; + loadArticles: (categoryId: string) => void; + loadedArticles: any[]; + save: (doc: { ids: string[]; data: any; callback: () => void }) => void; + closeModal: () => void; + selectedArticleIds?: string[]; +}; + +function AssignArticles(props: Props) { + const { objects, kbTopics, save, closeModal, selectedArticleIds } = props; + + const [assignType, setAssignType] = React.useState('add'); + const [selectedArticles, setSelectedArticles] = React.useState( + selectedArticleIds || [] + ); + + const onSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + save({ + ids: (objects || []).map(asset => asset._id), + data: { + action: assignType, + articleIds: selectedArticles + }, + callback: () => { + setAssignType(assignType); + setSelectedArticles(selectedArticleIds || []); + closeModal(); + } + }); + }; + + const renderTopics = () => { + return kbTopics.map(topic => { + const updatedProps = { + ...props, + topic, + selectedArticles, + setSelectedArticles + }; + return ; + }); + }; + + const onChangeAction = option => { + setAssignType(option.value); + }; + + return ( +
    + {renderTopics()} + + + + {!!objects?.length && !selectedArticleIds?.length && ( + +