From ddb2395ef9ebe3aa1206dafd4a86c81dc59fa50a Mon Sep 17 00:00:00 2001 From: "munkhsaikhan.g@nmma.co" Date: Wed, 20 Sep 2023 13:50:28 +0800 Subject: [PATCH 01/50] clean timeclock --- .github/workflows/plugin-timeclock-api.yaml | 4 ++-- .github/workflows/plugin-timeclock-ui.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/plugin-timeclock-api.yaml b/.github/workflows/plugin-timeclock-api.yaml index 5c2df7ee74..d6f88d7084 100644 --- a/.github/workflows/plugin-timeclock-api.yaml +++ b/.github/workflows/plugin-timeclock-api.yaml @@ -62,5 +62,5 @@ jobs: run: | cd dist/plugin-timeclock-api/.erxes echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin - docker build -t erxes/plugin-timeclock-api:${GITHUB_REF#refs/heads/} -f Dockerfile . - docker push erxes/plugin-timeclock-api:${GITHUB_REF#refs/heads/} + docker build -t erxes/plugin-timeclock-api:community -f Dockerfile . + docker push erxes/plugin-timeclock-api:community diff --git a/.github/workflows/plugin-timeclock-ui.yaml b/.github/workflows/plugin-timeclock-ui.yaml index 9fc73399b0..cc982bb43b 100644 --- a/.github/workflows/plugin-timeclock-ui.yaml +++ b/.github/workflows/plugin-timeclock-ui.yaml @@ -84,4 +84,4 @@ jobs: tar -cf build.tar --directory=packages/plugin-timeclock-ui/.erxes/dist . cp build.tar packages/plugin-timeclock-ui/.erxes/dist rm -rf packages/plugin-timeclock-ui/.erxes/dist/*.js - aws s3 sync packages/plugin-timeclock-ui/.erxes/dist s3://erxes-${GITHUB_REF#refs/heads/}-plugins/uis/plugin-timeclock-ui --delete + aws s3 sync packages/plugin-timeclock-ui/.erxes/dist s3://erxes-community-plugins/uis/plugin-timeclock-ui --delete From 7fd22845fc8f4b7ae3c96c4a045bd16d0f7bbd47 Mon Sep 17 00:00:00 2001 From: "munkhsaikhan.g@nmma.co" Date: Wed, 20 Sep 2023 13:57:30 +0800 Subject: [PATCH 02/50] clean return clean; --- .github/workflows/plugin-timeclock-api.yaml | 4 ++-- .github/workflows/plugin-timeclock-ui.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/plugin-timeclock-api.yaml b/.github/workflows/plugin-timeclock-api.yaml index d6f88d7084..5c2df7ee74 100644 --- a/.github/workflows/plugin-timeclock-api.yaml +++ b/.github/workflows/plugin-timeclock-api.yaml @@ -62,5 +62,5 @@ jobs: run: | cd dist/plugin-timeclock-api/.erxes echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin - docker build -t erxes/plugin-timeclock-api:community -f Dockerfile . - docker push erxes/plugin-timeclock-api:community + docker build -t erxes/plugin-timeclock-api:${GITHUB_REF#refs/heads/} -f Dockerfile . + docker push erxes/plugin-timeclock-api:${GITHUB_REF#refs/heads/} diff --git a/.github/workflows/plugin-timeclock-ui.yaml b/.github/workflows/plugin-timeclock-ui.yaml index cc982bb43b..9fc73399b0 100644 --- a/.github/workflows/plugin-timeclock-ui.yaml +++ b/.github/workflows/plugin-timeclock-ui.yaml @@ -84,4 +84,4 @@ jobs: tar -cf build.tar --directory=packages/plugin-timeclock-ui/.erxes/dist . cp build.tar packages/plugin-timeclock-ui/.erxes/dist rm -rf packages/plugin-timeclock-ui/.erxes/dist/*.js - aws s3 sync packages/plugin-timeclock-ui/.erxes/dist s3://erxes-community-plugins/uis/plugin-timeclock-ui --delete + aws s3 sync packages/plugin-timeclock-ui/.erxes/dist s3://erxes-${GITHUB_REF#refs/heads/}-plugins/uis/plugin-timeclock-ui --delete From 4815ecf702cdb7b75459001ca4c836cd9078ca54 Mon Sep 17 00:00:00 2001 From: Anu-Ujin Bat-Ulzii Date: Wed, 20 Sep 2023 13:59:21 +0800 Subject: [PATCH 03/50] improve imap activity log --- .../src/components/ActivityLog.tsx | 17 +- packages/plugin-imap-ui/src/styles.ts | 434 ++++++++++++++++++ .../activityLogs/components/ActivityItem.tsx | 2 +- 3 files changed, 450 insertions(+), 3 deletions(-) create mode 100644 packages/plugin-imap-ui/src/styles.ts diff --git a/packages/plugin-imap-ui/src/components/ActivityLog.tsx b/packages/plugin-imap-ui/src/components/ActivityLog.tsx index c44f2fe545..ab72a8c0aa 100644 --- a/packages/plugin-imap-ui/src/components/ActivityLog.tsx +++ b/packages/plugin-imap-ui/src/components/ActivityLog.tsx @@ -1,4 +1,9 @@ +import { ActivityIcon, ActivityRow } from '../styles'; + +import Icon from '@erxes/ui/src/components/Icon'; import React from 'react'; +import Tip from '@erxes/ui/src/components/Tip'; +import { getIconAndColor } from '@erxes/ui-log/src/activityLogs/utils'; type Props = { contentType: string; @@ -12,8 +17,16 @@ class ActivityItem extends React.Component { const { contentTypeDetail } = activity; const { body, subject } = contentTypeDetail; + const iconAndColor = getIconAndColor('email'); + return ( -
+ + + + + + + Sent an email @@ -27,7 +40,7 @@ class ActivityItem extends React.Component { Content:

-
+
); } } diff --git a/packages/plugin-imap-ui/src/styles.ts b/packages/plugin-imap-ui/src/styles.ts new file mode 100644 index 0000000000..029a79e414 --- /dev/null +++ b/packages/plugin-imap-ui/src/styles.ts @@ -0,0 +1,434 @@ +import { colors, dimensions, typography } from '@erxes/ui/src/styles'; + +import { WhiteBox } from '@erxes/ui/src/layout/styles'; +import styled from 'styled-components'; +import styledTS from 'styled-components-ts'; + +const iconWrapperWidth = 80; + +const Timeline = styled.div` + padding-left: ${iconWrapperWidth}px; + position: relative; + + &:before { + border-right: 1px solid ${colors.borderDarker}; + content: ''; + height: 100%; + position: absolute; + z-index: 1; + margin-top: 1px; + left: ${iconWrapperWidth / 2}px; + } +`; + +const ActivityTitle = styled.h4` + margin: 0; + padding: ${dimensions.coreSpacing * 1.5}px 0 ${dimensions.coreSpacing}px; + font-weight: 400; + color: ${colors.textPrimary}; +`; + +const ActivityRow = styledTS<{ isConversation?: boolean }>(styled(WhiteBox))` + padding: ${props => (props.isConversation ? '0' : dimensions.coreSpacing)}px; + background: ${props => props.isConversation && colors.bgLight}; + position: relative; + overflow: visible; + margin-bottom: ${dimensions.coreSpacing}px; + border-radius: 2px; + height: auto; + transition:height 0.3s ease-out; + + &:last-of-type { + margin-bottom: 0; + } + + &:hover { + background: ${props => props.isConversation && colors.bgLightPurple}; + } +`; + +const FlexCenterContent = styled.div` + display: flex; + justify-content: space-between; + align-items: center; +`; + +const FlexContent = styled.div` + display: flex; + align-items: center; +`; + +const Title = styledTS<{ isComplete?: boolean; isEditing: boolean }>( + styled.div +)` + position: relative; + margin: ${dimensions.unitSpacing}px; + flex: 1; + font-size: 16px; + + > div { + margin-bottom: ${dimensions.unitSpacing}px; + } + + h4 { + text-decoration: ${props => props.isComplete && 'line-through'}; + transition: all ease 0.4s; + margin-bottom: ${dimensions.unitSpacing}px; + + > i { + margin-right: 5px; + } + } + + .icon-edit { + visibility: hidden; + transition: all ease 0.3s; + position: absolute; + right: ${dimensions.unitSpacing}px; + top: 5px; + } + + &:hover { + cursor: text; + + .icon-edit { + visibility: ${props => !props.isEditing && 'visible'}; + } + } +`; + +const FlexBody = styled.div` + flex: 1; + align-self: center; + word-break: break-word; + + p { + margin: 0; + font-weight: 500; + font-size: 14px; + } + + > div { + font-size: ${typography.fontSizeHeading8}px; + } + + span { + padding-right: ${dimensions.unitSpacing}px; + } +`; + +const Row = styled.div` + margin-right: ${dimensions.coreSpacing}px; +`; + +const AvatarWrapper = styledTS<{ + isOnline?: boolean; + hideIndicator?: boolean; + size?: number; +}>(styled.div)` + margin-right: ${dimensions.unitSpacing * 1.5}px; + position: relative; + max-height: ${props => (props.size ? `${props.size}px` : '50px')}; + + a { + float: none; + } + + &:before { + content: ''; + position: absolute; + right: -3px; + top: 32px; + background: ${props => + props.isOnline ? colors.colorCoreGreen : colors.colorShadowGray}; + width: 14px; + height: 14px; + border-radius: ${dimensions.unitSpacing}px; + font-size: ${dimensions.unitSpacing}px; + border: 1px solid ${colors.colorWhite}; + z-index: 1; + display: ${props => props.hideIndicator && 'none'}; + } +`; + +const ActivityIcon = styledTS<{ color?: string }>(styled.span)` + display: inline-block; + position: absolute; + background-color: ${props => props.color}; + height: ${iconWrapperWidth * 0.4}px; + width: ${iconWrapperWidth * 0.4}px; + line-height: ${iconWrapperWidth * 0.4}px; + text-align: center; + border-radius: 50%; + left: ${-iconWrapperWidth + iconWrapperWidth * 0.3}px; + top: ${dimensions.coreSpacing}px; + z-index: 2; + + & i { + margin: 0; + color: ${colors.colorWhite}; + } +`; + +const ActivityDate = styled.div` + color: ${colors.colorCoreGray}; + font-weight: ${typography.fontWeightLight}; + font-size: 11px; + margin-left: 5px; + cursor: help; +`; + +const ActivityContent = styledTS<{ isInternalNote?: boolean }>(styled.div)` + margin-top: ${dimensions.unitSpacing}px; + padding: ${dimensions.unitSpacing}px; + background: ${props => + props.isInternalNote ? colors.bgInternal : colors.borderPrimary}; + box-shadow: 0 1px 2px 0 ${colors.darkShadow}; + word-break:break-word; + + p:last-of-type { + margin-bottom: 0; + } + + img { + max-width: 100%; + } +`; + +const EmptyContent = styled.div` + display: flex; + height: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + padding: ${dimensions.coreSpacing + dimensions.coreSpacing}px 0; + + > img { + width: 300px; + } + + p { + text-align: center; + max-width: 400px; + + b { + margin: ${dimensions.unitSpacing}px 0; + display: block; + } + } +`; + +const EmailContent = styledTS<{ longEmail: boolean; expand: boolean }>( + styled.div +)` + margin-top: ${dimensions.unitSpacing}px; + max-height: ${props => (props.expand ? 'auto' : '80px')}; + overflow: hidden; + transition: height .5s; + + p { + margin: 0; + } +`; + +const ExpandButton = styled.div` + margin-top: ${dimensions.coreSpacing}px; + cursor: pointer; + color: ${colors.colorCoreBlue}; + font-weight: 500; + transition: all ease 0.4s; + + &:hover { + text-decoration: underline; + } +`; + +const ContentShadow = styled.div` + background-image: linear-gradient(rgba(255, 255, 255, 0), rgb(255, 255, 255)); + background-size: 100% 30px; + height: 40px; + position: absolute; + bottom: 40px; + left: 0px; + right: 0px; +`; + +const Date = styledTS<{ showDetail?: boolean }>(styled.div)` + cursor: pointer; + display: table; + margin-right: ${dimensions.unitSpacing - 2}px; + line-height: 33px; + + span { + font-weight: 600; + color: ${colors.colorCoreBlue}; + } + + i { + margin-right: 5px; + + &:before { + transition: all .15s ease-in-out; + transform: ${props => props.showDetail && 'rotate(90deg)'}; + } + } +`; + +const Detail = styledTS<{ full?: boolean }>(styled.div)` + margin-top: ${props => + props.full ? dimensions.coreSpacing : dimensions.unitSpacing}px; + + > p { + margin: ${dimensions.unitSpacing}px 0 ${dimensions.coreSpacing}px; + } + `; + +const IconWrapper = styledTS<{ isComplete?: boolean }>(styled.div)` + cursor: pointer; + + > i { + background: ${props => + props.isComplete ? colors.colorCoreGreen : colors.bgLight}; + color: ${props => + props.isComplete ? colors.colorWhite : colors.colorShadowGray}; + border-radius: 25px; + display: inline-block; + line-height: 25px; + border: 2px solid ${props => + props.isComplete ? colors.colorCoreGreen : colors.colorShadowGray}; + transition: all ease 0.3s; + } +`; + +const Description = styled.div` + padding: ${dimensions.unitSpacing}px; + background: ${colors.bgLight}; + border: 1px solid ${colors.borderPrimary}; + border-radius: 2px; + margin: ${dimensions.coreSpacing}px 0; + word-break: break-word; +`; + +const DeleteAction = styled.div` + color: ${colors.colorCoreRed}; + padding-right: ${dimensions.unitSpacing}px; + cursor: pointer; + visibility: hidden; + transition: all 0.2s ease-in-out 0.2s; + font-weight: 500; +`; + +const JumpTo = styled(DeleteAction)` + color: ${colors.colorCoreBlue}; + margin-right: ${dimensions.unitSpacing}px; +`; + +const LogWrapper = styled.div` + flex: 1; + + &:hover { + ${DeleteAction} { + visibility: visible; + } + } +`; + +const ConversationContent = styled.div` + margin-top: ${dimensions.unitSpacing}px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 90%; +`; + +const Count = styled.div` + text-align: center; + border: 1px solid ${colors.colorShadowGray}; + border-radius: 2px; + padding: 0 7px; + color: ${colors.colorCoreGray}; +`; + +const Collapse = styled.div` + padding: ${dimensions.coreSpacing}px; + transition: all ease 0.5s; + + .dropdown { + display: none; + } +`; + +const CollapseTrigger = styled.div` + &:hover { + cursor: pointer; + opacity: 0.9; + } +`; + +const Header = styled(CollapseTrigger)` + border-bottom: 1px solid ${colors.colorShadowGray}; + padding-bottom: ${dimensions.unitSpacing}px; + margin-bottom: ${dimensions.coreSpacing}px; + font-size: 15px; +`; + +const CenterText = styled.div` + text-align: center; + margin-top: ${dimensions.coreSpacing}px; +`; + +const MergedContacts = styled.div` + a { + font-weight: 600; + + &:after { + content: ', '; + } + + &:last-child::after { + content: ''; + } + } +`; + +const ShowMore = styled.span` + color: #6569df; + cursor: pointer; + &:hover { + color: black; + } +`; + +export { + ShowMore, + Timeline, + ActivityTitle, + ActivityRow, + ActivityIcon, + AvatarWrapper, + ActivityDate, + ActivityContent, + Description, + EmailContent, + ConversationContent, + FlexCenterContent, + FlexContent, + FlexBody, + MergedContacts, + Row, + IconWrapper, + Title, + Date, + Detail, + ContentShadow, + Count, + LogWrapper, + Collapse, + Header, + CenterText, + ExpandButton, + DeleteAction, + JumpTo, + EmptyContent, + CollapseTrigger +}; diff --git a/packages/ui-log/src/activityLogs/components/ActivityItem.tsx b/packages/ui-log/src/activityLogs/components/ActivityItem.tsx index 3b928e5baa..1d724859d1 100644 --- a/packages/ui-log/src/activityLogs/components/ActivityItem.tsx +++ b/packages/ui-log/src/activityLogs/components/ActivityItem.tsx @@ -3,13 +3,13 @@ import { formatText, getIconAndColor } from '../utils'; import ErrorBoundary from '@erxes/ui/src/components/ErrorBoundary'; import { IActivityLog } from '../types'; +import { IIntegration } from '@erxes/ui-inbox/src/settings/integrations/types'; import { IUser } from '@erxes/ui/src/auth/types'; import Icon from '@erxes/ui/src/components/Icon'; import InternalNote from '../containers/items/InternalNote'; import React from 'react'; import { RenderDynamicComponent } from '@erxes/ui/src/utils/core'; import Tip from '@erxes/ui/src/components/Tip'; -import { IIntegration } from '@erxes/ui-inbox/src/settings/integrations/types'; type Props = { activity: IActivityLog; From b3e01a1d1c58a89be65ab2eb775342eded1c6eb0 Mon Sep 17 00:00:00 2001 From: Anu-Ujin Bat-Ulzii Date: Wed, 20 Sep 2023 18:00:47 +0800 Subject: [PATCH 04/50] update --- .../src/components/ActivityLog.tsx | 88 +++- packages/plugin-imap-ui/src/styles.ts | 401 ++---------------- .../activityLogs/components/Conversation.tsx | 11 +- .../activityLogs/components/ActivityItem.tsx | 2 +- packages/ui-log/src/activityLogs/styles.ts | 2 +- 5 files changed, 117 insertions(+), 387 deletions(-) diff --git a/packages/plugin-imap-ui/src/components/ActivityLog.tsx b/packages/plugin-imap-ui/src/components/ActivityLog.tsx index ab72a8c0aa..56fb74deca 100644 --- a/packages/plugin-imap-ui/src/components/ActivityLog.tsx +++ b/packages/plugin-imap-ui/src/components/ActivityLog.tsx @@ -1,8 +1,18 @@ -import { ActivityIcon, ActivityRow } from '../styles'; +import { + AcitivityHeader, + ActivityDate, + ActivityIcon, + ActivityRow, + IMapActivityContent, + SentWho +} from '../styles'; +import Button from '@erxes/ui/src/components/Button'; import Icon from '@erxes/ui/src/components/Icon'; import React from 'react'; import Tip from '@erxes/ui/src/components/Tip'; +import { __ } from '@erxes/ui/src/utils/core'; +import dayjs from 'dayjs'; import { getIconAndColor } from '@erxes/ui-log/src/activityLogs/utils'; type Props = { @@ -11,11 +21,62 @@ type Props = { currentUser: any; }; -class ActivityItem extends React.Component { +type State = { + shrink: boolean; +}; + +class ActivityItem extends React.Component { + constructor(props) { + super(props); + + const { contentTypeDetail = {} } = props.activity; + + this.state = { + shrink: (contentTypeDetail.body || '').length > 380 ? true : false + }; + } + + renderWhom(contentTypeDetail) { + const { from, to } = contentTypeDetail; + + const From = from ? from.map(f => f.name || f.address) : 'unknown'; + const To = to ? to.map(f => f.name || f.address) : 'unknown'; + + return ( + + {From.map(f => f)} + {__('send email to ')} + {To.map(t => t)} + + ); + } + + renderExpandButton() { + const { shrink } = this.state; + + if (!shrink) { + return null; + } + + return ( + + ); + } + render() { const { activity } = this.props; - const { contentTypeDetail } = activity; - const { body, subject } = contentTypeDetail; + const { contentTypeDetail, contentType } = activity; + const { body, subject, createdAt } = contentTypeDetail; + + if (contentType && !contentType.includes('imap')) { + return null; + } const iconAndColor = getIconAndColor('email'); @@ -27,19 +88,16 @@ class ActivityItem extends React.Component { - - Sent an email - - -

- Subject: -

{subject}
-

+ + {subject} + {dayjs(createdAt).format('lll')} + + {this.renderWhom(contentTypeDetail)} -

- Content: +

-

+ {this.renderExpandButton()} + ); } diff --git a/packages/plugin-imap-ui/src/styles.ts b/packages/plugin-imap-ui/src/styles.ts index 029a79e414..fc6b069b88 100644 --- a/packages/plugin-imap-ui/src/styles.ts +++ b/packages/plugin-imap-ui/src/styles.ts @@ -6,35 +6,13 @@ import styledTS from 'styled-components-ts'; const iconWrapperWidth = 80; -const Timeline = styled.div` - padding-left: ${iconWrapperWidth}px; - position: relative; - - &:before { - border-right: 1px solid ${colors.borderDarker}; - content: ''; - height: 100%; - position: absolute; - z-index: 1; - margin-top: 1px; - left: ${iconWrapperWidth / 2}px; - } -`; - -const ActivityTitle = styled.h4` - margin: 0; - padding: ${dimensions.coreSpacing * 1.5}px 0 ${dimensions.coreSpacing}px; - font-weight: 400; - color: ${colors.textPrimary}; -`; - const ActivityRow = styledTS<{ isConversation?: boolean }>(styled(WhiteBox))` padding: ${props => (props.isConversation ? '0' : dimensions.coreSpacing)}px; background: ${props => props.isConversation && colors.bgLight}; position: relative; overflow: visible; margin-bottom: ${dimensions.coreSpacing}px; - border-radius: 2px; + border-radius: 5px; height: auto; transition:height 0.3s ease-out; @@ -47,110 +25,6 @@ const ActivityRow = styledTS<{ isConversation?: boolean }>(styled(WhiteBox))` } `; -const FlexCenterContent = styled.div` - display: flex; - justify-content: space-between; - align-items: center; -`; - -const FlexContent = styled.div` - display: flex; - align-items: center; -`; - -const Title = styledTS<{ isComplete?: boolean; isEditing: boolean }>( - styled.div -)` - position: relative; - margin: ${dimensions.unitSpacing}px; - flex: 1; - font-size: 16px; - - > div { - margin-bottom: ${dimensions.unitSpacing}px; - } - - h4 { - text-decoration: ${props => props.isComplete && 'line-through'}; - transition: all ease 0.4s; - margin-bottom: ${dimensions.unitSpacing}px; - - > i { - margin-right: 5px; - } - } - - .icon-edit { - visibility: hidden; - transition: all ease 0.3s; - position: absolute; - right: ${dimensions.unitSpacing}px; - top: 5px; - } - - &:hover { - cursor: text; - - .icon-edit { - visibility: ${props => !props.isEditing && 'visible'}; - } - } -`; - -const FlexBody = styled.div` - flex: 1; - align-self: center; - word-break: break-word; - - p { - margin: 0; - font-weight: 500; - font-size: 14px; - } - - > div { - font-size: ${typography.fontSizeHeading8}px; - } - - span { - padding-right: ${dimensions.unitSpacing}px; - } -`; - -const Row = styled.div` - margin-right: ${dimensions.coreSpacing}px; -`; - -const AvatarWrapper = styledTS<{ - isOnline?: boolean; - hideIndicator?: boolean; - size?: number; -}>(styled.div)` - margin-right: ${dimensions.unitSpacing * 1.5}px; - position: relative; - max-height: ${props => (props.size ? `${props.size}px` : '50px')}; - - a { - float: none; - } - - &:before { - content: ''; - position: absolute; - right: -3px; - top: 32px; - background: ${props => - props.isOnline ? colors.colorCoreGreen : colors.colorShadowGray}; - width: 14px; - height: 14px; - border-radius: ${dimensions.unitSpacing}px; - font-size: ${dimensions.unitSpacing}px; - border: 1px solid ${colors.colorWhite}; - z-index: 1; - display: ${props => props.hideIndicator && 'none'}; - } -`; - const ActivityIcon = styledTS<{ color?: string }>(styled.span)` display: inline-block; position: absolute; @@ -174,261 +48,60 @@ const ActivityDate = styled.div` color: ${colors.colorCoreGray}; font-weight: ${typography.fontWeightLight}; font-size: 11px; - margin-left: 5px; - cursor: help; -`; - -const ActivityContent = styledTS<{ isInternalNote?: boolean }>(styled.div)` - margin-top: ${dimensions.unitSpacing}px; - padding: ${dimensions.unitSpacing}px; - background: ${props => - props.isInternalNote ? colors.bgInternal : colors.borderPrimary}; - box-shadow: 0 1px 2px 0 ${colors.darkShadow}; - word-break:break-word; - - p:last-of-type { - margin-bottom: 0; - } - - img { - max-width: 100%; - } -`; - -const EmptyContent = styled.div` - display: flex; - height: 100%; - flex-direction: column; - align-items: center; - justify-content: center; - padding: ${dimensions.coreSpacing + dimensions.coreSpacing}px 0; - - > img { - width: 300px; - } - - p { - text-align: center; - max-width: 400px; - - b { - margin: ${dimensions.unitSpacing}px 0; - display: block; - } - } + flex-shrink: 0; + margin-left: ${dimensions.unitSpacing}px; `; -const EmailContent = styledTS<{ longEmail: boolean; expand: boolean }>( - styled.div -)` - margin-top: ${dimensions.unitSpacing}px; - max-height: ${props => (props.expand ? 'auto' : '80px')}; +const IMapActivityContent = styledTS<{ shrink: boolean }>(styled.div)` + position: relative; overflow: hidden; - transition: height .5s; - - p { - margin: 0; - } -`; - -const ExpandButton = styled.div` - margin-top: ${dimensions.coreSpacing}px; - cursor: pointer; - color: ${colors.colorCoreBlue}; - font-weight: 500; - transition: all ease 0.4s; - - &:hover { - text-decoration: underline; - } -`; - -const ContentShadow = styled.div` - background-image: linear-gradient(rgba(255, 255, 255, 0), rgb(255, 255, 255)); - background-size: 100% 30px; - height: 40px; - position: absolute; - bottom: 40px; - left: 0px; - right: 0px; -`; - -const Date = styledTS<{ showDetail?: boolean }>(styled.div)` - cursor: pointer; - display: table; - margin-right: ${dimensions.unitSpacing - 2}px; - line-height: 33px; - - span { - font-weight: 600; - color: ${colors.colorCoreBlue}; - } - - i { - margin-right: 5px; + border-radius: 5px; - &:before { - transition: all .15s ease-in-out; - transform: ${props => props.showDetail && 'rotate(90deg)'}; - } - } -`; - -const Detail = styledTS<{ full?: boolean }>(styled.div)` - margin-top: ${props => - props.full ? dimensions.coreSpacing : dimensions.unitSpacing}px; - - > p { - margin: ${dimensions.unitSpacing}px 0 ${dimensions.coreSpacing}px; + > button { + position: absolute; + bottom: 20px; + left: 50%; + transform: translate(-50%, -50%); + z-index: 5; } - `; - -const IconWrapper = styledTS<{ isComplete?: boolean }>(styled.div)` - cursor: pointer; - > i { - background: ${props => - props.isComplete ? colors.colorCoreGreen : colors.bgLight}; - color: ${props => - props.isComplete ? colors.colorWhite : colors.colorShadowGray}; - border-radius: 25px; - display: inline-block; - line-height: 25px; - border: 2px solid ${props => - props.isComplete ? colors.colorCoreGreen : colors.colorShadowGray}; - transition: all ease 0.3s; - } -`; + ${props => + props.shrink && + ` + max-height: 200px; -const Description = styled.div` - padding: ${dimensions.unitSpacing}px; - background: ${colors.bgLight}; - border: 1px solid ${colors.borderPrimary}; - border-radius: 2px; - margin: ${dimensions.coreSpacing}px 0; - word-break: break-word; -`; - -const DeleteAction = styled.div` - color: ${colors.colorCoreRed}; - padding-right: ${dimensions.unitSpacing}px; - cursor: pointer; - visibility: hidden; - transition: all 0.2s ease-in-out 0.2s; - font-weight: 500; -`; - -const JumpTo = styled(DeleteAction)` - color: ${colors.colorCoreBlue}; - margin-right: ${dimensions.unitSpacing}px; -`; - -const LogWrapper = styled.div` - flex: 1; - - &:hover { - ${DeleteAction} { - visibility: visible; + &:after { + content: ''; + height: 100px; + width: 100%; + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(180deg, rgba(255,255,255,0) 0%, ${colors.borderPrimary} 100%); } - } + `} `; -const ConversationContent = styled.div` - margin-top: ${dimensions.unitSpacing}px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 90%; -`; - -const Count = styled.div` - text-align: center; - border: 1px solid ${colors.colorShadowGray}; - border-radius: 2px; - padding: 0 7px; - color: ${colors.colorCoreGray}; -`; +const SentWho = styled.div` + margin-bottom: ${dimensions.unitSpacing}px; + color: #666; -const Collapse = styled.div` - padding: ${dimensions.coreSpacing}px; - transition: all ease 0.5s; - - .dropdown { - display: none; - } -`; - -const CollapseTrigger = styled.div` - &:hover { - cursor: pointer; - opacity: 0.9; + strong { + margin-right: ${dimensions.unitSpacing - 5}px; } `; -const Header = styled(CollapseTrigger)` - border-bottom: 1px solid ${colors.colorShadowGray}; - padding-bottom: ${dimensions.unitSpacing}px; - margin-bottom: ${dimensions.coreSpacing}px; - font-size: 15px; -`; - -const CenterText = styled.div` - text-align: center; - margin-top: ${dimensions.coreSpacing}px; -`; - -const MergedContacts = styled.div` - a { - font-weight: 600; - - &:after { - content: ', '; - } - - &:last-child::after { - content: ''; - } - } -`; - -const ShowMore = styled.span` - color: #6569df; - cursor: pointer; - &:hover { - color: black; - } +const AcitivityHeader = styled.div` + display: flex; + justify-content: space-between; `; export { - ShowMore, - Timeline, - ActivityTitle, ActivityRow, ActivityIcon, - AvatarWrapper, ActivityDate, - ActivityContent, - Description, - EmailContent, - ConversationContent, - FlexCenterContent, - FlexContent, - FlexBody, - MergedContacts, - Row, - IconWrapper, - Title, - Date, - Detail, - ContentShadow, - Count, - LogWrapper, - Collapse, - Header, - CenterText, - ExpandButton, - DeleteAction, - JumpTo, - EmptyContent, - CollapseTrigger + AcitivityHeader, + SentWho, + IMapActivityContent }; diff --git a/packages/plugin-inbox-ui/src/activityLogs/components/Conversation.tsx b/packages/plugin-inbox-ui/src/activityLogs/components/Conversation.tsx index 810caa3dc6..af0317e859 100644 --- a/packages/plugin-inbox-ui/src/activityLogs/components/Conversation.tsx +++ b/packages/plugin-inbox-ui/src/activityLogs/components/Conversation.tsx @@ -1,8 +1,3 @@ -import { Link } from 'react-router-dom'; -import React from 'react'; -import dayjs from 'dayjs'; -import xss from 'xss'; - import { ActivityDate, ActivityIcon, @@ -25,9 +20,13 @@ import { import { IIntegration } from '@erxes/ui-inbox/src/settings/integrations/types'; import Icon from '@erxes/ui/src/components/Icon'; +import { Link } from 'react-router-dom'; import MailConversation from '@erxes/ui-inbox/src/inbox/components/conversationDetail/workarea/mail/MailConversation'; import Message from '@erxes/ui-inbox/src/inbox/components/conversationDetail/workarea/conversation/messages/Message'; +import React from 'react'; import Tip from '@erxes/ui/src/components/Tip'; +import dayjs from 'dayjs'; +import xss from 'xss'; type Props = { activity: any; @@ -150,7 +149,7 @@ class Conversation extends React.Component { renderContent() { const { conversation, messages } = this.props; const { customer, content, createdAt, integration } = conversation; - + console.log('ccc', conversation); if (!this.state.toggleMessage && integration) { return ( <> diff --git a/packages/ui-log/src/activityLogs/components/ActivityItem.tsx b/packages/ui-log/src/activityLogs/components/ActivityItem.tsx index 1d724859d1..6925999184 100644 --- a/packages/ui-log/src/activityLogs/components/ActivityItem.tsx +++ b/packages/ui-log/src/activityLogs/components/ActivityItem.tsx @@ -66,7 +66,7 @@ class ActivityItem extends React.Component { } if (kind) { - const p = plugins.find(p => p.name === kind); + const p = plugins.find(pl => pl.name === kind); if (p) { scope = p.scope; diff --git a/packages/ui-log/src/activityLogs/styles.ts b/packages/ui-log/src/activityLogs/styles.ts index 029a79e414..574379bad2 100644 --- a/packages/ui-log/src/activityLogs/styles.ts +++ b/packages/ui-log/src/activityLogs/styles.ts @@ -34,7 +34,7 @@ const ActivityRow = styledTS<{ isConversation?: boolean }>(styled(WhiteBox))` position: relative; overflow: visible; margin-bottom: ${dimensions.coreSpacing}px; - border-radius: 2px; + border-radius: 5px; height: auto; transition:height 0.3s ease-out; From acb64a0f208e38aceb95d9cb584c7467425abade Mon Sep 17 00:00:00 2001 From: Anu-Ujin Bat-Ulzii Date: Wed, 20 Sep 2023 21:39:40 +0800 Subject: [PATCH 05/50] update --- .../src/activityLogs/components/Conversation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-inbox-ui/src/activityLogs/components/Conversation.tsx b/packages/plugin-inbox-ui/src/activityLogs/components/Conversation.tsx index af0317e859..87169a7576 100644 --- a/packages/plugin-inbox-ui/src/activityLogs/components/Conversation.tsx +++ b/packages/plugin-inbox-ui/src/activityLogs/components/Conversation.tsx @@ -149,7 +149,7 @@ class Conversation extends React.Component { renderContent() { const { conversation, messages } = this.props; const { customer, content, createdAt, integration } = conversation; - console.log('ccc', conversation); + if (!this.state.toggleMessage && integration) { return ( <> From 3e5120142bf13cd7cc9262f4ab9e2fe6c2462897 Mon Sep 17 00:00:00 2001 From: munkhsaikhan Date: Wed, 20 Sep 2023 22:50:13 +0800 Subject: [PATCH 06/50] online pos with productName --- packages/plugin-pos-api/src/utils.ts | 21 +++++++++++++++++++ .../src/graphql/resolvers/mutations/orders.ts | 10 +++++++++ .../src/graphql/resolvers/orderItem.ts | 6 +++++- .../plugin-posclient-api/src/messageBroker.ts | 14 +++++++++++++ .../src/models/definitions/orderItems.ts | 1 + 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/packages/plugin-pos-api/src/utils.ts b/packages/plugin-pos-api/src/utils.ts index 9f2f129f81..b80584c2aa 100644 --- a/packages/plugin-pos-api/src/utils.ts +++ b/packages/plugin-pos-api/src/utils.ts @@ -520,6 +520,7 @@ export const syncOrderFromClient = async ({ responses; oldBranchId: string; }) => { + const oldOrder = await models.PosOrders.findOne({ _id: order._id }).lean(); for (const response of responses || []) { if (response && response._id) { await sendEbarimtMessage({ @@ -582,6 +583,26 @@ export const syncOrderFromClient = async ({ pos: toPos }); } + + // change branch and before another pos synced then remove from befort sync + if ( + oldOrder && + oldOrder.branchId && + newOrder.branchId !== oldOrder.branchId + ) { + const toCancelPos = await models.Pos.findOne({ + branchId: oldOrder.branchId + }).lean(); + + await sendPosclientMessage({ + subdomain, + action: 'erxes-posclient-to-pos-api-remove', + data: { + order: { ...newOrder, posToken, subToken: toPos.token } + }, + pos: toCancelPos + }); + } } await syncErkhetRemainder({ subdomain, models, pos, newOrder }); diff --git a/packages/plugin-posclient-api/src/graphql/resolvers/mutations/orders.ts b/packages/plugin-posclient-api/src/graphql/resolvers/mutations/orders.ts index 3ede565748..63833e2a26 100644 --- a/packages/plugin-posclient-api/src/graphql/resolvers/mutations/orders.ts +++ b/packages/plugin-posclient-api/src/graphql/resolvers/mutations/orders.ts @@ -737,6 +737,16 @@ const orderMutations = { } }); + if (config.isOnline) { + const products = await models.Products.find({ + _id: { $in: items.map(i => i.productId) } + }).lean(); + for (const item of items) { + const product = products.find(p => p._id === item.productId) || {}; + item.productName = `${product.code} - ${product.name}`; + } + } + try { sendPosMessage({ subdomain, diff --git a/packages/plugin-posclient-api/src/graphql/resolvers/orderItem.ts b/packages/plugin-posclient-api/src/graphql/resolvers/orderItem.ts index f2107879b3..1ba98fbf66 100644 --- a/packages/plugin-posclient-api/src/graphql/resolvers/orderItem.ts +++ b/packages/plugin-posclient-api/src/graphql/resolvers/orderItem.ts @@ -9,7 +9,11 @@ export default { ) { const product = await models.Products.findOne({ _id: orderItem.productId }); - return product ? product.name : 'product not found'; + if (!product) { + return orderItem.productName || 'product not found'; + } + + return `${product.code} - ${product.name}`; }, async productImgUrl( orderItem: IOrderItemDocument, diff --git a/packages/plugin-posclient-api/src/messageBroker.ts b/packages/plugin-posclient-api/src/messageBroker.ts index 524a9a8f84..bbd0ff1bc4 100644 --- a/packages/plugin-posclient-api/src/messageBroker.ts +++ b/packages/plugin-posclient-api/src/messageBroker.ts @@ -164,6 +164,20 @@ export const initBroker = async cl => { } ); + consumeQueue( + `posclient:erxes-posclient-to-pos-api-remove${channelToken}`, + async ({ subdomain, data }) => { + const models = await generateModels(subdomain); + const { order } = data; + + await models.Orders.deleteOne({ + _id: order._id, + posToken: order.posToken, + subToken: order.subToken + }); + } + ); + consumeRPCQueue( `posclient:health_check${channelToken}`, async ({ subdomain, data }) => { diff --git a/packages/plugin-posclient-api/src/models/definitions/orderItems.ts b/packages/plugin-posclient-api/src/models/definitions/orderItems.ts index 12332e21ed..e6b2da437f 100644 --- a/packages/plugin-posclient-api/src/models/definitions/orderItems.ts +++ b/packages/plugin-posclient-api/src/models/definitions/orderItems.ts @@ -36,6 +36,7 @@ export const orderItemSchema = schemaHooksWrapper( _id: field({ pkey: true }), createdAt: getDateFieldDefinition('Created at'), productId: field({ type: String, label: 'Product' }), + productName: field({ type: String, label: 'Product Name if subtoken' }), count: getNumberFieldDefinition({ label: 'Count', positive: true }), unitPrice: getNumberFieldDefinition({ label: 'Unit price', From 095a5a6f276c3de85b676580c9bc14b533c9424e Mon Sep 17 00:00:00 2001 From: erdeneuul Date: Wed, 20 Sep 2023 23:04:59 +0800 Subject: [PATCH 07/50] reload fix --- cypress/tests/ui/auth.cy.js | 5 +++-- cypress/tests/ui/contacts/company.cy.js | 8 ++++---- cypress/tests/ui/contacts/customer.cy.js | 3 +-- cypress/tests/ui/contacts/lead.cy.js | 10 +++++----- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cypress/tests/ui/auth.cy.js b/cypress/tests/ui/auth.cy.js index 56609ccff9..a8d229f5cb 100644 --- a/cypress/tests/ui/auth.cy.js +++ b/cypress/tests/ui/auth.cy.js @@ -11,12 +11,13 @@ describe("User sign up and login", () => { it("should redirect unauthenticated user to signin page", function () { cy.visit("/contacts/customer"); - cy.get('button.sc-bRBYWo').should("be.visible"); + cy.get('button.sc-bRBYWo',{timeout: 300000}).should("be.visible"); // cy.visualSnapshot("Redirect to SignIn"); }); it("input error message", () => { - cy.get('input[name=email]').type("{enter}"); + + cy.get('input[name=email]',{timeout:300000}).type("{enter}"); cy.get('label.sc-frDJqD').should('be.visible') }) diff --git a/cypress/tests/ui/contacts/company.cy.js b/cypress/tests/ui/contacts/company.cy.js index 900625cb2b..f25c00669a 100644 --- a/cypress/tests/ui/contacts/company.cy.js +++ b/cypress/tests/ui/contacts/company.cy.js @@ -15,7 +15,7 @@ describe("Contacts", () => { it("add company", () => { - cy.get('i[icon = "plus-circle"]').click(); + cy.get('i[icon = "plus-circle"]', { timeout: 300000 }).click(); cy.get("div .Select-placeholder") .contains("Enter company name") @@ -33,7 +33,7 @@ describe("Contacts", () => { it("set tag company", () => { - cy.get("#companiesCheckBox").click(); + cy.get("#companiesCheckBox",{ timeout: 300000 }).eq(0).click(); cy.get('button[icon="tag-alt"]').click(); @@ -47,8 +47,8 @@ describe("Contacts", () => { }) it("remove company", () => { - - cy.contains(random) + + cy.contains(random, { timeout: 300000 }) .parent() .parent() .parent() diff --git a/cypress/tests/ui/contacts/customer.cy.js b/cypress/tests/ui/contacts/customer.cy.js index 0031392573..5a54f4ae85 100644 --- a/cypress/tests/ui/contacts/customer.cy.js +++ b/cypress/tests/ui/contacts/customer.cy.js @@ -14,8 +14,7 @@ describe("Customer", () => { it("add customer", () => { - cy.waitElm('button[icon="plus-circle"]'); - cy.get('button[icon="plus-circle"]').click(); + cy.get('button[icon="plus-circle"]', { timeout: 300000}).click(); const random = Math.random().toString(36).slice(2) diff --git a/cypress/tests/ui/contacts/lead.cy.js b/cypress/tests/ui/contacts/lead.cy.js index e6f7c5f9db..b61a2ed3af 100644 --- a/cypress/tests/ui/contacts/lead.cy.js +++ b/cypress/tests/ui/contacts/lead.cy.js @@ -15,7 +15,7 @@ describe("Lead", () => { const random = Math.random().toString(36).slice(2) - cy.get('button[icon="plus-circle"]').click(); + cy.get('button[icon="plus-circle"]', {timeout: 300000}).click(); cy.get('input[name="firstName"]').type(random); @@ -38,7 +38,7 @@ describe("Lead", () => { const random2 = Math.random().toString(36).slice(2) - cy.get('button[icon="plus-circle"]').click(); + cy.get('button[icon="plus-circle"]',{timeout:300000}).click(); cy.get('input[name="firstName"]').type(random2); @@ -59,7 +59,7 @@ describe("Lead", () => { it("tag", () => { - cy.get("#customers>.crow") + cy.get("#customers>.crow",{timeout: 300000}) .eq(0) .get("#customersCheckBox") .click(); @@ -81,8 +81,8 @@ describe("Lead", () => { }) it("merge", () => { - - cy.get("#customers>.crow") + + cy.get("#customers>.crow",{timeout: 300000}) .eq(0) .within(() => { cy.get("input[type='checkbox']") From 2017ab91fd19fa85c5e80ce5590739ae43b9ed82 Mon Sep 17 00:00:00 2001 From: KhBaterdene <95618276+KhBaterdene@users.noreply.github.com> Date: Thu, 21 Sep 2023 01:39:48 +0800 Subject: [PATCH 08/50] pos ui cancel & return (#319) --- .../components/history/ReturnForm.tsx | 154 ++++++++++++++++ .../(orders)/components/history/ReturnOdd.tsx | 25 +++ .../components/history/historyItemAction.tsx | 11 +- .../components/history/orderCancel.tsx | 94 ++++++++++ .../components/history/orderReturn.tsx | 58 ++++++ .../components/history/paymentDetail.tsx | 36 ++++ pos/components/ui/alert-dialog.tsx | 6 +- pos/components/ui/badge.tsx | 2 +- pos/components/ui/dropdown-menu.tsx | 4 +- pos/modules/auth/graphql/queries.ts | 9 + pos/modules/orders/graphql/mutations.ts | 24 +++ pos/modules/orders/graphql/queries.ts | 14 ++ pos/package.json | 4 +- pos/store/history.store.ts | 6 +- pos/yarn.lock | 174 +++++++++--------- 15 files changed, 524 insertions(+), 97 deletions(-) create mode 100644 pos/app/(main)/(orders)/components/history/ReturnForm.tsx create mode 100644 pos/app/(main)/(orders)/components/history/ReturnOdd.tsx create mode 100644 pos/app/(main)/(orders)/components/history/orderCancel.tsx create mode 100644 pos/app/(main)/(orders)/components/history/orderReturn.tsx create mode 100644 pos/app/(main)/(orders)/components/history/paymentDetail.tsx diff --git a/pos/app/(main)/(orders)/components/history/ReturnForm.tsx b/pos/app/(main)/(orders)/components/history/ReturnForm.tsx new file mode 100644 index 0000000000..8864c20fc7 --- /dev/null +++ b/pos/app/(main)/(orders)/components/history/ReturnForm.tsx @@ -0,0 +1,154 @@ +import { queries } from "@/modules/auth/graphql" +import { mutations } from "@/modules/orders/graphql" +import { openReturnDialogAtom, paymentDetailAtom } from "@/store/history.store" +import { useMutation, useQuery } from "@apollo/client" +import { useAtomValue, useSetAtom } from "jotai" +import { useForm } from "react-hook-form" + +import { IPaidAmount } from "@/types/order.types" +import { PaymentType } from "@/types/payment.types" +import { ALL_BANK_CARD_TYPES } from "@/lib/constants" +import { + AlertDialogCancel, + AlertDialogFooter, +} from "@/components/ui/alert-dialog" +import { Button } from "@/components/ui/button" +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { LoaderIcon, LoaderWrapper } from "@/components/ui/loader" +import { useToast } from "@/components/ui/use-toast" + +import ReturnOdd from "./ReturnOdd" + +const ReturnForm = ({ + totalAmount, + _id, +}: { + totalAmount: number + _id: string +}) => { + const changeOpen = useSetAtom(openReturnDialogAtom) + + const { data, loading } = useQuery(queries.getPaymentTypes) + const { paymentTypes } = data?.currentConfig || {} + const notBankPts = paymentTypes?.filter( + (pt: PaymentType) => !ALL_BANK_CARD_TYPES.includes(pt.type) + ) + + const { cashAmount, paidAmounts } = useAtomValue(paymentDetailAtom) || {} + + let amounts: { [key: string]: number } = {} + + const nonBankPas = paidAmounts?.filter( + (pt: IPaidAmount) => !ALL_BANK_CARD_TYPES.includes(pt.type) + ) + + nonBankPas?.map((pa: { type: string; amount: number }) => { + amounts[pa.type] = pa.amount + }) + + const form = useForm({ + defaultValues: { cashAmount, ...amounts }, + }) + + const { onError } = useToast() + + const [orderReturn, { loading: loadingReturn }] = useMutation( + mutations.ordersReturn, + { + onError(err) { + onError(err) + changeOpen(null) + }, + onCompleted() { + changeOpen(null) + }, + refetchQueries: ["OrdersHistory"], + } + ) + + const onSubmit = (data: any) => { + const { cashAmount, ...rest } = data + const paidAmounts = Object.keys(rest).map((key: string) => ({ + type: key, + amount: isNaN(Number(rest[key])) ? 0 : Number(rest[key]), + })) + orderReturn({ + variables: { _id, cashAmount: Number(cashAmount || 0), paidAmounts }, + }) + } + + return ( +
+ {loading ? ( + + + + ) : ( + +
+ ( + + Cash + + + + + + )} + /> + {notBankPts.map((pt: PaymentType) => ( + ( + + {pt.title} + + + + + + )} + key={pt.type} + /> + ))} +
+ + +
+ + + + +
+
+
+ )} + + ) +} + +export default ReturnForm diff --git a/pos/app/(main)/(orders)/components/history/ReturnOdd.tsx b/pos/app/(main)/(orders)/components/history/ReturnOdd.tsx new file mode 100644 index 0000000000..4a599f1862 --- /dev/null +++ b/pos/app/(main)/(orders)/components/history/ReturnOdd.tsx @@ -0,0 +1,25 @@ +import { useWatch } from "react-hook-form" + +const ReturnOdd = ({ + totalAmount, + control, +}: { + totalAmount: number + control: any +}) => { + const results = useWatch({ control }) + // const formValues = getValues() + + const total = Object.values(results).reduce( + (acc: number, curr: any) => + isNaN(Number(curr)) ? acc : acc + Number(curr), + 0 + ) + return ( +
+ Зөрүү: {(totalAmount - total).toLocaleString()}₮ +
+ ) +} + +export default ReturnOdd diff --git a/pos/app/(main)/(orders)/components/history/historyItemAction.tsx b/pos/app/(main)/(orders)/components/history/historyItemAction.tsx index f73dfc229a..b10ad22a48 100644 --- a/pos/app/(main)/(orders)/components/history/historyItemAction.tsx +++ b/pos/app/(main)/(orders)/components/history/historyItemAction.tsx @@ -17,8 +17,12 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" +import OrderCancel from "./orderCancel" +import OrderReturn from "./orderReturn" +import PaymentDetail from "./paymentDetail" + const HistoryItemAction = ({ row }: CellContext) => { - const { _id, paidDate } = row.original || {} + const { _id, paidDate, number, totalAmount } = row.original || {} const router = useRouter() const setActiveOrder = useSetAtom(activeOrderAtom) const setOpenDetail = useSetAtom(detailIdAtom) @@ -65,7 +69,12 @@ const HistoryItemAction = ({ row }: CellContext) => { setOpenDetail(_id)}> Дэлгэрэнгүй + + + + + ) } diff --git a/pos/app/(main)/(orders)/components/history/orderCancel.tsx b/pos/app/(main)/(orders)/components/history/orderCancel.tsx new file mode 100644 index 0000000000..0d29ce1f68 --- /dev/null +++ b/pos/app/(main)/(orders)/components/history/orderCancel.tsx @@ -0,0 +1,94 @@ +import { mutations } from "@/modules/orders/graphql" +import { openCancelDialogAtom, paymentDetailAtom } from "@/store/history.store" +import { useMutation } from "@apollo/client" +import { useAtom, useAtomValue, useSetAtom } from "jotai" + +import { + AlertDialog, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "@/components/ui/alert-dialog" +import { Button } from "@/components/ui/button" +import { DropdownMenuItem } from "@/components/ui/dropdown-menu" +import { useToast } from "@/components/ui/use-toast" + +export const OrderCancelTrigger = ({ + loading, + _id, +}: { + loading?: boolean + _id: string +}) => { + const changeOpen = useSetAtom(openCancelDialogAtom) + const { cashAmount, mobileAmount, paidAmounts } = + useAtomValue(paymentDetailAtom) || {} + + const paidTotal = + (cashAmount || 0) + + (mobileAmount || 0) + + (paidAmounts?.reduce((total, el) => el.amount + total, 0) || 0) + + return ( + changeOpen(_id)} + disabled={loading || paidTotal > 0} + > + Устгах + + ) +} + +const OrderCancel = ({ _id, number }: { _id: string; number: string }) => { + const [open, changeOpen] = useAtom(openCancelDialogAtom) + const { onError } = useToast() + + const [orderCancel, { loading }] = useMutation(mutations.ordersCancel, { + variables: { + _id, + }, + onCompleted() { + changeOpen(null) + }, + onError(error) { + onError(error) + changeOpen(null) + }, + refetchQueries: ["OrdersHistory"], + }) + + return ( + changeOpen(open === _id ? null : _id)} + > + + + + Та {number} дугаартай захиалгыг устгахдаа итгэлтэй байна уу? + + + Энэ үйлдлийг буцаах боломжгүй. Энэ нь таны захиалгийг бүрмөсөн + устгана + + + + Болих + + + + + ) +} + +export default OrderCancel diff --git a/pos/app/(main)/(orders)/components/history/orderReturn.tsx b/pos/app/(main)/(orders)/components/history/orderReturn.tsx new file mode 100644 index 0000000000..d6f3ea04b1 --- /dev/null +++ b/pos/app/(main)/(orders)/components/history/orderReturn.tsx @@ -0,0 +1,58 @@ +import { openReturnDialogAtom } from "@/store/history.store" +import { useAtom, useSetAtom } from "jotai" + +import { + AlertDialog, + AlertDialogContent, + AlertDialogHeader, + AlertDialogTitle, +} from "@/components/ui/alert-dialog" +import { DropdownMenuItem } from "@/components/ui/dropdown-menu" + +import ReturnForm from "./ReturnForm" + +const OrderReturn = ({ + _id, + number, + totalAmount, +}: { + _id: string + number: string + totalAmount: number +}) => { + const [open, changeOpen] = useAtom(openReturnDialogAtom) + + return ( + changeOpen(open === _id ? null : _id)} + > + + + + Буцаалт хийх + {number} + + + + + + ) +} + +export const OrderReturnTrigger = ({ + _id, + paidDate, +}: { + _id: string + paidDate: string | null +}) => { + const changeOpen = useSetAtom(openReturnDialogAtom) + return ( + changeOpen(_id)} disabled={!paidDate}> + Буцааx + + ) +} + +export default OrderReturn diff --git a/pos/app/(main)/(orders)/components/history/paymentDetail.tsx b/pos/app/(main)/(orders)/components/history/paymentDetail.tsx new file mode 100644 index 0000000000..7ffacce4df --- /dev/null +++ b/pos/app/(main)/(orders)/components/history/paymentDetail.tsx @@ -0,0 +1,36 @@ +import { queries } from "@/modules/orders/graphql" +import { paymentDetailAtom } from "@/store/history.store" +import { useQuery } from "@apollo/client" +import { useSetAtom } from "jotai" + +import { OrderCancelTrigger } from "./orderCancel" +import { OrderReturnTrigger } from "./orderReturn" + +const PaymentDetail = ({ + _id, + paidDate, +}: { + _id: string + paidDate: string | null +}) => { + const setPaymentDetail = useSetAtom(paymentDetailAtom) + + const { loading } = useQuery(queries.historyItemDetail, { + variables: { + _id, + }, + onCompleted(data) { + const { orderDetail } = data || {} + setPaymentDetail(orderDetail || {}) + }, + }) + + return ( + <> + + + + ) +} + +export default PaymentDetail diff --git a/pos/components/ui/alert-dialog.tsx b/pos/components/ui/alert-dialog.tsx index 98205fff13..37a64799d4 100644 --- a/pos/components/ui/alert-dialog.tsx +++ b/pos/components/ui/alert-dialog.tsx @@ -24,7 +24,7 @@ const AlertDialogOverlay = React.forwardRef< >(({ className, children, ...props }, ref) => ( (({ className, ...props }, ref) => ( )) diff --git a/pos/components/ui/badge.tsx b/pos/components/ui/badge.tsx index 217baa657d..ae2c4501fd 100644 --- a/pos/components/ui/badge.tsx +++ b/pos/components/ui/badge.tsx @@ -4,7 +4,7 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/utils" const badgeVariants = cva( - "inline-flex items-center rounded-full border border-slate-200 px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 dark:border-slate-800 dark:focus:ring-slate-300", + "inline-flex items-center rounded-full border border-slate-200 px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2", { variants: { variant: { diff --git a/pos/components/ui/dropdown-menu.tsx b/pos/components/ui/dropdown-menu.tsx index e7d30015c9..b8cdd02196 100644 --- a/pos/components/ui/dropdown-menu.tsx +++ b/pos/components/ui/dropdown-menu.tsx @@ -65,7 +65,7 @@ const DropdownMenuContent = React.forwardRef< ref={ref} sideOffset={sideOffset} className={cn( - "z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50", + "z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ", className )} {...props} @@ -83,7 +83,7 @@ const DropdownMenuItem = React.forwardRef< (null) +export const paymentDetailAtom = atom(null) +export const openReturnDialogAtom = atom(null) + export const filterAtom = atom({ ...defaultFilter, statuses: ORDER_STATUSES.ALL, diff --git a/pos/yarn.lock b/pos/yarn.lock index 71223e9875..1f2cde95a6 100644 --- a/pos/yarn.lock +++ b/pos/yarn.lock @@ -371,62 +371,62 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@next/env@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/env/-/env-13.4.20-canary.18.tgz#184c1e8191e52d8bc69cc2996e4a1c1313f80584" - integrity sha512-v0LXMmRRLPUCyUdO3sVMwCTCY/1tp+kye+78drjkQm0MC+ujKyVemVS0HYH0kkz1oUibuD2gthlVgiokPL08pA== +"@next/env@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/env/-/env-13.5.1.tgz#337f5f3d325250f91ed23d783cbf8297800ee7d3" + integrity sha512-CIMWiOTyflFn/GFx33iYXkgLSQsMQZV4jB91qaj/TfxGaGOXxn8C1j72TaUSPIyN7ziS/AYG46kGmnvuk1oOpg== -"@next/eslint-plugin-next@13.4.19": - version "13.4.19" - resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.19.tgz#93d130c37b47fd120f6d111aee36a60611148df1" - integrity sha512-N/O+zGb6wZQdwu6atMZHbR7T9Np5SUFUjZqCbj0sXm+MwQO35M8TazVB4otm87GkXYs2l6OPwARd3/PUWhZBVQ== +"@next/eslint-plugin-next@13.5.2": + version "13.5.2" + resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-13.5.2.tgz#1571199796e23182e68f814ee6aab5f1eca16eae" + integrity sha512-Ew8DOUerJYGRo8pI84SVwn9wxxx8sH92AanCXSkkLJM2W0RJEWy+BqWSCfrlA/3ZIczEl4l4o4lOeTGBPYfBJg== dependencies: glob "7.1.7" -"@next/swc-darwin-arm64@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.20-canary.18.tgz#64c9ccd42fe2c21445fb2b9f0745ed34c79d9535" - integrity sha512-/pI6Dm8EN0hnEyyIl0ABeXSU2RKaV87XJPz1fy2wU+ccsQrb1lK8RWqapR/5nSM/2B7HcSB8pUDjzX51bwQfYg== - -"@next/swc-darwin-x64@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.20-canary.18.tgz#65ab55ad164656e1dd1775d60964797737c6b28d" - integrity sha512-sKPC/CwZntxQKYmdpV0mqzbxE8whGKd7onPR7PDFCOYCzaZhfEoAAWHwokBsv/MQ+CEtTy7x8sMvzlN8DgvNaA== - -"@next/swc-linux-arm64-gnu@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.20-canary.18.tgz#b98f723da4afa8b10c8112b309cc22a9baed3524" - integrity sha512-W7VQhzNK7elzFzzUCvO92gdtCVhZgU19FPdWma5HpCxvK4O03lakeGpEnxKzWyLDjy4LryUutLI2G/wyuT/cww== - -"@next/swc-linux-arm64-musl@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.20-canary.18.tgz#d33b018e584b925edc4f8b98f17af35a479ba97f" - integrity sha512-tiDRcKQJsQLBrA/xKk2FxZmQiqbzCweY6xQM3e8dXcUiP3Ou7zn5Cl5GGMld2BQolnuh/UrUj605PoO6gpEauA== - -"@next/swc-linux-x64-gnu@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.20-canary.18.tgz#1735c22f74b950283c596bba483ca4fb71c4d634" - integrity sha512-9KcUvZNGrl8bXgu/rh/Fpd6wZM+H+m0pJv62U+pu467u59dFsp9T3QwoCPSIK1NFGQy0SqsrUwJXoBLz0K4P+Q== - -"@next/swc-linux-x64-musl@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.20-canary.18.tgz#60fce126a2a879cbe5811bfa260904a0109dea9f" - integrity sha512-LR2ygXB+we+vFjBieWHziy6A0i1PFepG2f/+nVHdvYGKH2musGUvP+2SfalgdbLMmdfAbdlfzlp+/kXAo6iRWA== - -"@next/swc-win32-arm64-msvc@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.20-canary.18.tgz#f39c491719ba69fd3a3508f8cab46ffa89003a90" - integrity sha512-fnoInsl1nmRXbAEMp24edyLNBvL+7eptptXGt9on+klP21zNSclJmYoJUcW13z0BZWw9XJrmcGPOe79NbpwIlA== - -"@next/swc-win32-ia32-msvc@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.20-canary.18.tgz#f9505051a2a986625384264ea0da0c8f33f9368e" - integrity sha512-fNAoxBQsnV+GiTWcS7RG0nZPqCUnj9MszKAH6Lf5HA1fITkWN5Dp7R0ZRKF5xaeTUIJQPlzIHlhBg2cF9ZBTQA== - -"@next/swc-win32-x64-msvc@13.4.20-canary.18": - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.20-canary.18.tgz#139a7e898d3b4c66669fc73620f59feecb9a0d69" - integrity sha512-hI85vIDhZE44Exnvz/cqezz/yU0YrEyDPB1XbiRKXK8mWUwc4XQ/EE/0/Iofp4aT0+SzAZ+AmAFT0bwZJ75Gdw== +"@next/swc-darwin-arm64@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.1.tgz#dc21234afce27910a8d141e6a7ab5e821725dc94" + integrity sha512-Bcd0VFrLHZnMmJy6LqV1CydZ7lYaBao8YBEdQUVzV8Ypn/l5s//j5ffjfvMzpEQ4mzlAj3fIY+Bmd9NxpWhACw== + +"@next/swc-darwin-x64@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.1.tgz#29591ac96cc839903918621cf2d8f79c40cba3ca" + integrity sha512-uvTZrZa4D0bdWa1jJ7X1tBGIxzpqSnw/ATxWvoRO9CVBvXSx87JyuISY+BWsfLFF59IRodESdeZwkWM2l6+Kjg== + +"@next/swc-linux-arm64-gnu@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.1.tgz#349ce2714dc87d1db6911758652f3b2b0810dd6f" + integrity sha512-/52ThlqdORPQt3+AlMoO+omicdYyUEDeRDGPAj86ULpV4dg+/GCFCKAmFWT0Q4zChFwsAoZUECLcKbRdcc0SNg== + +"@next/swc-linux-arm64-musl@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.1.tgz#3f8bc223db9100887ffda998ad963820f39d944b" + integrity sha512-L4qNXSOHeu1hEAeeNsBgIYVnvm0gg9fj2O2Yx/qawgQEGuFBfcKqlmIE/Vp8z6gwlppxz5d7v6pmHs1NB6R37w== + +"@next/swc-linux-x64-gnu@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.1.tgz#4503d43d27aa178efb4a5c9efe229faae37d67a8" + integrity sha512-QVvMrlrFFYvLtABk092kcZ5Mzlmsk2+SV3xYuAu8sbTuIoh0U2+HGNhVklmuYCuM3DAAxdiMQTNlRQmNH11udw== + +"@next/swc-linux-x64-musl@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.1.tgz#a6e81f0df0be2fac78392705f487036695cf7b10" + integrity sha512-bBnr+XuWc28r9e8gQ35XBtyi5KLHLhTbEvrSgcWna8atI48sNggjIK8IyiEBO3KIrcUVXYkldAzGXPEYMnKt1g== + +"@next/swc-win32-arm64-msvc@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.1.tgz#9d8517fe1dd6aa348c7be36b933ad8195f961294" + integrity sha512-EQGeE4S5c9v06jje9gr4UlxqUEA+zrsgPi6kg9VwR+dQHirzbnVJISF69UfKVkmLntknZJJI9XpWPB6q0Z7mTg== + +"@next/swc-win32-ia32-msvc@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.1.tgz#42e711d00642f538edaabf9535545697d093b2f7" + integrity sha512-1y31Q6awzofVjmbTLtRl92OX3s+W0ZfO8AP8fTnITcIo9a6ATDc/eqa08fd6tSpFu6IFpxOBbdevOjwYTGx/AQ== + +"@next/swc-win32-x64-msvc@13.5.1": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.1.tgz#34bc139cf37704d595fe84eb803b1578a539e35e" + integrity sha512-+9XBQizy7X/GuwNegq+5QkkxAPV7SBsIwapVRQd9WSvvU20YO23B3bZUpevdabi4fsd25y9RJDDncljy/V54ww== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1124,15 +1124,15 @@ dependencies: "@babel/runtime" "^7.13.10" -"@rushstack/eslint-patch@^1.1.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz#16ab6c727d8c2020a5b6e4a176a243ecd88d8d69" - integrity sha512-0xd7qez0AQ+MbHatZTlI1gu5vkG8r7MYRUJAHPAHJBmGLs16zpkrpAVLvjQKQOqaXPDUBwOiJzNc00znHSCVBw== +"@rushstack/eslint-patch@^1.3.3": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.4.0.tgz#77e948b9760bd22736a5d26e335a690f76fda37b" + integrity sha512-cEjvTPU32OM9lUFegJagO0mRnIn+rbqrG89vV8/xLnLFX0DoR0r1oy5IlTga71Q7uT3Qus7qm7wgeiMT/+Irlg== -"@swc/helpers@0.5.1": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.1.tgz#e9031491aa3f26bfcc974a67f48bd456c8a5357a" - integrity sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg== +"@swc/helpers@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.2.tgz#85ea0c76450b61ad7d10a37050289eded783c27d" + integrity sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw== dependencies: tslib "^2.4.0" @@ -1955,19 +1955,19 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-config-next@^13.4.13: - version "13.4.19" - resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-13.4.19.tgz#f46be9d4bd9e52755f846338456132217081d7f8" - integrity sha512-WE8367sqMnjhWHvR5OivmfwENRQ1ixfNE9hZwQqNCsd+iM3KnuMc1V8Pt6ytgjxjf23D+xbesADv9x3xaKfT3g== +eslint-config-next@^13.5.2: + version "13.5.2" + resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-13.5.2.tgz#6cd120322deeecfcdbda5f6007f2bd9dbf890e03" + integrity sha512-kCF7k7fHBtFtxfP6J6AP6Mo0vW3CrFeoIuoZ7NHGIvLFc/RUaIspJ6inO/R33zE1o9t/lbJgTnsqnRB++sxCUQ== dependencies: - "@next/eslint-plugin-next" "13.4.19" - "@rushstack/eslint-patch" "^1.1.3" + "@next/eslint-plugin-next" "13.5.2" + "@rushstack/eslint-patch" "^1.3.3" "@typescript-eslint/parser" "^5.4.2 || ^6.0.0" eslint-import-resolver-node "^0.3.6" eslint-import-resolver-typescript "^3.5.2" - eslint-plugin-import "^2.26.0" - eslint-plugin-jsx-a11y "^6.5.1" - eslint-plugin-react "^7.31.7" + eslint-plugin-import "^2.28.1" + eslint-plugin-jsx-a11y "^6.7.1" + eslint-plugin-react "^7.33.2" eslint-plugin-react-hooks "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" eslint-config-prettier@^8.3.0: @@ -2004,7 +2004,7 @@ eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" -eslint-plugin-import@^2.26.0: +eslint-plugin-import@^2.28.1: version "2.28.1" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz#63b8b5b3c409bfc75ebaf8fb206b07ab435482c4" integrity sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A== @@ -2027,7 +2027,7 @@ eslint-plugin-import@^2.26.0: semver "^6.3.1" tsconfig-paths "^3.14.2" -eslint-plugin-jsx-a11y@^6.5.1: +eslint-plugin-jsx-a11y@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== @@ -2054,7 +2054,7 @@ eslint-plugin-jsx-a11y@^6.5.1: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== -eslint-plugin-react@^7.31.11, eslint-plugin-react@^7.31.7: +eslint-plugin-react@^7.31.11, eslint-plugin-react@^7.33.2: version "7.33.2" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== @@ -3009,13 +3009,13 @@ next-themes@^0.2.1: resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.2.1.tgz#0c9f128e847979daf6c67f70b38e6b6567856e45" integrity sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A== -next@13.4.20-canary.18: - version "13.4.20-canary.18" - resolved "https://registry.yarnpkg.com/next/-/next-13.4.20-canary.18.tgz#dbcab38e9e1652534bd602e3f6ac11b0dd2a7632" - integrity sha512-ebHSLdj2EusCFIuF0W385dvcFrof53d/kb2DNsLKtOVjiboXgMZ7ZKSLG0KE4lM08nTg0GTpNyRu5OAJB0oUWw== +next@^13.5.1: + version "13.5.1" + resolved "https://registry.yarnpkg.com/next/-/next-13.5.1.tgz#cf51e950017121f5404eedbde7d59d9ed310839b" + integrity sha512-GIudNR7ggGUZoIL79mSZcxbXK9f5pwAIPZxEM8+j2yLqv5RODg4TkmUlaKSYVqE1bPQueamXSqdC3j7axiTSEg== dependencies: - "@next/env" "13.4.20-canary.18" - "@swc/helpers" "0.5.1" + "@next/env" "13.5.1" + "@swc/helpers" "0.5.2" busboy "1.6.0" caniuse-lite "^1.0.30001406" postcss "8.4.14" @@ -3023,15 +3023,15 @@ next@13.4.20-canary.18: watchpack "2.4.0" zod "3.21.4" optionalDependencies: - "@next/swc-darwin-arm64" "13.4.20-canary.18" - "@next/swc-darwin-x64" "13.4.20-canary.18" - "@next/swc-linux-arm64-gnu" "13.4.20-canary.18" - "@next/swc-linux-arm64-musl" "13.4.20-canary.18" - "@next/swc-linux-x64-gnu" "13.4.20-canary.18" - "@next/swc-linux-x64-musl" "13.4.20-canary.18" - "@next/swc-win32-arm64-msvc" "13.4.20-canary.18" - "@next/swc-win32-ia32-msvc" "13.4.20-canary.18" - "@next/swc-win32-x64-msvc" "13.4.20-canary.18" + "@next/swc-darwin-arm64" "13.5.1" + "@next/swc-darwin-x64" "13.5.1" + "@next/swc-linux-arm64-gnu" "13.5.1" + "@next/swc-linux-arm64-musl" "13.5.1" + "@next/swc-linux-x64-gnu" "13.5.1" + "@next/swc-linux-x64-musl" "13.5.1" + "@next/swc-win32-arm64-msvc" "13.5.1" + "@next/swc-win32-ia32-msvc" "13.5.1" + "@next/swc-win32-x64-msvc" "13.5.1" node-abi@^3.3.0: version "3.47.0" From 1dee263985a9d459fab8b515ef6cc9ed4033f407 Mon Sep 17 00:00:00 2001 From: munkhsaikhan Date: Thu, 21 Sep 2023 01:51:04 +0800 Subject: [PATCH 09/50] fix another logic resync less orders --- packages/plugin-pos-api/src/configs.ts | 12 +- packages/plugin-pos-api/src/messageBroker.ts | 29 ++++- packages/plugin-pos-api/src/utils.ts | 10 +- .../graphql/resolvers/mutations/configs.ts | 107 +++++++++--------- .../src/graphql/resolvers/mutations/orders.ts | 6 +- 5 files changed, 86 insertions(+), 78 deletions(-) diff --git a/packages/plugin-pos-api/src/configs.ts b/packages/plugin-pos-api/src/configs.ts index 69178fa9a8..cbcb131b2b 100644 --- a/packages/plugin-pos-api/src/configs.ts +++ b/packages/plugin-pos-api/src/configs.ts @@ -5,12 +5,7 @@ import { generateModels } from './connectionResolver'; import { initBroker } from './messageBroker'; import { getSubdomain } from '@erxes/api-utils/src/core'; import * as permissions from './permissions'; -import { - posInit, - posSyncConfig, - posSyncOrders, - unfetchOrderInfo -} from './routes'; +import { posInit, posSyncConfig, unfetchOrderInfo } from './routes'; import afterMutations from './afterMutations'; import automations from './automations'; import forms from './forms'; @@ -32,10 +27,7 @@ export default { { path: `/pos-sync-config`, method: posSyncConfig }, { path: `/file-export`, method: exportFileRunner } ], - postHandlers: [ - { path: `/api/unfetch-order-info`, method: unfetchOrderInfo }, - { path: `/pos-sync-orders`, method: posSyncOrders } - ], + postHandlers: [{ path: `/api/unfetch-order-info`, method: unfetchOrderInfo }], graphql: async sd => { serviceDiscovery = sd; return { diff --git a/packages/plugin-pos-api/src/messageBroker.ts b/packages/plugin-pos-api/src/messageBroker.ts index 86ad3f564f..aa054e978a 100644 --- a/packages/plugin-pos-api/src/messageBroker.ts +++ b/packages/plugin-pos-api/src/messageBroker.ts @@ -20,7 +20,7 @@ export const initBroker = async cl => { consumeQueue('pos:createOrUpdateOrders', async ({ subdomain, data }) => { const models = await generateModels(subdomain); - const { action, posToken, responses, order, items, oldBranchId } = data; + const { action, posToken, responses, order, items } = data; const pos = await models.Pos.findOne({ token: posToken }).lean(); // ====== if (action === 'statusToDone') @@ -37,8 +37,7 @@ export const initBroker = async cl => { items, pos, posToken, - responses, - oldBranchId + responses }); return { @@ -46,6 +45,30 @@ export const initBroker = async cl => { }; }); + consumeQueue('pos:createOrUpdateOrdersMany', async ({ subdomain, data }) => { + const models = await generateModels(subdomain); + const { posToken, syncOrders } = data; + const pos = await models.Pos.findOne({ token: posToken }).lean(); + + for (const perData of syncOrders) { + const { responses, order, items } = perData; + + await syncOrderFromClient({ + subdomain, + models, + order, + items, + pos, + posToken, + responses + }); + } + + return { + status: 'success' + }; + }); + consumeRPCQueue( 'pos:getModuleRelation', async ({ data: { module, target } }) => { diff --git a/packages/plugin-pos-api/src/utils.ts b/packages/plugin-pos-api/src/utils.ts index b80584c2aa..342004c0ae 100644 --- a/packages/plugin-pos-api/src/utils.ts +++ b/packages/plugin-pos-api/src/utils.ts @@ -466,8 +466,8 @@ const syncInventoriesRem = async ({ } if ( - (!oldBranchId && newOrder.branchId) || - (oldBranchId && oldBranchId !== newOrder.branchId) + newOrder.branchId && + (!oldBranchId || oldBranchId !== newOrder.branchId) ) { sendInventoriesMessage({ subdomain, @@ -508,8 +508,7 @@ export const syncOrderFromClient = async ({ items, pos, posToken, - responses, - oldBranchId + responses }: { subdomain: string; models: IModels; @@ -518,9 +517,10 @@ export const syncOrderFromClient = async ({ pos: IPosDocument; posToken: string; responses; - oldBranchId: string; }) => { const oldOrder = await models.PosOrders.findOne({ _id: order._id }).lean(); + const oldBranchId = oldOrder ? oldOrder.branchId : ''; + for (const response of responses || []) { if (response && response._id) { await sendEbarimtMessage({ diff --git a/packages/plugin-posclient-api/src/graphql/resolvers/mutations/configs.ts b/packages/plugin-posclient-api/src/graphql/resolvers/mutations/configs.ts index 11293f068a..fe9e531406 100644 --- a/packages/plugin-posclient-api/src/graphql/resolvers/mutations/configs.ts +++ b/packages/plugin-posclient-api/src/graphql/resolvers/mutations/configs.ts @@ -10,12 +10,12 @@ import { } from '../../utils/syncUtils'; import { IContext } from '../../../connectionResolver'; import { init as initBrokerMain } from '@erxes/api-utils/src/messageBroker'; -import { initBroker } from '../../../messageBroker'; +import { initBroker, sendPosMessage } from '../../../messageBroker'; import { IOrderItemDocument } from '../../../models/definitions/orderItems'; -import { ORDER_STATUSES } from '../../../models/definitions/constants'; import { redis } from '@erxes/api-utils/src/serviceDiscovery'; import { sendRequest } from '@erxes/api-utils/src/requests'; import { app } from '../../../configs'; +import { IPutResponseDocument } from '../../../models/definitions/putResponses'; const configMutations = { posConfigsFetch: async ( @@ -129,75 +129,70 @@ const configMutations = { }, async syncOrders(_root, _param, { models, subdomain, config }: IContext) { + const unSyncedPutResponses: IPutResponseDocument[] = await models.PutResponses.find( + { synced: { $ne: true } } + ) + .sort({ paidDate: 1 }) + .limit(100) + .lean(); + const putResContentIds = unSyncedPutResponses.map(pr => pr.contentId); + const orderFilter = { - synced: false, - status: { $in: ORDER_STATUSES.FULL }, - paidDate: { $exists: true, $ne: null } + $and: [ + { posToken: config.token }, + { + $or: [ + { + synced: { $ne: true }, + paidDate: { $exists: true, $ne: null } + }, + { _id: { $in: putResContentIds } } + ] + } + ] }; + let sumCount = await models.Orders.find({ ...orderFilter }).count(); const orders = await models.Orders.find({ ...orderFilter }) .sort({ paidDate: 1 }) .limit(100) .lean(); - let kind = 'order'; - let putResponses = []; - - if (orders.length) { - const orderIds = orders.map(o => o._id); - const orderItems: IOrderItemDocument[] = await models.OrderItems.find({ - orderId: { $in: orderIds } - }).lean(); - - for (const order of orders) { - order.items = (orderItems || []).filter( - item => item.orderId === order._id - ); - } + const data: any[] = []; + const orderIds = orders.map(o => o._id); + const orderItems: IOrderItemDocument[] = await models.OrderItems.find({ + orderId: { $in: orderIds } + }).lean(); + + const putResponses = await models.PutResponses.find({ + contentId: { $in: orderIds } + }).lean(); + + for (const order of orders) { + const perData: any = { + posToken: config.token, + order + }; + perData.items = (orderItems || []).filter( + item => item.orderId === order._id + ); + perData.responses = (putResponses || []).filter( + pr => pr.contentId === order._id + ); - putResponses = await models.PutResponses.find({ - contentId: { $in: orderIds }, - synced: false - }).lean(); - } else { - kind = 'putResponse'; - sumCount = await models.PutResponses.find({ synced: false }).count(); - putResponses = await models.PutResponses.find({ synced: false }) - .sort({ paidDate: 1 }) - .limit(100) - .lean(); + data.push(perData); } - const address = await getServerAddress(subdomain); - - try { - const response = await sendRequest({ - url: `${address}/pos-sync-orders`, - method: 'post', - headers: { 'POS-TOKEN': config.token || '' }, - body: { token: config.token, orders, putResponses } + if (data.length) { + await sendPosMessage({ + subdomain, + action: 'createOrUpdateOrdersMany', + data: { posToken: config.token, syncOrders: data } }); - - const { error, resOrderIds, putResponseIds } = response; - - if (error) { - throw new Error(error); - } - - await models.Orders.updateMany( - { _id: { $in: resOrderIds } }, - { $set: { synced: true } } - ); - await models.PutResponses.updateMany( - { _id: { $in: putResponseIds } }, - { $set: { synced: true } } - ); - } catch (e) { - throw new Error(e.message); } return { - kind, + kind: 'order', sumCount, syncedCount: orders.length }; diff --git a/packages/plugin-posclient-api/src/graphql/resolvers/mutations/orders.ts b/packages/plugin-posclient-api/src/graphql/resolvers/mutations/orders.ts index 63833e2a26..5a70d14adb 100644 --- a/packages/plugin-posclient-api/src/graphql/resolvers/mutations/orders.ts +++ b/packages/plugin-posclient-api/src/graphql/resolvers/mutations/orders.ts @@ -1,3 +1,4 @@ +import { getPureDate } from '@erxes/api-utils/src'; import { debugError } from '@erxes/api-utils/src/debuggers'; import { graphqlPubsub } from '../../../configs'; import { IModels } from '../../../connectionResolver'; @@ -376,9 +377,7 @@ const orderMutations = { throw new Error('Can not change cause: order is not paid'); } - const oldBranchId = order.branchId; - - if (params.dueDate && params.dueDate < new Date()) { + if (params.dueDate && params.dueDate < getPureDate(new Date())) { throw new Error('due date must be in future'); } @@ -410,7 +409,6 @@ const orderMutations = { data: { posToken: config.token, action: 'makePayment', - oldBranchId, order, items: await models.OrderItems.find({ orderId: params._id From bd003b05b86b6eb4b1d30c2eebe493bf8a2b208d Mon Sep 17 00:00:00 2001 From: munkhsaikhan Date: Thu, 21 Sep 2023 02:13:45 +0800 Subject: [PATCH 10/50] clean code --- packages/plugin-pos-api/src/routes.ts | 82 --------------------------- 1 file changed, 82 deletions(-) diff --git a/packages/plugin-pos-api/src/routes.ts b/packages/plugin-pos-api/src/routes.ts index 497a8a2016..9db24c8c8d 100644 --- a/packages/plugin-pos-api/src/routes.ts +++ b/packages/plugin-pos-api/src/routes.ts @@ -300,88 +300,6 @@ export const posSyncConfig = async (req, res) => { return res.send({ error: 'wrong type' }); }; -export const posSyncOrders = async (req, res) => { - const subdomain = getSubdomain(req); - const models = await generateModels(subdomain); - - const token = req.headers['pos-token']; - const { orders, putResponses } = req.body; - - const pos = await models.Pos.findOne({ token }).lean(); - - if (!pos) { - return res.send({ error: 'not found pos' }); - } - - const resOrderIds: any[] = []; - const putResponseIds: any[] = []; - - try { - let orderBulkOps: Array<{ - updateOne: { - filter: { _id: string }; - update: any; - upsert: true; - }; - }> = []; - - for (const order of orders) { - resOrderIds.push(order._id); - orderBulkOps.push({ - updateOne: { - filter: { _id: order._id }, - update: { - $set: { - ...order, - posToken: token, - branchId: pos.branchId, - departmentId: pos.departmentId - } - }, - upsert: true - } - }); - } - - if (orderBulkOps.length) { - await models.PosOrders.bulkWrite(orderBulkOps); - } - - let bulkOps: Array<{ - updateOne: { - filter: { _id: string }; - update: any; - upsert: true; - }; - }> = []; - - for (const putResponse of putResponses) { - putResponseIds.push(putResponse._id); - bulkOps.push({ - updateOne: { - filter: { _id: putResponse._id }, - update: { $set: { ...putResponse, posToken: token } }, - upsert: true - } - }); - } - - if (bulkOps.length) { - await sendEbarimtMessage({ - subdomain, - action: 'putresponses.bulkWrite', - data: { - bulkOps - } - }); - } - - return res.send({ resOrderIds, putResponseIds }); - } catch (e) { - return res.send({ error: e.message }); - } -}; - export const unfetchOrderInfo = async (req, res) => { const subdomain = getSubdomain(req); const models = await generateModels(subdomain); From 1c93934b4b6f589853b119544d961d0d3de76b2b Mon Sep 17 00:00:00 2001 From: munkhsaikhan Date: Thu, 21 Sep 2023 03:00:06 +0800 Subject: [PATCH 11/50] fix cover filter --- .../src/graphql/resolvers/queries/covers.ts | 10 ++++++++-- .../src/graphql/resolvers/queries/covers.ts | 20 +++++++++++++------ pos/app/(main)/cover/components/coverCU.tsx | 2 +- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/plugin-pos-api/src/graphql/resolvers/queries/covers.ts b/packages/plugin-pos-api/src/graphql/resolvers/queries/covers.ts index b7ad9d8cde..d7b25f3c41 100644 --- a/packages/plugin-pos-api/src/graphql/resolvers/queries/covers.ts +++ b/packages/plugin-pos-api/src/graphql/resolvers/queries/covers.ts @@ -19,12 +19,18 @@ const generateFilterQuery = async (models, params) => { query.userId = userId; } + const dateQry: any = {}; + if (startDate) { - query.endDate = { $gte: getPureDate(startDate) }; + dateQry.$gte = getPureDate(startDate); } if (endDate) { - query.beginDate = { $lte: getPureDate(endDate) }; + dateQry.$lte = getPureDate(endDate); + } + + if (Object.keys(dateQry).length) { + query.endDate = dateQry; } return query; diff --git a/packages/plugin-posclient-api/src/graphql/resolvers/queries/covers.ts b/packages/plugin-posclient-api/src/graphql/resolvers/queries/covers.ts index 2f84a0f090..82e8ae048c 100644 --- a/packages/plugin-posclient-api/src/graphql/resolvers/queries/covers.ts +++ b/packages/plugin-posclient-api/src/graphql/resolvers/queries/covers.ts @@ -5,20 +5,28 @@ const coverQueries = { async covers(_root, params, { models, config, posUser }: IContext) { const selector: any = { posToken: config.token }; - if (params.userId) { - selector.userId = params.userId; + const { userId, startDate, endDate } = params; + + if (userId) { + selector.userId = userId; } if (!config.adminIds.includes(posUser._id)) { selector.userId = posUser._id; } - if (params.startDate) { - selector.beginDate = { $gte: params.startDate }; + const dateQry: any = {}; + + if (startDate) { + dateQry.$gte = getPureDate(startDate); + } + + if (endDate) { + dateQry.$lte = getPureDate(endDate); } - if (params.endDate) { - selector.endDate = { $lte: params.endDate }; + if (Object.keys(dateQry).length) { + selector.endDate = dateQry; } return paginate( diff --git a/pos/app/(main)/cover/components/coverCU.tsx b/pos/app/(main)/cover/components/coverCU.tsx index 6b211c0362..76d5528cf7 100644 --- a/pos/app/(main)/cover/components/coverCU.tsx +++ b/pos/app/(main)/cover/components/coverCU.tsx @@ -81,7 +81,7 @@ const CoverCU = () => { }) } - if (!beginDate) return null + if (!endDate) return null return ( diff --git a/packages/ui-cards/src/boards/components/portable/ConvertTrigger.tsx b/packages/ui-cards/src/boards/components/portable/ConvertTrigger.tsx index 4fbe51a27f..1eb024d359 100644 --- a/packages/ui-cards/src/boards/components/portable/ConvertTrigger.tsx +++ b/packages/ui-cards/src/boards/components/portable/ConvertTrigger.tsx @@ -1,8 +1,8 @@ import AddForm from '../../containers/portable/AddForm'; +import Button from '@erxes/ui/src/components/Button'; +import { IOptions } from '../../types'; import ModalTrigger from '@erxes/ui/src/components/ModalTrigger'; import React from 'react'; -import { IOptions } from '../../types'; -import Button from '@erxes/ui/src/components/Button'; type Props = { relType: string; @@ -39,18 +39,17 @@ export default function ConvertTrigger(props: Props) { if (url) { return ( - + ); } - const trigger = ; + const trigger = {title}; const content = formProps => ( Date: Thu, 21 Sep 2023 18:00:23 +0800 Subject: [PATCH 22/50] fix(imap): calendar --- .../conversationDetail/workarea/mail/style.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/ui-inbox/src/inbox/components/conversationDetail/workarea/mail/style.ts b/packages/ui-inbox/src/inbox/components/conversationDetail/workarea/mail/style.ts index 3b604ee92e..2a29d57baf 100644 --- a/packages/ui-inbox/src/inbox/components/conversationDetail/workarea/mail/style.ts +++ b/packages/ui-inbox/src/inbox/components/conversationDetail/workarea/mail/style.ts @@ -9,6 +9,20 @@ import styledTS from 'styled-components-ts'; const Content = styled.div` padding: ${dimensions.unitSpacing}px ${dimensions.coreSpacing}px; overflow: auto; + + a { + &.primary-button-text { + color: #fff; + } + &.grey-button-text { + color: #5f6368; + } + + span { + font-size: 14px; + cursor: pointer; + } + } `; const SmallContent = styledTS<{ toggle?: boolean }>(styled.div)` From b1fbf567764edf441dbf6a7c352364ba24c19298 Mon Sep 17 00:00:00 2001 From: batmnkh2344 Date: Thu, 21 Sep 2023 18:32:21 +0800 Subject: [PATCH 23/50] fix reply was showing twice after sent --- .../integrations/components/mail/MailForm.tsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/ui-inbox/src/settings/integrations/components/mail/MailForm.tsx b/packages/ui-inbox/src/settings/integrations/components/mail/MailForm.tsx index 2d5974a560..64423709af 100644 --- a/packages/ui-inbox/src/settings/integrations/components/mail/MailForm.tsx +++ b/packages/ui-inbox/src/settings/integrations/components/mail/MailForm.tsx @@ -97,6 +97,7 @@ type State = { emailSignature: string; name: string; showReply: string; + isRepliesRetrieved: boolean; }; class MailForm extends React.Component { @@ -173,7 +174,8 @@ class MailForm extends React.Component { fileIds: [], name: `mail_${mailKey}`, - showReply: `reply_${mailKey}` + showReply: `reply_${mailKey}`, + isRepliesRetrieved: false }; } @@ -199,7 +201,7 @@ class MailForm extends React.Component { const content = localStorage.getItem(name); if (content && content !== this.state.content) { - this.setState({ content }); + this.setState({ content: '' }); } if ((content || '').length === 0 && showPrevEmails) { @@ -261,6 +263,9 @@ class MailForm extends React.Component { getReplies(messageId?: string) { const { mails = [] } = this.props; + const { isRepliesRetrieved } = this.state; + this.setState({ isRepliesRetrieved: !isRepliesRetrieved }); + if (!messageId) { return ''; } @@ -348,7 +353,8 @@ class MailForm extends React.Component { cc, bcc, subject, - kind + kind, + isRepliesRetrieved } = this.state; if (!to) { @@ -370,7 +376,11 @@ class MailForm extends React.Component { const subjectValue = subject || mailData.subject || ''; const updatedContent = - isForward || !isReply ? content : this.getReplies(messageId); + isForward || !isReply + ? content + : !isRepliesRetrieved + ? this.getReplies(messageId) + : content; const variables = { headerId, From 4d973db9d2c7d32d6f30290fe84f31ac5be5d978 Mon Sep 17 00:00:00 2001 From: KhBaterdene <95618276+KhBaterdene@users.noreply.github.com> Date: Fri, 22 Sep 2023 09:40:29 +0800 Subject: [PATCH 24/50] Pos payment (#323) --- pos/app/(main)/checkout/page.tsx | 16 ++- pos/app/(main)/cover/components/amounts.tsx | 17 ++- .../cover/components/bank-amount-ui.tsx | 1 - .../cover/components/cover-item-action.tsx | 30 +++--- pos/app/(main)/main.tsx | 5 +- pos/app/(main)/market.tsx | 2 +- pos/app/reciept/components/Ebarimt.tsx | 4 +- pos/app/reciept/cover/page.tsx | 6 +- pos/app/reciept/ebarimt/page.tsx | 43 ++++---- pos/components/header/logo.tsx | 11 +- pos/modules/auth/chooseConfig.tsx | 101 +++++++++++++----- .../components/buyAction/buyAction.main.tsx | 36 ++++--- .../checkout/components/orderFinish/index.tsx | 2 +- .../paymentType/cancelPayment.market.tsx | 44 ++++++++ .../paymentType/paidType.market.tsx | 14 +-- .../components/paymentType/paidTypes.tsx | 7 +- .../components/paymentType/paymentSheet.tsx | 4 +- .../paymentType/paymentType.main.tsx | 10 +- .../paymentType/paymentType.market.tsx | 54 +++++----- .../paymentType/selectPaymentType.main.tsx | 9 +- pos/modules/checkout/hooks/useAddPayment.tsx | 10 +- .../checkout/hooks/useHandlePayment.tsx | 18 +++- .../hooks/usePossiblePaymentTerms.tsx | 5 +- pos/modules/checkout/market.tsx | 2 +- pos/modules/orders/OrderDetail.main.tsx | 31 ------ pos/modules/orders/OrderDetail.tsx | 37 +++++++ .../DeliveryInputs/ShowDeliveryInfo.tsx | 9 +- .../components/DeliveryInputs/index.tsx | 38 ++++--- pos/modules/orders/graphql/queries.ts | 3 +- pos/modules/orders/hooks/useOrderDetail.tsx | 50 --------- 30 files changed, 361 insertions(+), 258 deletions(-) create mode 100644 pos/modules/checkout/components/paymentType/cancelPayment.market.tsx delete mode 100644 pos/modules/orders/OrderDetail.main.tsx create mode 100644 pos/modules/orders/OrderDetail.tsx delete mode 100644 pos/modules/orders/hooks/useOrderDetail.tsx diff --git a/pos/app/(main)/checkout/page.tsx b/pos/app/(main)/checkout/page.tsx index a16d2d53e5..efea14ac91 100644 --- a/pos/app/(main)/checkout/page.tsx +++ b/pos/app/(main)/checkout/page.tsx @@ -1,14 +1,15 @@ "use client" -import { useMemo } from "react" +import { useEffect } from "react" import { useSearchParams } from "next/navigation" import EbarimtMain from "@/modules/checkout/components/ebarimt/ebarimt.main" import PaymentType from "@/modules/checkout/components/paymentType/paymentType.main" import SelectPaymentTypeMain from "@/modules/checkout/components/paymentType/selectPaymentType.main" import usePaymentLabel from "@/modules/checkout/hooks/usePaymentLabel" -import OrderDetail from "@/modules/orders/OrderDetail.main" +import OrderDetail from "@/modules/orders/OrderDetail" import { currentPaymentTypeAtom } from "@/store" -import { useAtomValue } from "jotai" +import { activeOrderAtom } from "@/store/order.store" +import { useAtomValue, useSetAtom } from "jotai" import Detail from "./components/Detail" @@ -17,11 +18,16 @@ const Checkout = () => { const { getLabel } = usePaymentLabel() const searchValue = useSearchParams() const _id = searchValue.get("orderId") + const setActiveOrderId = useSetAtom(activeOrderAtom) - const variables = useMemo(() => ({ _id }), [_id]) + useEffect(() => { + if (_id) { + setActiveOrderId(_id) + } + }, [_id, setActiveOrderId]) return ( - +

diff --git a/pos/app/(main)/cover/components/amounts.tsx b/pos/app/(main)/cover/components/amounts.tsx index 42d9702be1..ab7385a93b 100644 --- a/pos/app/(main)/cover/components/amounts.tsx +++ b/pos/app/(main)/cover/components/amounts.tsx @@ -1,18 +1,27 @@ +import { coverConfigAtom } from "@/store/config.store" import { isCoverAmountsFetchedAtom } from "@/store/cover.store" import { useAtomValue } from "jotai" +import { BANK_CARD_TYPES } from "@/lib/constants" + import Khaan from "./Khaan" import CashAmounts from "./cash-amounts" import CustomAmounts from "./custom-amounts" import Description from "./description" import Golomt from "./golomt" -import TDB from "./tdb" +import Tdb from "./tdb" + +const { KHANBANK, GOLOMT, TDB } = BANK_CARD_TYPES const Amounts = () => { const isFetched = useAtomValue(isCoverAmountsFetchedAtom) + const { paymentTypes } = useAtomValue(coverConfigAtom) || {} if (!isFetched) return null + const showBank = (type: string) => + paymentTypes?.find((pt) => pt.type === type) + return (
@@ -21,9 +30,9 @@ const Amounts = () => {
- - - + {showBank(KHANBANK) && } + {showBank(GOLOMT) && } + {showBank(TDB) && }
) diff --git a/pos/app/(main)/cover/components/bank-amount-ui.tsx b/pos/app/(main)/cover/components/bank-amount-ui.tsx index f5645f527f..425e77a7f7 100644 --- a/pos/app/(main)/cover/components/bank-amount-ui.tsx +++ b/pos/app/(main)/cover/components/bank-amount-ui.tsx @@ -29,7 +29,6 @@ const BankAmountUi = ({ const [currentAmounts, setCurrentAmounts] = useAtom(currentAmountsAtom) const calcAmount = (calcAmounts || {})[type] || 0 const currentAmount = (currentAmounts || {})[type] || 0 - return (
diff --git a/pos/app/(main)/cover/components/cover-item-action.tsx b/pos/app/(main)/cover/components/cover-item-action.tsx index 21b075ab66..5df302d024 100644 --- a/pos/app/(main)/cover/components/cover-item-action.tsx +++ b/pos/app/(main)/cover/components/cover-item-action.tsx @@ -25,6 +25,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" +import { ScrollArea } from "@/components/ui/scroll-area" import { Sheet, SheetContent } from "@/components/ui/sheet" import { toast, useToast } from "@/components/ui/use-toast" @@ -35,11 +36,6 @@ const CoverItemAction = ({ row }: { row: Row }) => { const [actionType, setActionType] = useState("") const [openSheet, setOpenSheet] = useState(false) const { onError } = useToast() - // const { iframeRef } = useReciept({ - // onCompleted() { - // setOpenSheet(false) - // }, - // }) const options = { variables: { @@ -88,7 +84,7 @@ const CoverItemAction = ({ row }: { row: Row }) => { {disabled ? ( "Өөрчлөх" ) : ( - Өөрчлөх + Өөрчлөх )} }) => { open={openSheet} onOpenChange={() => setOpenSheet((prev) => !prev)} > - - {openSheet && ( -