Skip to content

Commit

Permalink
feature(picker-starter): add picker.config file (#84)
Browse files Browse the repository at this point in the history
* add picker.config file

* return service from defineConfig

* make options config to be optional

* add simple validation without using Joi

* get rid of the option example property in our config schema

* make optionsValidate optional

* fix type error

* fix prettier

* only accept limit as option and get rid of selectOnly
  • Loading branch information
demetriusfeijoo authored Dec 11, 2023
1 parent 2ffcbb3 commit 027caed
Show file tree
Hide file tree
Showing 16 changed files with 104 additions and 190 deletions.
5 changes: 2 additions & 3 deletions picker-starter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ As you can see in the example below, the default `platform` example function ret

```js
export const platform: PickerPlatform<OptionsParams> = (options) => ({
itemServices: [
tabs: [
{
name: 'product',
label: 'Products',
Expand All @@ -44,7 +44,6 @@ This file is responsible for handling all [options](https://www.storyblok.com/do
In this starter example, we accept two options by default, they are:

- `limit`: how many items this starter can select
- `selectOnly`: which service/tab we want to show. By default, as we have two services (products and categories), you're able to pass `product` or `category` as value.

See below how to test these options using our Sandbox:

Expand All @@ -58,7 +57,7 @@ So, suppose you are working in a `Spotify Song Picker` and you don't want to lis

```js
export const platform: PickerPlatform<OptionsParams> = (options) => ({
itemServices: [
tabs: [
{
name: 'songs',
label: 'Songs',
Expand Down
2 changes: 0 additions & 2 deletions picker-starter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@
"@storyblok/design-system": "^3.19.3",
"@storyblok/field-plugin": "1.0.0",
"debounce": "^1.2.1",
"joi": "^17.11.0",
"vue": "^3.2.47",
"vue-draggable-next": "^2.2.1"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.1.4",
"@types/debounce": "^1.2.4",
"@types/joi": "^17.2.3",
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^6.12.0",
"@vitejs/plugin-vue": "^4.1.0",
Expand Down
6 changes: 5 additions & 1 deletion picker-starter/src/components/FieldPlugin.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { computed } from 'vue'
import { Picker } from './Picker'
import { servicePluginParams } from '../picker-params'
import { useFieldPlugin } from '@storyblok/field-plugin/vue3'
import { pluginName } from '../settings'
import setup from '../picker.config'
const plugin = useFieldPlugin()
Expand All @@ -18,6 +18,10 @@ const setValue = (content: any) => {
...content,
})
}
const servicePluginParams = computed(() => {
return setup(plugin.data.options)
})
</script>

<template>
Expand Down
27 changes: 11 additions & 16 deletions picker-starter/src/components/ModalPage/ModalPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,21 @@
:type="null"
>
<SbTab
v-for="itemService in itemServices"
:key="itemService.name"
:label="itemService.label"
:name="itemService.name"
v-for="tab in tabs"
:key="tab.name"
:label="tab.label"
:name="tab.name"
/>
</SbTabs>
<div class="sb-tab-panels">
<SbTabPanels v-model="activeTab">
<SbTabPanel
v-for="itemService in itemServices"
:key="itemService.name"
:name="itemService.name"
v-for="tab in tabs"
:key="tab.name"
:name="tab.name"
>
<ItemPicker
:item-service="itemService"
:item-service="tab"
:basket="basket"
:is-limit-reached="isLimitReached"
/>
Expand Down Expand Up @@ -88,7 +88,6 @@ import { ItemPicker } from '../ItemPicker'
import { CartList } from '../CartList'
import { EmptyScreen } from '../EmptyScreen'
import { NonItemsAddedIcon } from '../Icons'
import { getItemServices } from '../ModalPage/getItemServices'
export default {
name: 'ModalPage',
Expand Down Expand Up @@ -126,10 +125,6 @@ export default {
type: Object,
default: undefined,
},
selectOnly: {
type: String,
default: undefined,
},
maxItems: {
type: Number,
default: undefined,
Expand All @@ -145,16 +140,16 @@ export default {
NoItemsIcon() {
return NonItemsAddedIcon
},
itemServices() {
return getItemServices(this.pickerService, this.selectOnly)
tabs() {
return this.pickerService.tabs
},
isLimitReached() {
return this.maxItems <= this.basket.size()
},
},
methods: {
initialActiveTab() {
return getItemServices(this.pickerService, this.selectOnly)?.[0]?.name
return this.pickerService.tabs[0]?.name
},
},
}
Expand Down
29 changes: 0 additions & 29 deletions picker-starter/src/components/ModalPage/getItemServices.test.ts

This file was deleted.

11 changes: 0 additions & 11 deletions picker-starter/src/components/ModalPage/getItemServices.ts

This file was deleted.

4 changes: 0 additions & 4 deletions picker-starter/src/components/Picker/Picker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
:basket="basket"
:picker-service="pickerService"
:close-modal="closeModal"
:select-only="selectOnly"
:max-items="maxItems"
/>
<NonModalPage
Expand Down Expand Up @@ -67,9 +66,6 @@ export default {
...pluginPropsDef,
},
computed: {
selectOnly() {
return this.unvalidatedOptions.selectOnly
},
maxItems() {
return this.unvalidatedOptions.limit === ''
? undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
<p class="plugin-validation-error__details">
{{ validationResult.error }}
</p>
<p>Example of valid options:</p>
<div class="plugin-validation-error__example">
{{ validationResult.exampleOptions }}
</div>
</div>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions picker-starter/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './basket'
export * from './matchItem'
export * from './service'
export * from './types'
export * from './setup'
44 changes: 44 additions & 0 deletions picker-starter/src/core/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Component } from 'vue'
import { OptionsParams, PickerPluginParams, TabItem } from './types'

export type PickerConfig = {
title?: string
icon?: Component
validateOptions?: () => ValidationResult
tabs: TabItem[]
}

export type ValidationResult = {
isValid: boolean
error?: string
}

export type PickerConfigFn = (optionsParams: OptionsParams) => PickerConfig

export type PickerBuilderFn = (
optionsParams: OptionsParams,
) => PickerPluginParams

export const defineConfig =
(fn: PickerConfigFn): PickerBuilderFn =>
(optionsParams: OptionsParams): PickerPluginParams => {
const { title, icon, tabs, validateOptions } = fn(optionsParams)

return {
title,
icon,
makeService: () => {
const validation = validateOptions?.()

if (validation?.isValid === false) {
return {
error: validation.error || 'Unknown error',
}
}

return {
value: { tabs },
}
},
}
}
6 changes: 2 additions & 4 deletions picker-starter/src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@ export type CursorPaginatedResult<Item> = {

export type PickerServiceValidationResult =
| {
exampleOptions: Record<string, string>
value: undefined
error: string
}
| {
exampleOptions: Record<string, string>
value: PickerService
error: undefined
}
Expand Down Expand Up @@ -75,15 +73,15 @@ export type ItemQuery = (
params: ItemQueryParams,
) => Promise<QueryResponse<BasketItem>>

export type ItemService = {
export type TabItem = {
name: string
label: string
query: ItemQuery // TODO rename propery
getFilters?: FilterList
}

export type PickerService = {
itemServices: ItemService[]
tabs: TabItem[]
}

export type PickerPluginParams = {
Expand Down
27 changes: 0 additions & 27 deletions picker-starter/src/options-schema.ts

This file was deleted.

24 changes: 0 additions & 24 deletions picker-starter/src/picker-params.ts

This file was deleted.

39 changes: 39 additions & 0 deletions picker-starter/src/picker.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { getProductFilters, queryCategories, queryProducts } from '@/data'
import { defineConfig } from '@/core'
import { StoryblokIcon } from './components'

export default defineConfig((options) => {
return {
title: 'Picker Starter',
icon: StoryblokIcon,
validateOptions: () => {
const { limit } = options

const isLimitOptionValid = limit === undefined || Number(limit) > 0

if (!isLimitOptionValid) {
return {
isValid: false,
error: `The 'limit' option must be an integer greater than 0`,
}
}

return {
isValid: true,
}
},
tabs: [
{
name: 'product',
label: 'Products',
query: queryProducts,
getFilters: getProductFilters,
},
{
name: 'category',
label: 'Categories',
query: queryCategories,
},
],
}
})
18 changes: 0 additions & 18 deletions picker-starter/src/platform.ts

This file was deleted.

Loading

1 comment on commit 027caed

@vercel
Copy link

@vercel vercel bot commented on 027caed Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.