Skip to content

Commit

Permalink
Merge pull request #59 from vtex-apps/feature/lazy2
Browse files Browse the repository at this point in the history
Feature/lazy
  • Loading branch information
lbebber authored Feb 10, 2020
2 parents 7dc1442 + e2c0cc5 commit c45dda4
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 87 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Changed
- Content is loaded lazily.

## [2.9.8] - 2019-12-03
### Added
Expand Down
94 changes: 94 additions & 0 deletions react/components/TelemarketingContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { compose, path } from 'ramda'
import React, { FC, useState } from 'react'
import { graphql } from 'react-apollo'
import { withSession } from 'vtex.render-runtime'
import { Queries } from 'vtex.store-resources'

import depersonifyMutation from '../mutations/depersonify.gql'
import impersonateMutation from '../mutations/impersonate.gql'
import isMyVtex from '../utils/isMyVtex'
import processSession from '../utils/processSession'
import Telemarketing from './Telemarketing'

interface Props {
/** Query with the session */
session?: Session
/** Mutation to depersonify */
depersonify: () => Promise<void>
/** Mutation to impersonate a customer */
impersonate: (s: {}) => Promise<void>
}

const TelemarketingContainer: FC<Props> = ({ depersonify, impersonate, session }) => {
const [emailInput, setEmailInput] = useState<string>('')
const [loadingImpersonate, setloadingImpersonate] = useState<boolean>(false)

const processedSession = processSession(session)

if (!session || !processedSession || !processedSession.canImpersonate) {
return null
}

const handleInputChange = (event: any) => {
setEmailInput(event.target.value)
}

const handleDepersonify = () => {
setloadingImpersonate(true)
depersonify()
.then(response => {
const depersonifyData = path(['data', 'depersonify'], response)
!!depersonifyData && session.refetch()
window.location.reload()
})
.catch(() => setloadingImpersonate(false))
}

const handleImpersonate = (email: string) => {
setloadingImpersonate(true)
const variables = { email }
impersonate({ variables })
.then(response => {
const profile = path(
['data', 'impersonate', 'impersonate', 'profile'],
response
)
!!profile && session.refetch()
window.location.reload()
})
.catch(() => setloadingImpersonate(false))
}

const { client, attendantEmail } = processedSession

return (
<Telemarketing
client={client}
loading={loadingImpersonate}
emailInput={emailInput}
attendantEmail={attendantEmail}
onImpersonate={handleImpersonate}
onDepersonify={handleDepersonify}
onInputChange={handleInputChange}
/>
)
}

const options = {
name: 'session',
skip: () => !isMyVtex(),
options: () => ({
ssr: false,
}),
}

const EnhancedTelemarketing = withSession({ loading: React.Fragment })(
compose(
graphql(Queries.session, options),
graphql(depersonifyMutation, { name: 'depersonify' }),
graphql(impersonateMutation, { name: 'impersonate' }),
)(TelemarketingContainer as any)
)

export default EnhancedTelemarketing

97 changes: 12 additions & 85 deletions react/index.tsx
Original file line number Diff line number Diff line change
@@ -1,94 +1,21 @@
import { compose, path, pathOr, includes } from 'ramda'
import React, { useState, FC } from 'react'
import { graphql } from 'react-apollo'
import { withSession } from 'vtex.render-runtime'
import { Queries } from 'vtex.store-resources'
import React, { FC, Suspense } from 'react'
import { NoSSR } from 'vtex.render-runtime'
import isMyVtex from './utils/isMyVtex'

import Telemarketing from './components/Telemarketing'
import depersonifyMutation from './mutations/depersonify.gql'
import impersonateMutation from './mutations/impersonate.gql'
import processSession from './utils/processSession'
const TelemarketingContainer = React.lazy(() => import('./components/TelemarketingContainer'))

interface Props {
/** Query with the session */
session?: Session
/** Mutation to depersonify */
depersonify: () => Promise<void>
/** Mutation to impersonate a customer */
impersonate: (s: {}) => Promise<void>
}

const TelemarketingContainer: FC<Props> = ({ depersonify, impersonate, session }) => {
const [emailInput, setEmailInput] = useState<string>('')
const [loadingImpersonate, setloadingImpersonate] = useState<boolean>(false)

const processedSession = processSession(session)

if (!session || !processedSession || !processedSession.canImpersonate) {
const Telemarketing: FC = (props) => {
if (!isMyVtex()) {
return null
}

const handleInputChange = (event: any) => {
setEmailInput(event.target.value)
}

const handleDepersonify = () => {
setloadingImpersonate(true)
depersonify()
.then(response => {
const depersonifyData = path(['data', 'depersonify'], response)
!!depersonifyData && session.refetch()
window.location.reload()
})
.catch(() => setloadingImpersonate(false))
}

const handleImpersonate = (email: string) => {
setloadingImpersonate(true)
const variables = { email }
impersonate({ variables })
.then(response => {
const profile = path(
['data', 'impersonate', 'impersonate', 'profile'],
response
)
!!profile && session.refetch()
window.location.reload()
})
.catch(() => setloadingImpersonate(false))
}

const { client, attendantEmail } = processedSession

return (
<Telemarketing
client={client}
loading={loadingImpersonate}
emailInput={emailInput}
attendantEmail={attendantEmail}
onImpersonate={handleImpersonate}
onDepersonify={handleDepersonify}
onInputChange={handleInputChange}
/>
<NoSSR>
<Suspense fallback={<React.Fragment />}>
<TelemarketingContainer {...props} />
</Suspense>
</NoSSR>
)
}

const hasMyVtex = compose(includes('myvtex.com'), pathOr('', ['location', 'hostname']))

const options = {
name: 'session',
skip: () => !hasMyVtex(window),
options: () => ({
ssr: false,
}),
}

const EnhancedTelemarketing = withSession({ loading: React.Fragment })(
compose(
graphql(Queries.session, options),
graphql(depersonifyMutation, { name: 'depersonify' }),
graphql(impersonateMutation, { name: 'impersonate' }),
)(TelemarketingContainer as any)
)

export default EnhancedTelemarketing
export default Telemarketing
2 changes: 1 addition & 1 deletion react/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"types": ["node", "jest", "graphql"],
"typeRoots": ["node_modules/@types"],
"target": "es2017",
"module": "es6",
"module": "esnext",
"sourceMap": true,
"moduleResolution": "node",
"jsx": "react",
Expand Down
2 changes: 1 addition & 1 deletion react/typings/render.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ declare module 'vtex.render-runtime' {
export const ExtensionPoint: ReactElement
export const Helmet: ReactElement
export const Link: ComponentType<any>
export const NoSSR: ReactElement
export const NoSSR: ComponentType<any>
export const RenderContextConsumer: ReactElement
export const canUseDOM: boolean
export const withRuntimeContext: <TOriginalProps extends {}>(
Expand Down
8 changes: 8 additions & 0 deletions react/utils/isMyVtex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { compose, includes, pathOr } from 'ramda'

export default function isMyVtex() {
return compose(
includes('myvtex.com'),
pathOr('', ['location', 'hostname'])
)(window)
}

0 comments on commit c45dda4

Please sign in to comment.