Skip to content
This repository was archived by the owner on Nov 20, 2024. It is now read-only.

Commit 194e44b

Browse files
authored
feat: [SPMVP-6575] karbon support dropdown reference type (#279)
1 parent 127929d commit 194e44b

File tree

6 files changed

+158
-17
lines changed

6 files changed

+158
-17
lines changed

packages/custom-field/model/field.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export enum FieldType {
1111
RichText = 'RICHTEXT',
1212
Json = 'JSON',
1313
Ref = 'REF',
14+
Select = 'SELECT',
1415
}
1516

1617
export interface FieldTypeMap {
@@ -24,6 +25,7 @@ export interface FieldTypeMap {
2425
[FieldType.RichText]: unknown
2526
[FieldType.Json]: unknown
2627
[FieldType.Ref]: unknown
28+
[FieldType.Select]: unknown
2729
}
2830

2931
const VALID_TYPE = new Set<string>(values(FieldType))

packages/custom-field/model/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export { CUSTOM_FIELD_KEY, CUSTOM_FIELD_EDITOR_BLOCK_KEY } from './constants'
2-
export { useField } from './storage'
2+
export { useField, normalizeOptions } from './storage'
3+
export type { UseFieldReturn, UseFieldOptions } from './storage'
34
export {
45
useFieldStorage,
56
storageCtx,

packages/custom-field/model/storage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function useField(
6464
})
6565
}
6666

67-
function normalizeOptions<Type extends FieldType, IsAll extends boolean = false>(
67+
export function normalizeOptions<Type extends FieldType, IsAll extends boolean = false>(
6868
type?: Type | UseFieldOptions<Type, IsAll>,
6969
all?: IsAll,
7070
): UseFieldOptions<Type, IsAll> {

packages/karbon/src/runtime/api/article.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,39 @@ const GetArticle = gql`
180180
id
181181
jsonValue: value
182182
}
183+
... on CustomFieldReferenceValue {
184+
id
185+
referenceValue: value {
186+
... on Article {
187+
__typename
188+
id
189+
articleId: id
190+
title
191+
}
192+
... on Desk {
193+
__typename
194+
id
195+
deskId: id
196+
name
197+
}
198+
... on Tag {
199+
__typename
200+
id
201+
tagId: id
202+
name
203+
}
204+
... on User {
205+
__typename
206+
id
207+
userId: id
208+
full_name
209+
}
210+
}
211+
}
212+
... on CustomFieldSelectValue {
213+
id
214+
selectValue: value
215+
}
183216
}
184217
group {
185218
id
@@ -238,6 +271,39 @@ const GetArticle = gql`
238271
id
239272
jsonValue: value
240273
}
274+
... on CustomFieldReferenceValue {
275+
id
276+
referenceValue: value {
277+
... on Article {
278+
__typename
279+
id
280+
articleId: id
281+
title
282+
}
283+
... on Desk {
284+
__typename
285+
id
286+
deskId: id
287+
name
288+
}
289+
... on Tag {
290+
__typename
291+
id
292+
tagId: id
293+
name
294+
}
295+
... on User {
296+
__typename
297+
id
298+
userId: id
299+
full_name
300+
}
301+
}
302+
}
303+
... on CustomFieldSelectValue {
304+
id
305+
selectValue: value
306+
}
241307
}
242308
group {
243309
id
Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,70 @@
1-
export { useField, FieldType } from '@storipress/custom-field'
1+
import type { UseFieldOptions, UseFieldReturn } from '@storipress/custom-field'
2+
import { FieldType, useField as _useField, normalizeOptions } from '@storipress/custom-field'
3+
import type { ResourceID } from '../types'
4+
import { useResourceResolver } from './resources'
5+
6+
interface ReferenceValue {
7+
articleId?: string
8+
deskId?: string
9+
tagId?: string
10+
userId?: string
11+
}
12+
13+
function getReferenceResourceID({ articleId, deskId, tagId, userId }: ReferenceValue = {}): ResourceID {
14+
if (articleId) return { type: 'article', id: articleId }
15+
if (deskId) return { type: 'desk', id: deskId }
16+
if (tagId) return { type: 'tag', id: tagId }
17+
if (userId) return { type: 'author', id: userId }
18+
19+
return null as never
20+
}
21+
22+
export function useField(key: string): UseFieldReturn<undefined, false>
23+
export function useField<Type extends FieldType>(key: string, type: Type): UseFieldReturn<Type, false>
24+
export function useField<Type extends FieldType, IsAll extends boolean>(
25+
key: string,
26+
type: Type,
27+
all: IsAll,
28+
): UseFieldReturn<Type, IsAll>
29+
export function useField<Type extends FieldType, IsAll extends boolean>(
30+
key: string,
31+
options: UseFieldOptions<Type, IsAll>,
32+
_all?: IsAll,
33+
): UseFieldReturn<Type, IsAll>
34+
export function useField(
35+
key: string,
36+
type_?: FieldType | UseFieldOptions<FieldType, boolean>,
37+
all_ = false,
38+
): Ref<unknown> {
39+
const { type } = normalizeOptions(type_, all_)
40+
41+
const field = _useField(key, type_ as FieldType, all_)
42+
if (!field.value) return field
43+
44+
if (type === FieldType.Ref) {
45+
const { resolveFromID } = useResourceResolver()
46+
47+
const { data } = useAsyncData(
48+
`resource-meta-${key}::${type}`,
49+
async () => {
50+
const refValue = field.value as ReferenceValue[]
51+
const promises = refValue.map((value) => {
52+
const resourceID = getReferenceResourceID(value)
53+
return resolveFromID(resourceID)
54+
})
55+
return await Promise.all(promises)
56+
},
57+
{
58+
watch: [field],
59+
},
60+
)
61+
62+
return computed(() => {
63+
return data.value?.map((resource) => resource?.meta)
64+
})
65+
}
66+
67+
return field
68+
}
69+
70+
export { FieldType }

packages/karbon/src/runtime/routes/payload-handler.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { filter, first, pipe } from 'remeda'
22
import { setHeader } from 'h3'
3+
import { FieldType } from '@storipress/custom-field'
34
import type { Identifiable } from '../types'
45
import {
56
ALL_RESOURCE_JSON_PATH,
@@ -11,20 +12,18 @@ import {
1112
import { NOT_FOUND, defineSnapshotHandler } from './snapshot-handler'
1213
import { shouldBypassCache } from './cache-control'
1314

14-
export enum FieldType {
15-
Text = 'TEXT',
16-
Number = 'NUM',
17-
Bool = 'BOOL',
18-
File = 'FILE',
19-
URL = 'URL',
20-
Color = 'COLOR',
21-
Date = 'DATE',
22-
RichText = 'RICHTEXT',
23-
Json = 'JSON',
24-
Ref = 'REF',
25-
}
26-
27-
type CustomFieldType = 'text' | 'number' | 'color' | 'url' | 'boolean' | 'richText' | 'file' | 'date' | 'json'
15+
type CustomFieldType =
16+
| 'text'
17+
| 'number'
18+
| 'color'
19+
| 'url'
20+
| 'boolean'
21+
| 'richText'
22+
| 'file'
23+
| 'date'
24+
| 'json'
25+
| 'reference'
26+
| 'select'
2827
enum FieldTypeMap {
2928
boolean = 'Bool',
3029
color = 'Color',
@@ -35,6 +34,8 @@ enum FieldTypeMap {
3534
richText = 'RichText',
3635
text = 'Text',
3736
url = 'URL',
37+
reference = 'Ref',
38+
select = 'Select',
3839
}
3940
interface MetaFieldValue {
4041
__typename: string
@@ -145,6 +146,8 @@ const SWITCH_VALUE_MAP: Record<string, string> = {
145146
CustomFieldRichTextValue: 'jsonValue',
146147
CustomFieldFileValue: 'fileValue',
147148
CustomFieldDateValue: 'dateValue',
149+
CustomFieldReferenceValue: 'referenceValue',
150+
CustomFieldSelectValue: 'selectValue',
148151
}
149152
function getFieldValue(value: MetaFieldValue) {
150153
const valueKey = SWITCH_VALUE_MAP[value.__typename]

0 commit comments

Comments
 (0)