UNPKG

4.26 kBPlain TextView Raw
1import memoizeOne from 'memoize-one'
2import {Schema, defaultSchema, SchemaType} from './parts/Schema'
3import {dataAspects, DataAspectsResolver} from './parts/DataAspects'
4import {getPlusIcon, getListIcon, getDetailsIcon} from './parts/Icon'
5import {MenuItemBuilder, getOrderingMenuItemsForSchemaType} from './MenuItem'
6import {DEFAULT_SELECTED_ORDERING_OPTION} from './Sort'
7import {DocumentListBuilder} from './DocumentList'
8import {ListItemBuilder} from './ListItem'
9import {EditorBuilder} from './Editor'
10import {isActionEnabled} from './parts/documentActionUtils'
11import {DocumentTypeListBuilder} from './DocumentTypeList'
12import {IntentChecker} from './Intent'
13
14const PlusIcon = getPlusIcon()
15const ListIcon = getListIcon()
16const DetailsIcon = getDetailsIcon()
17
18const getDataAspectsForSchema: (schema: Schema) => DataAspectsResolver = memoizeOne(dataAspects)
19
20export const DEFAULT_INTENT_HANDLER = Symbol('Document type list canHandleIntent')
21
22function shouldShowIcon(schemaType: SchemaType): boolean {
23 const preview = schemaType.preview
24 return Boolean(preview && (preview.prepare || (preview.select && preview.select.media)))
25}
26
27export function getDocumentTypeListItems(schema: Schema = defaultSchema): ListItemBuilder[] {
28 const resolver = getDataAspectsForSchema(schema)
29 const types = resolver.getDocumentTypes()
30 return types.map(typeName => getDocumentTypeListItem(typeName, schema))
31}
32
33export function getDocumentTypeListItem(
34 typeName: string,
35 schema: Schema = defaultSchema
36): ListItemBuilder {
37 const type = schema.get(typeName)
38 if (!type) {
39 throw new Error(`Schema type with name "${typeName}" not found`)
40 }
41
42 const resolver = getDataAspectsForSchema(schema)
43 const title = resolver.getDisplayName(typeName)
44 return new ListItemBuilder()
45 .id(typeName)
46 .title(title)
47 .schemaType(type)
48 .child(getDocumentTypeList(typeName, schema))
49}
50
51export function getDocumentTypeList(
52 typeName: string,
53 schema: Schema = defaultSchema
54): DocumentListBuilder {
55 const type = schema.get(typeName)
56 if (!type) {
57 throw new Error(`Schema type with name "${typeName}" not found`)
58 }
59
60 const resolver = getDataAspectsForSchema(schema)
61 const title = resolver.getDisplayName(typeName)
62 const showIcons = shouldShowIcon(type)
63 const canCreate = isActionEnabled(type, 'create')
64
65 const intentChecker: IntentChecker = (intentName, params): boolean =>
66 Boolean(intentName === 'edit' && params && params.id && params.type === typeName) ||
67 Boolean(intentName === 'create' && params && params.type === typeName)
68
69 intentChecker.identity = DEFAULT_INTENT_HANDLER
70
71 return new DocumentTypeListBuilder()
72 .id(typeName)
73 .title(title)
74 .filter('_type == $type')
75 .params({type: typeName})
76 .schemaType(type)
77 .showIcons(showIcons)
78 .defaultOrdering(DEFAULT_SELECTED_ORDERING_OPTION.by)
79 .menuItemGroups([
80 {id: 'sorting', title: 'Sort'},
81 {id: 'layout', title: 'Layout'},
82 {id: 'actions', title: 'Actions'}
83 ])
84 .child((documentId: string) =>
85 new EditorBuilder()
86 .id('editor')
87 .schemaType(type)
88 .documentId(documentId)
89 )
90 .canHandleIntent(intentChecker)
91 .menuItems([
92 // Create new (from action button)
93 ...(canCreate
94 ? [
95 new MenuItemBuilder()
96 .title(`Create new ${title}`)
97 .icon(PlusIcon)
98 .intent({type: 'create', params: {type: typeName}})
99 .showAsAction({whenCollapsed: true})
100 ]
101 : []),
102
103 // Sort by <Y>
104 ...getOrderingMenuItemsForSchemaType(type),
105
106 // Display as <Z>
107 new MenuItemBuilder()
108 .group('layout')
109 .title('List')
110 .icon(ListIcon)
111 .action('setLayout')
112 .params({layout: 'default'}),
113
114 new MenuItemBuilder()
115 .group('layout')
116 .title('Details')
117 .icon(DetailsIcon)
118 .action('setLayout')
119 .params({layout: 'detail'}),
120
121 // Create new (from menu)
122 ...(canCreate
123 ? [
124 new MenuItemBuilder()
125 .group('actions')
126 .title('Create new…')
127 .icon(PlusIcon)
128 .intent({type: 'create', params: {type: typeName}})
129 ]
130 : [])
131 ])
132}