Skip to content

Commit 8a9db63

Browse files
committed
Support sync recent updated/created contacts
1 parent 172cad4 commit 8a9db63

File tree

8 files changed

+296
-15
lines changed

8 files changed

+296
-15
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "pipedrive-embeddable-ringcentral-phone-spa",
3-
"version": "2.0.0",
3+
"version": "2.0.1",
44
"description": "Add RingCentral Embeddable Voice widgets to Pipedrive",
55
"keywords": [
66
"RingCentral",

src/config.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
search,
4141
match
4242
} from 'ringcentral-embeddable-extension-common/src/common/db'
43+
import initReact from './lib/react-entry'
4344

4445
let {
4546
pageSize = 100
@@ -244,7 +245,9 @@ export function thirdPartyServiceConfig (serviceName) {
244245
} else if (path === '/contacts') {
245246
let isMannulSync = _.get(data, 'body.type') === 'manual'
246247
if (isMannulSync) {
247-
reSyncData()
248+
window.postMessage({
249+
type: 'rc-show-sync-menu'
250+
}, '*')
248251
rc.postMessage({
249252
type: 'rc-post-message-response',
250253
responseId: data.requestId,
@@ -362,6 +365,7 @@ export async function initThirdParty () {
362365
notifyRCAuthed()
363366
}
364367
upgrade()
368+
initReact()
365369
}
366370

367371
// init call with ringcenntral button at page bottom

src/features/contacts.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const {
3030
serviceName
3131
} = thirdPartyConfigs
3232
const lastSyncOffset = 'last-sync-offset'
33+
const lastSyncOffsetRecent = 'last-sync-offset-recent'
3334

3435
/**
3536
* convert pipedrive contact data to ringcentral format data
@@ -103,36 +104,47 @@ export const getContact = async function (start = 0) {
103104
let token = getSessionToken()
104105
// let self = await getSelfInfo(token)
105106
// let uid = self.data.id
106-
let url = `${host}/api/v1/persons/list:(cc_email,active_flag,id,name,label,org_id,email,phone,closed_deals_count,open_deals_count,next_activity_date,owner_id,next_activity_time)?session_token=${token}&strict_mode=true&user_id=&sort=&label=&start=${start}&type=person&_=${+new Date()}`
107+
const sort = encodeURIComponent('update_time ASC')
108+
let url = `${host}/api/v1/persons/list:(cc_email,active_flag,id,name,label,org_id,email,phone,closed_deals_count,open_deals_count,update_time,next_activity_date,owner_id,next_activity_time)?session_token=${token}&strict_mode=true&user_id=&sort=${sort}&label=&start=${start}&type=person&_=${+new Date()}`
107109
return fetch.get(url)
108110
}
109111

110-
async function fetchAllContacts () {
112+
async function fetchAllContacts (recent) {
111113
if (window.rc.isFetchingContacts) {
112114
return
113115
}
114116
console.debug('running fetchAllContacts')
115117
window.rc.isFetchingContacts = true
116118
loadingContacts()
117-
let start = await getCache(lastSyncOffset) || 0
119+
const lastSync = recent
120+
? lastSyncOffsetRecent
121+
: lastSyncOffset
122+
let start = recent
123+
? 0
124+
: await getCache(lastSync) || 0
118125
let hasMore = true
119-
await remove().catch(e => {
120-
console.log(e.stack)
121-
})
126+
if (!recent && !start) {
127+
await remove().catch(e => {
128+
console.log(e.stack)
129+
})
130+
}
122131
while (hasMore) {
123132
let res = await getContact(start).catch(console.debug)
133+
console.log(res, 'res')
124134
if (!res || !res.data) {
125135
window.rc.isFetchingContacts = false
126136
return
127137
}
128138
let final = formatData(res)
129139
start = _.get(res, 'additional_data.pagination.start') + _.get(res, 'additional_data.pagination.limit')
130-
hasMore = _.get(res, 'additional_data.pagination.more_items_in_collection')
140+
hasMore = recent
141+
? false
142+
: _.get(res, 'additional_data.pagination.more_items_in_collection')
131143
console.debug('fetching, start:', start, ', has more:', hasMore)
132144
await insert(final).catch(console.debug)
133-
await setCache(lastSyncOffset, start, 'never')
145+
await setCache(lastSync, start, 'never')
134146
}
135-
await setCache(lastSyncOffset, 0, 'never')
147+
await setCache(lastSync, 0, 'never')
136148
let now = Date.now()
137149
window.rc.syncTimestamp = now
138150
await ls.set('syncTimestamp', now)
@@ -256,12 +268,12 @@ function stopLoadingContacts () {
256268
}
257269
}
258270

259-
export function reSyncData () {
271+
export function reSyncData (recent) {
260272
if (!window.rc.userAuthed) {
261273
showAuthBtn()
262274
return
263275
}
264-
fetchAllContacts()
276+
fetchAllContacts(recent)
265277
}
266278

267279
function notifyReSyncContacts () {

src/lib/box.styl

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
2+
for $i, $index in 5 16 32
3+
4+
//padding
5+
.pd{$index+1}
6+
padding ($i)px
7+
8+
.pd{$index+1}x
9+
padding-left ($i)px
10+
padding-right ($i)px
11+
12+
.pd{$index+1}l
13+
padding-left ($i)px
14+
15+
.pd{$index+1}r
16+
padding-right ($i)px
17+
18+
.pd{$index+1}y
19+
padding-top ($i)px
20+
padding-bottom ($i)px
21+
22+
.pd{$index+1}t
23+
padding-top ($i)px
24+
25+
.pd{$index+1}b
26+
padding-bottom ($i)px
27+
28+
//margin
29+
.mg{$index+1}
30+
margin ($i)px
31+
32+
.mg{$index+1}x
33+
margin-left ($i)px
34+
margin-right ($i)px
35+
36+
.mg{$index+1}l
37+
margin-left ($i)px
38+
39+
.mg{$index+1}r
40+
margin-right ($i)px
41+
42+
.mg{$index+1}y
43+
margin-top ($i)px
44+
margin-bottom ($i)px
45+
46+
.mg{$index+1}t
47+
margin-top ($i)px
48+
49+
.mg{$index+1}b
50+
margin-bottom ($i)px
51+
52+
.mg-auto
53+
margin-left auto
54+
margin-right auto
55+
.mg0
56+
margin 0
57+
.pd0
58+
padding 0
59+
60+
.block
61+
display block
62+
63+
.inline
64+
display inline-block
65+
66+
.iblock
67+
display inline-block
68+
vertical-align middle
69+
70+
.ibblock
71+
display inline-block
72+
vertical-align baseline
73+
74+
.itblock
75+
display inline-block
76+
vertical-align top
77+
78+
.border
79+
border 1px solid #e4e4e4
80+
81+
.borderl
82+
border-left 1px solid #e4e4e4
83+
84+
.borderr
85+
border-right 1px solid #e4e4e4
86+
87+
.borderb
88+
border-bottom 1px solid #e4e4e4
89+
&.dashed
90+
border-bottom 1px dashed #e4e4e4
91+
92+
.bordert
93+
border-top 1px solid #e4e4e4
94+
95+
.borderr
96+
border-right 1px solid #e4e4e4
97+
98+
.borderl
99+
border-left 1px solid #e4e4e4
100+
101+
.border-dashed
102+
border-style dashed
103+
.border-dotted
104+
border-style dotted
105+
106+
.hide,
107+
.hide1,
108+
.hide2
109+
display none
110+
111+
.hidden
112+
visibility hidden
113+
114+
.fleft
115+
float left
116+
117+
.fright
118+
float right
119+
120+
.fcenter
121+
float center
122+
123+
.fix:before,
124+
.fix:after
125+
content " "
126+
display table
127+
128+
.fix
129+
&:after
130+
clear both
131+
132+
.overhide
133+
overflow hidden
134+
135+
.overscroll
136+
overflow scroll
137+
138+
.overscroll-y
139+
overflow-y scroll
140+
141+
.relative
142+
position relative
143+
.absolute
144+
position absolute
145+
.pointer
146+
cursor pointer
147+
148+
.spin-90
149+
transform rotate(90deg)

src/lib/react-ele.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* react element app
3+
*/
4+
5+
import { useEffect } from 'react'
6+
import { Modal, Button } from 'antd'
7+
import { SyncOutlined } from '@ant-design/icons'
8+
import { reSyncData } from '../features/contacts'
9+
10+
function showSyncMenu () {
11+
let mod = null
12+
function syncRecent () {
13+
reSyncData(true)
14+
destroyMod()
15+
}
16+
function syncAll () {
17+
reSyncData()
18+
destroyMod()
19+
}
20+
function destroyMod () {
21+
mod.destroy()
22+
}
23+
const content = (
24+
<div>
25+
<div className='pd2b'>After Sync contacts, conatacts data will update, so auto call log can match right contacts, you could choose sync only recent updated/created contacts or sync all contacts.</div>
26+
<div>
27+
<Button
28+
type='primary'
29+
className='mg1r mg1b'
30+
onClick={syncRecent}
31+
>
32+
Sync recent update/created contacts
33+
</Button>
34+
<Button
35+
type='primary'
36+
className='mg1r mg1b'
37+
onClick={syncAll}
38+
>
39+
Sync all contacts
40+
</Button>
41+
<Button
42+
type='ghost'
43+
className='mg1r mg1b'
44+
onClick={destroyMod}
45+
>
46+
Cancel
47+
</Button>
48+
</div>
49+
</div>
50+
)
51+
const btnProps = {
52+
disabled: true,
53+
className: 'hide'
54+
}
55+
mod = Modal.confirm({
56+
title: 'Sync contacts',
57+
width: '90%',
58+
icon: <SyncOutlined />,
59+
content,
60+
zIndex: 11000,
61+
closable: false,
62+
okButtonProps: btnProps,
63+
cancelButtonProps: btnProps
64+
})
65+
}
66+
67+
function showNotification (info, destroyPrev = false) {
68+
69+
}
70+
71+
export default () => {
72+
function onEvent (e) {
73+
if (!e || !e.data || !e.data.type) {
74+
return
75+
}
76+
const { type } = e.data
77+
if (type === 'rc-show-sync-menu') {
78+
showSyncMenu()
79+
} else if (type === 'rc-show-notification') {
80+
showNotification(e.data.info)
81+
}
82+
}
83+
useEffect(() => {
84+
window.addEventListener('message', onEvent)
85+
return () => {
86+
window.removeEventListener('message', onEvent)
87+
}
88+
}, [])
89+
90+
return null
91+
}

src/lib/react-entry.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* react entry
3+
*/
4+
5+
import { render } from 'react-dom'
6+
import {
7+
createElementFromHTML
8+
} from 'ringcentral-embeddable-extension-common/src/common/helpers'
9+
import App from './react-ele'
10+
import './box.styl'
11+
12+
export default () => {
13+
const id = 'rc-react-entry'
14+
let rootElement = document.getElementById(id)
15+
if (rootElement) {
16+
return
17+
}
18+
rootElement = createElementFromHTML(`<div id="${id}"></div>`)
19+
const home = document.body
20+
home.appendChild(rootElement)
21+
render(
22+
<App />,
23+
rootElement
24+
)
25+
}

src/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Ringcentral Embeddable Widgets for Pipedrive",
3-
"version": "2.0.0",
3+
"version": "2.0.1",
44
"description": "Add RingCentral Embeddable Voice widgets to Pipedrive",
55
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1YqYvCEeGGNOgtKrx8DfG33ujx7NgAwbyVpikug4mHiNvKZYWulw7lY5fjaD8wAy5bmXnkfULDzqMkL8UOxUcf8qD2lJFcLm+BqBtqNnoSz00vwjSOxXrcDvpvsMrjEZkI7N/FD60sTWp1U+QOehua7OboUpXb4iV7TQfppz3PsCz7qGOa4PWjUMAZTTgomUtW47Es6f/vjIeejs7Ihro3Al5Jo3SWIbjpjSU9BK34XgFvtcZx3lZQgfFiK+ZNyxlx8mgC/PLqJB+uX63ywMrT86TdcfxBuaThy98S8SCXjZTpHOP6X5pmGMk0lPM06hwxmSCBZgHOHL/Wk6r8FUlQIDAQAB",
66
"permissions": [

0 commit comments

Comments
 (0)