Skip to content

Commit

Permalink
[SDPA-3306] add mapping example (#555)
Browse files Browse the repository at this point in the history
* [SDPA-3306] Added example for mapping with minor fix

* Updated search code examples to make them working
  • Loading branch information
tim-yao authored Oct 13, 2019
1 parent edeb5ec commit 9cf6ef4
Show file tree
Hide file tree
Showing 17 changed files with 448 additions and 206 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* [Built With](#built-with)
* [Usage](#usage)
* [In a Nuxt application](#in-a-Nuxt-application)
* [In a Vue project](#in-a-vue-project)
* [In a Vue project](#in-a-vuejs-projectnot-nuxtjs)
* [Contributing](#contributing)
* [Getting Started](#getting-started)
* [Requirements](#requirements)
Expand Down Expand Up @@ -114,7 +114,7 @@ You can optionally pass options to `@dpc-sdp/ripple-nuxt-ui` by adding the `ripp

Ripple components are published individually as npm modules and can be imported in any Vue project.

Check out our [Vue app example](https://github.com/dpc-sdp/ripple/tree/develop/examples/basic-examples).
Check out our [Vue app example](https://github.com/dpc-sdp/ripple/tree/develop/examples/vue-example-app).

## Contributing

Expand Down
4 changes: 4 additions & 0 deletions examples/basic-examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
Provide a example for overriding the Ripple components in Tide landing page which
is dynamically loaded.

- [Override component mapping](tide/modules/example-override-mapping/)

Provide a example for overriding the components mapping.

- [Custom search page](tide/modules/example-search/)

Provide a example for adding a custom search page.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Feature: Custom mapping

Custom mapping should work

Background:
Given I visit the page "/"

Scenario: Example for overriding mapping with custom filter
And the example filter is applied

Scenario: Example for adding async filter
And the example async filter is applied

Scenario: Example for overriding core filter
And the core filter is overrode
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* global cy */

import { Then } from 'cypress-cucumber-preprocessor/steps'

Then(`the example filter is applied`, () => {
cy.get('.rpl-hero-banner__title span').should('contain', '[demo]')
})

Then(`the example async filter is applied`, () => {
cy.get('.rpl-hero-banner__description').should('contain', '[demo]')
})

Then(`the core filter is overrode`, () => {
cy.get('.rpl-hero-banner__link-list-item .rpl-text-label span span').should('contain', '[demo]')
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Ripple with custom mapping example

The mapping config is for mapping Tide data to Frontend Vue component(Not have to be Ripple components).

This is a example for overriding the Ripple default component mapping.

In this module, we are override the `heroBanner` mapping with custom filters.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Filters for adding extra process on a mapping value

// Create more filters if need.
module.exports = {

// Add your own filter, must with your own name prefix to avoid name conflict.
eomPageTitle: (pageTitle) => {
return `[demo] ${pageTitle}`
},

// An async filter example.
eomIntroText: async (introText) => {
const promise = new Promise((resolve, reject) => {
// Do some process
setTimeout(function () {
const processed = `[demo] ${introText}`
resolve(processed)
}, 300)
})
return promise
},

// We can override core filter by using same core filter name.
// Ripple v1.3.x required for this feature.
// ! Be careful, this way is hard to maintain.
// Use your own filter like above is the safer way.
paragraphKeyJourneyLinks: function (fieldParagraphLinks) {
if (typeof fieldParagraphLinks !== 'undefined' && fieldParagraphLinks !== null) {
let rtn = []
fieldParagraphLinks.forEach(item => {
rtn.push({
url: item.url || item.uri,
text: `[demo] ${item.title}`
})
})
return rtn
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Grid columns setting for cards.

module.exports = {

mapping: {
tideField: {

// A example for overriding default `heroBanner` mapping in https://github.com/dpc-sdp/ripple/blob/v1.2.1/packages/ripple-nuxt-tide/lib/config/tide.config.js#L33
// You can do:
// - Map to your own component.
// - Use your own filters to process the Tide field data.
'heroBanner': {
component: 'rpl-hero-banner',
props: {
title: {
field: 'pageTitle',
// Demo of a custom filter here.
filters: ['eomPageTitle']
},
introText: {
field: 'introText',
// Demo of another custom filter here.
filters: ['eomIntroText']
},
linkHeading: ['keyJourneys', 'field_paragraph_title'],
links: {
field: ['keyJourneys', 'field_paragraph_links'],
filters: ['paragraphKeyJourneyLinks']
},
moreLink: {
field: ['keyJourneys', 'field_paragraph_cta'],
filters: ['paragraphCta']
},
theme: 'theme',
showLinks: 'showLinks',
logo: 'logo',
backgroundGraphic: 'backgroundGraphic'
}
}
}
}
}
12 changes: 10 additions & 2 deletions examples/basic-examples/tide/modules/example-search/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ This example shows how to add a custom search page.

Three files required:

- `Search.vue`: Used for providing search form and search results.
- `formdata.js`: Used for providing search form configuration.
- Vue component e.g `Search.vue`: Used for providing search form and search results.
- Form config e.g `formdata.js`: Used for providing search form configuration.
- `module.js`: Used for providing search page route.

## Example search simple

It adds a very basic search page `/example-search-simple` has basic elements only.

## Example search

It adds a search page `/example-search`.
Original file line number Diff line number Diff line change
@@ -1,50 +1,45 @@
<template>
<rpl-page-layout class="app-main" :sidebar="sidebar">

<template slot="breadcrumbs" v-if="breadcrumbs">
<rpl-breadcrumbs :crumbs="breadcrumbs" />
</template>

<template slot="aboveContent" >
<rpl-search-form
@search="getSearchResults(searchForm.filterForm.model.title || '')"
@search="getSearchResults"
class="rpl-site-constrain--on-all"
v-bind="searchForm"
/>
<rpl-divider />
</template>
<transition name="fade">
<rpl-search-results
:searchResults="searchResults"
:pager="searchResults.length === 0 ? undefined : pager"
:responseSize="searchResults.length === 0 ? 0 : searchOptions.responseSize"
:count="searchResults.length === 0 ? 0 : count"
:errorMsg="errorMsg"
:noResultsMsg="noResultsCopy"
@pager-change="changed"
:type="searchComponent"
v-if="!loading"
/>
</transition>

<rpl-search-results
:searchResults="searchResults"
:pager="searchResults.length === 0 ? undefined : pager"
:responseSize="searchResults.length === 0 ? 0 : searchOptions.responseSize"
:count="searchResults.length === 0 ? 0 : count"
:errorMsg="errorMsg"
:noResultsMsg="noResultsCopy"
:childColsBp="sidebar ? cardColBp.narrow : cardColBp.wide"
@pager-change="changed"
:type="searchComponent"
/>
</rpl-page-layout>
</template>

<script>
import moment from 'moment'
import { RplDivider } from '@dpc-sdp/ripple-global'
import RplBreadcrumbs from '@dpc-sdp/ripple-breadcrumbs'
import { RplSearchForm, RplSearchResults } from '@dpc-sdp/ripple-search'
// Layout.
import { RplRow, RplCol } from '@dpc-sdp/ripple-grid'
import { RplPageLayout } from '@dpc-sdp/ripple-layout'
import { breadcrumbs as getBreadcrumbs } from '@dpc-sdp/ripple-nuxt-tide/lib/core/breadcrumbs'
import { RplSearchForm, RplSearchResults } from '@dpc-sdp/ripple-search'
import formData from './../formdata.js'
import formData from './formdata.js'
import { searchMixin } from '@dpc-sdp/ripple-nuxt-tide/modules/search'
export default {
name: 'ExampleSearch',
name: 'ExampleSearchSimple',
components: {
RplDivider,
RplBreadcrumbs,
RplSearchForm,
RplSearchResults,
Expand All @@ -58,65 +53,69 @@ export default {
const searchForm = await formData.getFormData(app.$tideSearch.setFilterOptions)
return {
sidebar: false,
breadcrumbs: getBreadcrumbs(route.path, searchForm.title, null),
searchComponent: 'RplCardHonourRoll',
searchComponent: 'RplCardEvent',
searchForm,
searchOptions: {
currentSiteOnly: true,
defaultHits: false,
responseSize: 9,
qFields: ['title'],
sFields: [
'field_profile_category_name',
'field_profile_expertise_name',
'field_life_span',
'field_media_image_absolute_path',
'field_year',
'summary_processed',
qFields: [
'body',
'field_event_details_event_locality',
'field_landing_page_summary',
'field_paragraph_body',
'field_paragraph_summary',
'title'
],
sFields: [
'field_event_category_name',
'field_event_date_end_value',
'field_event_date_start_value',
'field_event_details_event_locality',
'field_event_details_event_requirements_name',
'field_landing_page_summary',
'field_profile_intro_text',
'field_location_name',
'field_media_image_absolute_path',
'field_node_primary_site',
'title',
'type',
'url'
]
},
sort: false,
docType: 'profile'
sort: { field: 'field_event_date_end_value', order: 'asc' },
docType: 'event',
type: 'events'
}
},
methods: {
getComputedFilters () {
// Remove title from filter terms as it is being sent as the search query
const filters = this.$tideSearch.getFiltersValues(this.searchForm.filterForm)
if (filters.title) {
delete filters.title
let filterValues = this.$tideSearch.getFiltersValues(this.searchForm.filterForm)
// Test date filter based on start / end fields.
if (filterValues.field_event_date_end_value) {
const setFilterDate = moment(filterValues.field_event_date_end_value.values)
filterValues.field_event_date_end_value.values = setFilterDate.startOf('day').toISOString()
filterValues['field_event_date_start_value'] = {
operator: 'lte',
type: 'date',
values: setFilterDate.endOf('day').toISOString()
}
}
return filters
return filterValues
},
mapSearchResults (source) {
const titleLimit = 80
const lifespanLimit = 50
const summaryLimit = 100
let pSite = ''
if (source.field_node_primary_site) {
pSite = source.field_node_primary_site[0]
}
return {
name: source.title ? this.truncateText(source.title[0], titleLimit) : '',
inductionYear: source.field_year ? source.field_year[0] : '',
category: source.field_profile_category_name ? source.field_profile_category_name[0] : '',
lifespan: source.field_life_span ? this.truncateText(source.field_life_span[0], lifespanLimit) : '',
summary: typeof source.summary_processed !== 'undefined' && source.summary_processed[0].length > 1 ? this.truncateText(source.summary_processed[0], summaryLimit) : this.truncateText(source.field_landing_page_summary[0], summaryLimit),
link: this.getLink(source.url, this.$store.state.tide.siteData.drupal_internal__tid, source.field_node_primary_site, this.$store.state.tideSite.sitesDomainMap, { text: 'text', url: 'url' }, 'Read profile'),
image: source.field_media_image_absolute_path ? source.field_media_image_absolute_path[0] : ''
title: source.title[0] || '',
dateStart: source.field_event_date_start_value[0] || '',
dateEnd: source.field_event_date_end_value[0] || '',
location: source.field_event_details_event_locality[0] || '',
summary: typeof source.field_landing_page_summary !== 'undefined' ? this.truncateText(source.field_landing_page_summary[0]) : this.truncateText(source.body[0]),
image: source.field_media_image_absolute_path ? source.field_media_image_absolute_path[0] : '',
link: source.url && this.getLink(source.url, this.$store.state.tide.siteData.drupal_internal__tid, pSite, this.$store.state.tideSite.sitesDomainMap, { text: 'text', url: 'url' }, 'See event details')
}
}
}
}
</script>

<style lang="scss" scoped>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
Loading

0 comments on commit 9cf6ef4

Please sign in to comment.