-
-
Save rdai10/1edb44dc9fa284d82f20462249c491af to your computer and use it in GitHub Desktop.
zendesk app snippets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {StrictMode} from 'react'; | |
import ReactDOM from 'react-dom'; | |
import {ThemeProvider} from '@zendeskgarden/react-theming'; | |
import {GlobalContext} from '../context/Global'; | |
import {DEFAULT_LOCALE, MODAL, TICKET_SIDEBAR} from '../lib/constants'; | |
import I18n from '../lib/i18n'; | |
import ErrorBoundary from './ErrorBoundary'; | |
import Main from './Main'; | |
import Modal from './Modal'; | |
import {Theme} from './Theme'; | |
class App { | |
constructor(client, appData) { | |
this._client = client; | |
this._appData = appData; | |
this.states = {}; | |
// this.initializePromise is only used in testing | |
// indicates app initilization(including all async operations) is complete | |
this.initializePromise = this.init(); | |
} | |
/** | |
* Initialize module, render main template | |
*/ | |
init() { | |
const {location} = this._appData.context; | |
if (location) { | |
location === MODAL ? this._initModal() : this._initTicketSidebar(); | |
} else { | |
this._initTicketSidebar(); | |
} | |
} | |
async _initModal() { | |
const appInstances = await this._getAppInstances(); | |
const ticketSidebar = this._client.instance( | |
appInstances[TICKET_SIDEBAR] | |
); | |
this.states.ticketSidebar = ticketSidebar; | |
ticketSidebar.trigger('modalReady'); | |
this._client.on('transferModalData', (data) => this._renderModal(data)); | |
this._client.on('modal.close', () => this._client.invoke('destroy')); | |
} | |
async _initTicketSidebar() { | |
let currentUser = null; | |
let ticketSubject = ''; | |
try { | |
const [user, subject] = await Promise.all([ | |
this._client.get('currentUser'), | |
this._client.get('ticket.subject') | |
]); | |
currentUser = user.currentUser; | |
ticketSubject = subject['ticket.subject']; | |
} catch (e) { | |
this._handleError.call(this, e); | |
} | |
const locale = currentUser ? currentUser.locale : DEFAULT_LOCALE; | |
this.states.currentUser = currentUser; | |
this.states.locale = locale; | |
this.states.ticketSubject = ticketSubject; | |
this.states.ticketId = this._appData.context.ticketId; | |
I18n.loadTranslations(locale); | |
this._renderTicketSideBar(); | |
} | |
async _getAppInstances() { | |
const instanceData = await this._client.get('instances'); | |
return Object.fromEntries( | |
Object.entries(instanceData.instances).map(([uuid, {location}]) => [ | |
location, | |
uuid | |
]) | |
); | |
} | |
/** | |
* Handles error | |
* @param {Object} error error object | |
*/ | |
_handleError(error) { | |
console.error( | |
`Retriving data returned with the following error: `, | |
error.status, | |
error.statusText | |
); | |
} | |
_renderModal(data) { | |
ReactDOM.render( | |
<StrictMode> | |
<ErrorBoundary> | |
<GlobalContext.Provider | |
value={{ | |
client: this._client, | |
ticketSidebar: this.states.ticketSidebar | |
}} | |
> | |
<ThemeProvider theme={Theme}> | |
<Modal data={data} /> | |
</ThemeProvider> | |
</GlobalContext.Provider> | |
</ErrorBoundary> | |
</StrictMode>, | |
document.querySelector('.main') | |
); | |
} | |
_renderTicketSideBar() { | |
ReactDOM.render( | |
<StrictMode> | |
<ErrorBoundary> | |
<GlobalContext.Provider value={{client: this._client}}> | |
<ThemeProvider theme={Theme}> | |
<Main data={this.states} /> | |
</ThemeProvider> | |
</GlobalContext.Provider> | |
</ErrorBoundary> | |
</StrictMode>, | |
document.querySelector('.main') | |
); | |
} | |
} | |
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {useState} from 'react'; | |
import styled from 'styled-components'; | |
import {Col, Row} from '@zendeskgarden/react-grid'; | |
import {Well, Title, Paragraph} from '@zendeskgarden/react-notifications'; | |
import {SM} from '@zendeskgarden/react-typography'; | |
import {useGlobalContext} from '../context/Global'; | |
import I18n from '../lib/i18n'; | |
import {MAX_RECOMMENDED_HEIGHT, MODAL} from '../lib/constants'; | |
import {displayDateInMDYFormat, insertResult} from '../lib/utility'; | |
import LinkArticle from './LinkArticle'; | |
import ResultBreadcrumb from './ResultBreadcrumb'; | |
export default function SearchResults({categories, results, sections}) { | |
return ( | |
<Row id="primaryResults" wrap="nowrap"> | |
<Col> | |
{results.map((result) => ( | |
<Result | |
categories={categories} | |
key={result.id} | |
result={result} | |
sections={sections} | |
/> | |
))} | |
</Col> | |
</Row> | |
); | |
} | |
function Result({categories, sections, result}) { | |
const {client} = useGlobalContext(); | |
const [linked, setLinked] = useState(false); | |
const section = getSection(result.section_id); | |
const category = getCategory(section ? section.category_id : null); | |
function getCategory(id) { | |
return categories.find((category) => category.id === id); | |
} | |
function getSection(id) { | |
return sections.find((section) => section.id === id); | |
} | |
function handleLinkArticle(event) { | |
event.stopPropagation(); | |
insertResult(client, result.name, result.html_url); | |
setLinked(true); | |
} | |
async function handleOpenModal() { | |
try { | |
const modalContext = await client.invoke('instances.create', { | |
location: MODAL, | |
size: { | |
height: MAX_RECOMMENDED_HEIGHT, | |
width: '740px' | |
}, | |
url: 'assets/main.html' | |
}); | |
const [modal] = modalContext['instances.create']; | |
const modalInstance = client.instance(modal.instanceGuid); | |
client.on('modalReady', () => | |
modalInstance.trigger('transferModalData', result) | |
); | |
modalInstance.on('modal.close', () => modalInstance.invoke('destroy')); | |
} catch (e) { | |
console.error( | |
`Creating a new instance of modal threw the following error: ${e}` | |
); | |
} | |
} | |
return ( | |
<Well onClick={handleOpenModal}> | |
<ResultTitle title={result.name} /> | |
<SM> | |
{!!category && !!section && ( | |
<ResultBreadcrumb | |
category={category.name} | |
section={section.name} | |
/> | |
)} | |
<ModificationInformation date={result.edited_at} /> | |
</SM> | |
<LinkArticle linked={linked} handler={handleLinkArticle} /> | |
</Well> | |
); | |
} | |
const EditedAt = ({className, date}) => ( | |
<Paragraph className={className} size="small"> | |
{I18n.t('last edited')} {displayDateInMDYFormat(date)} | |
</Paragraph> | |
); | |
const WellTitle = ({className, title}) => ( | |
<Title className={className}> | |
<h3>{title}</h3> | |
</Title> | |
); | |
const ModificationInformation = styled(EditedAt)` | |
color: ${(p) => p.theme.palette.grey[600]}; | |
margin-top: ${(p) => p.theme.space.xxs}; | |
`; | |
const ResultTitle = styled(WellTitle)` | |
h3 { | |
font-size: ${(p) => p.theme.lineHeights.sm}; | |
} | |
`; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment