1 | import memoizeOne from 'memoize-one'
|
2 | import {Schema, defaultSchema, SchemaType} from './parts/Schema'
|
3 | import {dataAspects, DataAspectsResolver} from './parts/DataAspects'
|
4 | import {getPlusIcon, getListIcon, getDetailsIcon} from './parts/Icon'
|
5 | import {MenuItemBuilder, getOrderingMenuItemsForSchemaType} from './MenuItem'
|
6 | import {DEFAULT_SELECTED_ORDERING_OPTION} from './Sort'
|
7 | import {DocumentListBuilder} from './DocumentList'
|
8 | import {ListItemBuilder} from './ListItem'
|
9 | import {EditorBuilder} from './Editor'
|
10 | import {isActionEnabled} from './parts/documentActionUtils'
|
11 | import {DocumentTypeListBuilder} from './DocumentTypeList'
|
12 | import {IntentChecker} from './Intent'
|
13 |
|
14 | const PlusIcon = getPlusIcon()
|
15 | const ListIcon = getListIcon()
|
16 | const DetailsIcon = getDetailsIcon()
|
17 |
|
18 | const getDataAspectsForSchema: (schema: Schema) => DataAspectsResolver = memoizeOne(dataAspects)
|
19 |
|
20 | export const DEFAULT_INTENT_HANDLER = Symbol('Document type list canHandleIntent')
|
21 |
|
22 | function shouldShowIcon(schemaType: SchemaType): boolean {
|
23 | const preview = schemaType.preview
|
24 | return Boolean(preview && (preview.prepare || (preview.select && preview.select.media)))
|
25 | }
|
26 |
|
27 | export 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 |
|
33 | export 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 |
|
51 | export 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 |
|
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 |
|
104 | ...getOrderingMenuItemsForSchemaType(type),
|
105 |
|
106 |
|
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 |
|
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 | }
|