Skip to content

Commit

Permalink
improve: LDP-1975: Refactor for better DX. (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
TurtlBbx authored Feb 6, 2023
1 parent 2545ff3 commit 2cd9cbf
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 80 deletions.
3 changes: 2 additions & 1 deletion playground/components/Breadcrumbs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
</template>

<script setup>
const page = useDrupalCePage()
const { getPage } = useDrupalCe()
const page = getPage()
</script>

<style lang="css" scoped>
Expand Down
3 changes: 2 additions & 1 deletion playground/components/MainNavigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
</template>

<script lang="ts" setup>
const mainMenu = await useDrupalCeFetchMenu('main')
const { fetchMenu } = useDrupalCe()
const mainMenu = await fetchMenu('main')
</script>

<style lang="css" scoped>
Expand Down
8 changes: 4 additions & 4 deletions playground/pages/[...slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
<div>
<MainNavigation />
<Breadcrumbs />
<component :is="useDrupalCeRenderCustomElements(page.content)" />
<component :is="renderCustomElements(page.content)" />
</div>
</template>

<script lang="ts" setup>
const page = await useDrupalCeFetchPage(useRoute().path, { query: useRoute().query })
const messages = useDrupalCeMessages()
const { fetchPage, getMessages, renderCustomElements } = useDrupalCe()
const page = await fetchPage(useRoute().path, { query: useRoute().query })
const messages = getMessages()
</script>
158 changes: 84 additions & 74 deletions src/runtime/composables/useDrupalCe.ts
Original file line number Diff line number Diff line change
@@ -1,83 +1,93 @@
import { useRuntimeConfig, useState, useFetch, navigateTo, createError, useRoute, h, resolveComponent } from '#imports'
/**
* Fetches page data from Drupal, handles redirects, errors and messages
* @param path Path of the Drupal page to fetch
* @param useFetchOptions Optional Nuxt useFetch options
*/
export const useDrupalCeFetchPage = async (path: string, useFetchOptions = {}) => {
const config = useRuntimeConfig()
const baseURL = config.public.drupalCe.baseURL

// Workaround for issue - useState is not available after async call (Nuxt instance unavailable)
const pageState = useState(`page-${path}`, () => {})

useFetchOptions.query = useFetchOptions.query ?? {}
useFetchOptions.key = `page-${path}`
useFetchOptions.baseURL = baseURL

const { data: page, error } = await useFetch(path, useFetchOptions)

if (page?.value?.redirect) {
await navigateTo(page.value.redirect.url, {
external: page.value.redirect.external,
redirectCode: page.value.redirect.statusCode
})
return
}

if (error.value && !error.value?.data?.content) {
throw createError({ statusCode: error.value.status, statusMessage: error.value.message, fatal: true })
export const useDrupalCe = () => {
/**
* Fetches page data from Drupal, handles redirects, errors and messages
* @param path Path of the Drupal page to fetch
* @param useFetchOptions Optional Nuxt useFetch options
*/
const fetchPage = async (path: string, useFetchOptions = {}) => {
const config = useRuntimeConfig()
const baseURL = config.public.drupalCe.baseURL

// Workaround for issue - useState is not available after async call (Nuxt instance unavailable)
const pageState = useState(`page-${path}`, () => {})

useFetchOptions.query = useFetchOptions.query ?? {}
useFetchOptions.key = `page-${path}`
useFetchOptions.baseURL = baseURL

const { data: page, error } = await useFetch(path, useFetchOptions)

if (page?.value?.redirect) {
await navigateTo(page.value.redirect.url, {
external: page.value.redirect.external,
redirectCode: page.value.redirect.statusCode
})
return
}

if (error.value && !error.value?.data?.content) {
throw createError({ statusCode: error.value.status, statusMessage: error.value.message, fatal: true })
}

if (error.value) {
page.value = error.value?.data
}

page.value?.messages && pushMessagesToState(page.value.messages)

pageState.value = page
return page
}

if (error.value) {
page.value = error.value?.data
}

page.value?.messages && pushMessagesToState(page.value.messages)

pageState.value = page
return page
}
/**
* Fetches menu data from Drupal (configured by menuEndpoint option), handles errors
* @param name Menu name being fetched
*/
const fetchMenu = async (name: string) => {
const config = useRuntimeConfig()
const baseURL = config.public.drupalCe.baseURL
const menuEndpoint = config.public.drupalCe.menuEndpoint
const menuPath = menuEndpoint.replace('$$$NAME$$$', name)

const { data: menu, error } = await useFetch(menuPath, {
key: `menu-${name}`,
baseURL
})

/**
* Fetches menu data from Drupal (configured by menuEndpoint option), handles errors
* @param name Menu name being fetched
*/
export const useDrupalCeFetchMenu = async (name: string) => {
const config = useRuntimeConfig()
const baseURL = config.public.drupalCe.baseURL
const menuEndpoint = config.public.drupalCe.menuEndpoint
const menuPath = menuEndpoint.replace('$$$NAME$$$', name)

const { data: menu, error } = await useFetch(menuPath, {
key: `menu-${name}`,
baseURL
})
if (error.value) {
errorMenuHandler(error)
return
}

if (error.value) {
errorMenuHandler(error)
return
return menu
}

return menu
}
/**
* Use messages state
*/
const getMessages = () => useState('drupal-ce-messages', () => [])

/**
* Use page data
*/
const getPage = () => useState(`page-${useRoute().path}`)

/**
* Render elements from page data returned from fetchPage
* @param customElement
*/
const renderCustomElements = (customElement) => {
return h(resolveComponent(customElement.element), customElement)
}

/**
* Use messages state
*/
export const useDrupalCeMessages = () => useState('drupal-ce-messages', () => [])

/**
* Use page data
*/
export const useDrupalCePage = () => useState(`page-${useRoute().path}`)

/**
* Render elements from page data returned from useDrupalCeFetchPage
* @param customElement
*/
export const useDrupalCeRenderCustomElements = (customElement) => {
return h(resolveComponent(customElement.element), customElement)
return {
fetchPage,
fetchMenu,
getMessages,
getPage,
renderCustomElements,
}
}

const pushMessagesToState = (messages) => {
Expand All @@ -89,11 +99,11 @@ const pushMessagesToState = (messages) => {
if (!messagesArray.length) {
return
}
process.client && useDrupalCeMessages().value.push(...messagesArray)
process.client && useDrupalCe().getMessages().value.push(...messagesArray)
}

const errorMenuHandler = (error) => {
process.client && useDrupalCeMessages().value.push({
process.client && useDrupalCe().getMessages().value.push({
type: 'error',
message: `Menu error: ${error.value.message}.`
})
Expand Down

0 comments on commit 2cd9cbf

Please sign in to comment.