Skip to content

Instantly share code, notes, and snippets.

@rdai10
Last active October 7, 2021 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rdai10/1edb44dc9fa284d82f20462249c491af to your computer and use it in GitHub Desktop.
Save rdai10/1edb44dc9fa284d82f20462249c491af to your computer and use it in GitHub Desktop.
zendesk app snippets
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;
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