@brilo/base-blocks 0.1.28 → 0.1.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/build/.tsbuildinfo +1 -1
  2. package/build/blocks/career/career-header/edit.d.ts +6 -0
  3. package/build/blocks/career/career-header/edit.d.ts.map +1 -0
  4. package/build/blocks/career/career-header/edit.js +11 -0
  5. package/build/blocks/career/career-header/factory.d.ts +5 -0
  6. package/build/blocks/career/career-header/factory.d.ts.map +1 -0
  7. package/build/blocks/career/career-header/factory.js +24 -0
  8. package/build/blocks/career/career-header/icon.d.ts.map +1 -0
  9. package/build/blocks/career/career-header/icon.js +2 -0
  10. package/build/blocks/career/career-header/index.d.ts +5 -0
  11. package/build/blocks/career/career-header/index.d.ts.map +1 -0
  12. package/build/blocks/career/career-header/index.js +4 -0
  13. package/build/blocks/career/career-header/types.d.ts +10 -0
  14. package/build/blocks/career/career-header/types.d.ts.map +1 -0
  15. package/build/blocks/career/job-position-group/JobPositionsSelectModal.d.ts +9 -0
  16. package/build/blocks/career/job-position-group/JobPositionsSelectModal.d.ts.map +1 -0
  17. package/build/blocks/career/job-position-group/JobPositionsSelectModal.js +123 -0
  18. package/build/blocks/career/job-position-group/constants.d.ts +10 -0
  19. package/build/blocks/career/job-position-group/constants.d.ts.map +1 -0
  20. package/build/blocks/career/job-position-group/constants.js +9 -0
  21. package/build/blocks/career/job-position-group/edit.d.ts +6 -0
  22. package/build/blocks/career/job-position-group/edit.d.ts.map +1 -0
  23. package/build/blocks/career/job-position-group/edit.js +17 -0
  24. package/build/blocks/career/job-position-group/factory.d.ts +5 -0
  25. package/build/blocks/career/job-position-group/factory.d.ts.map +1 -0
  26. package/build/blocks/career/job-position-group/factory.js +44 -0
  27. package/build/blocks/career/job-position-group/icon.d.ts +2 -0
  28. package/build/blocks/career/job-position-group/icon.d.ts.map +1 -0
  29. package/build/blocks/career/job-position-group/icon.js +2 -0
  30. package/build/blocks/career/job-position-group/index.d.ts +6 -0
  31. package/build/blocks/career/job-position-group/index.d.ts.map +1 -0
  32. package/build/blocks/career/job-position-group/index.js +5 -0
  33. package/build/blocks/career/job-position-group/types.d.ts +20 -0
  34. package/build/blocks/career/job-position-group/types.d.ts.map +1 -0
  35. package/build/blocks/career/job-position-group/types.js +1 -0
  36. package/build/blocks/document/documents-grid/DocumentsSelectModal.d.ts.map +1 -0
  37. package/build/blocks/document/documents-grid/constants.d.ts +9 -0
  38. package/build/blocks/document/documents-grid/constants.d.ts.map +1 -0
  39. package/build/blocks/document/documents-grid/constants.js +8 -0
  40. package/build/blocks/document/documents-grid/edit.d.ts +6 -0
  41. package/build/blocks/document/documents-grid/edit.d.ts.map +1 -0
  42. package/build/blocks/document/{documents-group → documents-grid}/edit.js +10 -8
  43. package/build/blocks/document/documents-grid/factory.d.ts +5 -0
  44. package/build/blocks/document/documents-grid/factory.d.ts.map +1 -0
  45. package/build/blocks/document/{documents-group → documents-grid}/factory.js +12 -12
  46. package/build/blocks/document/documents-grid/icon.d.ts +2 -0
  47. package/build/blocks/document/documents-grid/icon.d.ts.map +1 -0
  48. package/build/blocks/document/documents-grid/index.d.ts +6 -0
  49. package/build/blocks/document/documents-grid/index.d.ts.map +1 -0
  50. package/build/blocks/document/documents-grid/index.js +5 -0
  51. package/build/blocks/document/documents-grid/types.d.ts +23 -0
  52. package/build/blocks/document/documents-grid/types.d.ts.map +1 -0
  53. package/build/blocks/document/documents-grid/types.js +1 -0
  54. package/build/blocks/post/post-content/edit.d.ts +6 -0
  55. package/build/blocks/post/post-content/edit.d.ts.map +1 -0
  56. package/build/blocks/post/post-content/edit.js +9 -0
  57. package/build/blocks/post/post-content/factory.d.ts +5 -0
  58. package/build/blocks/post/post-content/factory.d.ts.map +1 -0
  59. package/build/blocks/post/post-content/factory.js +18 -0
  60. package/build/blocks/post/post-content/icon.d.ts +2 -0
  61. package/build/blocks/post/post-content/icon.d.ts.map +1 -0
  62. package/build/blocks/post/post-content/icon.js +2 -0
  63. package/build/blocks/post/post-content/index.d.ts +5 -0
  64. package/build/blocks/post/post-content/index.d.ts.map +1 -0
  65. package/build/blocks/post/post-content/index.js +4 -0
  66. package/build/blocks/post/post-content/types.d.ts +5 -0
  67. package/build/blocks/post/post-content/types.d.ts.map +1 -0
  68. package/build/blocks/post/post-content/types.js +1 -0
  69. package/build/blocks/share/share/constants.d.ts +2 -0
  70. package/build/blocks/share/share/constants.d.ts.map +1 -0
  71. package/build/blocks/share/share/constants.js +1 -0
  72. package/build/blocks/share/share/edit.d.ts +6 -0
  73. package/build/blocks/share/share/edit.d.ts.map +1 -0
  74. package/build/blocks/share/share/edit.js +18 -0
  75. package/build/blocks/share/share/factory.d.ts +5 -0
  76. package/build/blocks/share/share/factory.d.ts.map +1 -0
  77. package/build/blocks/share/share/factory.js +26 -0
  78. package/build/blocks/share/share/icon.d.ts +2 -0
  79. package/build/blocks/share/share/icon.d.ts.map +1 -0
  80. package/build/blocks/share/share/icon.js +2 -0
  81. package/build/blocks/share/share/index.d.ts +5 -0
  82. package/build/blocks/share/share/index.d.ts.map +1 -0
  83. package/build/blocks/share/share/index.js +4 -0
  84. package/build/blocks/share/share/types.d.ts +11 -0
  85. package/build/blocks/share/share/types.d.ts.map +1 -0
  86. package/build/blocks/share/share/types.js +1 -0
  87. package/build/index.d.ts +10 -2
  88. package/build/index.d.ts.map +1 -1
  89. package/build/index.js +5 -1
  90. package/package.json +1 -1
  91. package/src/blocks/career/career-header/edit.tsx +61 -0
  92. package/src/blocks/career/career-header/factory.tsx +28 -0
  93. package/src/blocks/career/career-header/icon.tsx +8 -0
  94. package/src/blocks/career/career-header/index.ts +8 -0
  95. package/src/blocks/career/career-header/types.ts +11 -0
  96. package/src/blocks/career/job-position-group/JobPositionsSelectModal.tsx +238 -0
  97. package/src/blocks/career/job-position-group/constants.ts +11 -0
  98. package/src/blocks/career/job-position-group/edit.tsx +93 -0
  99. package/src/blocks/career/job-position-group/factory.tsx +56 -0
  100. package/src/blocks/career/job-position-group/icon.tsx +7 -0
  101. package/src/blocks/career/job-position-group/index.ts +15 -0
  102. package/src/blocks/career/job-position-group/types.ts +23 -0
  103. package/src/blocks/document/documents-grid/constants.ts +9 -0
  104. package/src/blocks/document/{documents-group → documents-grid}/edit.tsx +17 -15
  105. package/src/blocks/document/documents-grid/factory.tsx +63 -0
  106. package/src/blocks/document/documents-grid/index.ts +15 -0
  107. package/src/blocks/document/documents-grid/types.ts +31 -0
  108. package/src/blocks/post/post-content/edit.tsx +18 -0
  109. package/src/blocks/post/post-content/factory.tsx +22 -0
  110. package/src/blocks/post/post-content/icon.tsx +9 -0
  111. package/src/blocks/post/post-content/index.ts +8 -0
  112. package/src/blocks/post/post-content/types.ts +6 -0
  113. package/src/blocks/share/share/constants.ts +1 -0
  114. package/src/blocks/share/share/edit.tsx +57 -0
  115. package/src/blocks/share/share/factory.tsx +30 -0
  116. package/src/blocks/share/share/icon.tsx +9 -0
  117. package/src/blocks/share/share/index.ts +8 -0
  118. package/src/blocks/share/share/types.ts +12 -0
  119. package/src/index.ts +21 -7
  120. package/build/blocks/document/documents-group/DocumentsSelectModal.d.ts.map +0 -1
  121. package/build/blocks/document/documents-group/constants.d.ts +0 -7
  122. package/build/blocks/document/documents-group/constants.d.ts.map +0 -1
  123. package/build/blocks/document/documents-group/constants.js +0 -5
  124. package/build/blocks/document/documents-group/edit.d.ts +0 -6
  125. package/build/blocks/document/documents-group/edit.d.ts.map +0 -1
  126. package/build/blocks/document/documents-group/factory.d.ts +0 -5
  127. package/build/blocks/document/documents-group/factory.d.ts.map +0 -1
  128. package/build/blocks/document/documents-group/icon.d.ts.map +0 -1
  129. package/build/blocks/document/documents-group/index.d.ts +0 -6
  130. package/build/blocks/document/documents-group/index.d.ts.map +0 -1
  131. package/build/blocks/document/documents-group/index.js +0 -5
  132. package/build/blocks/document/documents-group/types.d.ts +0 -22
  133. package/build/blocks/document/documents-group/types.d.ts.map +0 -1
  134. package/src/blocks/document/documents-group/constants.ts +0 -7
  135. package/src/blocks/document/documents-group/factory.tsx +0 -59
  136. package/src/blocks/document/documents-group/index.ts +0 -15
  137. package/src/blocks/document/documents-group/types.ts +0 -25
  138. /package/build/blocks/{document/documents-group → career/career-header}/icon.d.ts +0 -0
  139. /package/build/blocks/{document/documents-group → career/career-header}/types.js +0 -0
  140. /package/build/blocks/document/{documents-group → documents-grid}/DocumentsSelectModal.d.ts +0 -0
  141. /package/build/blocks/document/{documents-group → documents-grid}/DocumentsSelectModal.js +0 -0
  142. /package/build/blocks/document/{documents-group → documents-grid}/icon.js +0 -0
  143. /package/src/blocks/document/{documents-group → documents-grid}/DocumentsSelectModal.tsx +0 -0
  144. /package/src/blocks/document/{documents-group → documents-grid}/icon.tsx +0 -0
@@ -0,0 +1,238 @@
1
+ import apiFetch from '@wordpress/api-fetch'
2
+ import {Button, Card, CardBody, __experimentalHStack as HStack, Modal, __experimentalVStack as VStack} from '@wordpress/components'
3
+ import {DataViews, type View} from '@wordpress/dataviews/wp'
4
+ import {__} from '@wordpress/i18n'
5
+ import {arrowDown, arrowUp, close, plusCircle} from '@wordpress/icons'
6
+ // biome-ignore lint/correctness/noUnusedImports: required in scope for classic JSX transform
7
+ import React, {useEffect, useMemo, useState} from 'react'
8
+ import type {SelectControlProps} from './types'
9
+
10
+ type JobPositionRecord = {
11
+ id: number
12
+ title: {rendered: string}
13
+ date: string
14
+ }
15
+
16
+ const DEFAULT_VIEW: View = {
17
+ type: 'table',
18
+ search: '',
19
+ filters: [],
20
+ page: 1,
21
+ perPage: 20,
22
+ sort: {field: 'title', direction: 'asc'},
23
+ fields: ['date'],
24
+ titleField: 'title',
25
+ }
26
+
27
+ function useJobPositions() {
28
+ const [positions, setPositions] = useState<JobPositionRecord[]>([])
29
+ const [isLoading, setIsLoading] = useState(true)
30
+
31
+ useEffect(() => {
32
+ setIsLoading(true)
33
+ apiFetch<JobPositionRecord[]>({
34
+ path: '/wp/v2/job_position?per_page=100&orderby=title&order=asc&_fields=id,title,date',
35
+ })
36
+ .then((result) => setPositions(result))
37
+ .catch(() => setPositions([]))
38
+ .finally(() => setIsLoading(false))
39
+ }, [])
40
+
41
+ return {positions, isLoading}
42
+ }
43
+
44
+ function SelectedOrderList({
45
+ items,
46
+ onChange,
47
+ onRemove,
48
+ }: {
49
+ items: JobPositionRecord[]
50
+ onChange: (ids: number[]) => void
51
+ onRemove: (id: number) => void
52
+ }) {
53
+ if (0 === items.length) {
54
+ return <p className="i-job-position-select-modal__empty">{__('Nevybrány žádné pozice.', 'brilo-blocks')}</p>
55
+ }
56
+
57
+ const move = (index: number, direction: -1 | 1) => {
58
+ const target = index + direction
59
+
60
+ if (target < 0 || target >= items.length) {
61
+ return
62
+ }
63
+
64
+ const next = [...items]
65
+ ;[next[index], next[target]] = [next[target], next[index]]
66
+ onChange(next.map((item) => item.id))
67
+ }
68
+
69
+ return (
70
+ <VStack spacing={2}>
71
+ {items.map((item, index) => (
72
+ <Card size="small" className="i-job-position-select-modal__item" key={item.id}>
73
+ <CardBody>
74
+ <HStack alignment="center">
75
+ <span
76
+ className="i-job-position-select-modal__item-title"
77
+ style={{
78
+ flexGrow: 1,
79
+ minWidth: 0,
80
+ textAlign: 'left',
81
+ overflow: 'hidden',
82
+ textOverflow: 'ellipsis',
83
+ whiteSpace: 'nowrap',
84
+ }}
85
+ >
86
+ {item.title.rendered || __('(bez názvu)', 'brilo-blocks')}
87
+ </span>
88
+
89
+ <HStack expanded={false} spacing={1}>
90
+ <Button
91
+ size="small"
92
+ icon={arrowUp}
93
+ label={__('Posunout výš', 'brilo-blocks')}
94
+ onClick={() => move(index, -1)}
95
+ disabled={0 === index}
96
+ />
97
+ <Button
98
+ size="small"
99
+ icon={arrowDown}
100
+ label={__('Posunout níž', 'brilo-blocks')}
101
+ onClick={() => move(index, 1)}
102
+ disabled={index === items.length - 1}
103
+ />
104
+ <Button size="small" icon={close} isDestructive label={__('Odebrat', 'brilo-blocks')} onClick={() => onRemove(item.id)} />
105
+ </HStack>
106
+ </HStack>
107
+ </CardBody>
108
+ </Card>
109
+ ))}
110
+ </VStack>
111
+ )
112
+ }
113
+
114
+ /**
115
+ * Manual job_position picker built on @wordpress/dataviews, mirroring
116
+ * DocumentsSelectModal closely (table view, search, sort, checkbox
117
+ * selection, reorderable selection list) but with just title/date columns.
118
+ */
119
+ export function JobPositionsSelectModal({selectedItems, onChange}: SelectControlProps) {
120
+ const {positions, isLoading} = useJobPositions()
121
+ const [isOpen, setIsOpen] = useState(false)
122
+ const [view, setView] = useState<View>(DEFAULT_VIEW)
123
+
124
+ const selectedPositions = useMemo(
125
+ () => selectedItems.map((id) => positions.find((pos) => pos.id === id)).filter((pos): pos is JobPositionRecord => undefined !== pos),
126
+ [selectedItems, positions],
127
+ )
128
+
129
+ const fields = useMemo(
130
+ () => [
131
+ {
132
+ id: 'title',
133
+ label: __('Název', 'brilo-blocks'),
134
+ enableHiding: false,
135
+ enableSorting: true,
136
+ render: ({item}: {item: JobPositionRecord}) => item.title.rendered || __('(bez názvu)', 'brilo-blocks'),
137
+ },
138
+ {
139
+ id: 'date',
140
+ label: __('Datum', 'brilo-blocks'),
141
+ enableSorting: true,
142
+ render: ({item}: {item: JobPositionRecord}) => (item.date ? new Date(item.date).toLocaleDateString() : '—'),
143
+ },
144
+ ],
145
+ [],
146
+ )
147
+
148
+ const {data, paginationInfo} = useMemo(() => {
149
+ let filtered = positions
150
+
151
+ if (view.search) {
152
+ const needle = view.search.toLowerCase()
153
+ filtered = filtered.filter((pos) => pos.title.rendered.toLowerCase().includes(needle))
154
+ }
155
+
156
+ if (view.sort?.field) {
157
+ const {field, direction} = view.sort
158
+ const sorted = [...filtered]
159
+
160
+ sorted.sort((a, b) => {
161
+ const valueA = 'title' === field ? a.title.rendered : ((a as never)[field] ?? '')
162
+ const valueB = 'title' === field ? b.title.rendered : ((b as never)[field] ?? '')
163
+ const result = String(valueA).localeCompare(String(valueB))
164
+
165
+ return 'desc' === direction ? -result : result
166
+ })
167
+
168
+ filtered = sorted
169
+ }
170
+
171
+ const perPage = view.perPage ?? 20
172
+ const page = view.page ?? 1
173
+ const start = (page - 1) * perPage
174
+
175
+ return {
176
+ data: filtered.slice(start, start + perPage),
177
+ paginationInfo: {totalItems: filtered.length, totalPages: Math.ceil(filtered.length / perPage) || 1},
178
+ }
179
+ }, [positions, view])
180
+
181
+ const toggleSelected = (id: number) => {
182
+ onChange(selectedItems.includes(id) ? selectedItems.filter((itemId) => itemId !== id) : [...selectedItems, id])
183
+ }
184
+
185
+ return (
186
+ <VStack spacing={3} className="i-job-position-select-modal">
187
+ <Button variant="secondary" icon={plusCircle} onClick={() => setIsOpen(true)}>
188
+ {__('Vybrat pozice', 'brilo-blocks')}
189
+ </Button>
190
+
191
+ <SelectedOrderList
192
+ items={selectedPositions}
193
+ onChange={onChange}
194
+ onRemove={(id) => onChange(selectedItems.filter((itemId) => itemId !== id))}
195
+ />
196
+
197
+ {isOpen && (
198
+ <Modal title={__('Vybrat pozice', 'brilo-blocks')} onRequestClose={() => setIsOpen(false)} size="fill">
199
+ <VStack spacing={4} style={{height: '100%'}}>
200
+ <div style={{flexGrow: 1, minHeight: 0}}>
201
+ <DataViews<JobPositionRecord>
202
+ data={data}
203
+ fields={fields}
204
+ view={view}
205
+ onChangeView={setView}
206
+ paginationInfo={paginationInfo}
207
+ isLoading={isLoading}
208
+ defaultLayouts={{table: {}}}
209
+ getItemId={(item) => String(item.id)}
210
+ selection={selectedItems.map(String)}
211
+ onChangeSelection={(ids) => onChange(ids.map(Number))}
212
+ actions={[
213
+ {
214
+ id: 'toggle',
215
+ label: (items) =>
216
+ items.length && selectedItems.includes(items[0].id) ? __('Odebrat', 'brilo-blocks') : __('Přidat', 'brilo-blocks'),
217
+ supportsBulk: true,
218
+ callback: (items) => {
219
+ items.forEach((item) => {
220
+ toggleSelected(item.id)
221
+ })
222
+ },
223
+ },
224
+ ]}
225
+ />
226
+ </div>
227
+
228
+ <HStack justify="flex-end">
229
+ <Button variant="primary" onClick={() => setIsOpen(false)}>
230
+ {__('Hotovo', 'brilo-blocks')}
231
+ </Button>
232
+ </HStack>
233
+ </VStack>
234
+ </Modal>
235
+ )}
236
+ </VStack>
237
+ )
238
+ }
@@ -0,0 +1,11 @@
1
+ export const JOB_POSITION_GROUP_MODES = ['selected', 'listing'] as const
2
+ export const JOB_POSITION_GROUP_SORT_BYS = ['date', 'title', 'start_date', 'menu_order'] as const
3
+ export const JOB_POSITION_GROUP_SORT_ORDERS = ['asc', 'desc'] as const
4
+
5
+ export const JOB_POSITION_GROUP_MODE = JOB_POSITION_GROUP_MODES[0]
6
+ export const JOB_POSITION_GROUP_SORT_BY = JOB_POSITION_GROUP_SORT_BYS[0]
7
+ export const JOB_POSITION_GROUP_SORT_ORDER = JOB_POSITION_GROUP_SORT_ORDERS[1]
8
+
9
+ export const JOB_POSITION_GROUP_PER_PAGE_MIN = 1
10
+ export const JOB_POSITION_GROUP_PER_PAGE_MAX = 24
11
+ export const JOB_POSITION_GROUP_PER_PAGE = 6
@@ -0,0 +1,93 @@
1
+ import {InspectorControls, useBlockProps} from '@wordpress/block-editor'
2
+ import {
3
+ PanelBody,
4
+ RangeControl,
5
+ __experimentalToggleGroupControl as ToggleGroupControl,
6
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
7
+ } from '@wordpress/components'
8
+ import {__} from '@wordpress/i18n'
9
+ import {JOB_POSITION_GROUP_PER_PAGE, JOB_POSITION_GROUP_PER_PAGE_MAX, JOB_POSITION_GROUP_PER_PAGE_MIN} from './constants'
10
+ import type {JobPositionGroupAttributes, JobPositionGroupOptions} from './types'
11
+
12
+ export function createJobPositionGroupEdit(options: JobPositionGroupOptions) {
13
+ return function Edit({
14
+ attributes,
15
+ setAttributes,
16
+ }: {
17
+ attributes: JobPositionGroupAttributes
18
+ setAttributes: (a: Partial<JobPositionGroupAttributes>) => void
19
+ }) {
20
+ const {mode, selectedPositions, perPage, sortBy, sortOrder} = attributes
21
+
22
+ const blockProps = useBlockProps({className: 'wp-block-section'})
23
+
24
+ return (
25
+ <>
26
+ <InspectorControls>
27
+ <PanelBody title={__('Nastavení výpisu', 'brilo-blocks')} initialOpen>
28
+ <ToggleGroupControl
29
+ label={__('Zdroj pozic', 'brilo-blocks')}
30
+ value={mode}
31
+ onChange={(value) => setAttributes({mode: value as JobPositionGroupAttributes['mode']})}
32
+ isBlock
33
+ >
34
+ <ToggleGroupControlOption value="selected" label={__('Vybrané', 'brilo-blocks')} />
35
+ <ToggleGroupControlOption value="listing" label={__('Výpis', 'brilo-blocks')} />
36
+ </ToggleGroupControl>
37
+
38
+ {'listing' === mode && (
39
+ <>
40
+ <RangeControl
41
+ label={__('Počet pozic', 'brilo-blocks')}
42
+ value={perPage}
43
+ onChange={(value) => setAttributes({perPage: value ?? JOB_POSITION_GROUP_PER_PAGE})}
44
+ min={JOB_POSITION_GROUP_PER_PAGE_MIN}
45
+ max={JOB_POSITION_GROUP_PER_PAGE_MAX}
46
+ />
47
+
48
+ <ToggleGroupControl
49
+ label={__('Řazení', 'brilo-blocks')}
50
+ value={sortBy}
51
+ onChange={(value) => setAttributes({sortBy: value as JobPositionGroupAttributes['sortBy']})}
52
+ isBlock
53
+ >
54
+ <ToggleGroupControlOption value="date" label={__('Datum publikace', 'brilo-blocks')} />
55
+ <ToggleGroupControlOption value="title" label={__('Název', 'brilo-blocks')} />
56
+ <ToggleGroupControlOption value="start_date" label={__('Datum nástupu', 'brilo-blocks')} />
57
+ <ToggleGroupControlOption value="menu_order" label={__('Pořadí', 'brilo-blocks')} />
58
+ </ToggleGroupControl>
59
+
60
+ <ToggleGroupControl
61
+ label={__('Směr řazení', 'brilo-blocks')}
62
+ value={sortOrder}
63
+ onChange={(value) => setAttributes({sortOrder: value as JobPositionGroupAttributes['sortOrder']})}
64
+ isBlock
65
+ >
66
+ <ToggleGroupControlOption value="desc" label={__('Sestupně', 'brilo-blocks')} />
67
+ <ToggleGroupControlOption value="asc" label={__('Vzestupně', 'brilo-blocks')} />
68
+ </ToggleGroupControl>
69
+ </>
70
+ )}
71
+ </PanelBody>
72
+ </InspectorControls>
73
+
74
+ <div {...blockProps}>
75
+ {'selected' === mode &&
76
+ options.renderPositionsControl?.({
77
+ selectedItems: selectedPositions,
78
+ onChange: (ids: number[]) => setAttributes({selectedPositions: ids}),
79
+ })}
80
+
81
+ {'listing' === mode && (
82
+ <div className="components-placeholder">
83
+ <div className="components-placeholder__label">{__('Pracovní pozice', 'brilo-blocks')}</div>
84
+ <div className="components-placeholder__instructions">
85
+ {`${__('Zobrazí', 'brilo-blocks')} ${perPage} ${__('pracovních pozic.', 'brilo-blocks')}`}
86
+ </div>
87
+ </div>
88
+ )}
89
+ </div>
90
+ </>
91
+ )
92
+ }
93
+ }
@@ -0,0 +1,56 @@
1
+ import type {BlockConfiguration} from '@wordpress/blocks'
2
+ import {__} from '@wordpress/i18n'
3
+ import {
4
+ JOB_POSITION_GROUP_MODE,
5
+ JOB_POSITION_GROUP_MODES,
6
+ JOB_POSITION_GROUP_PER_PAGE,
7
+ JOB_POSITION_GROUP_SORT_BY,
8
+ JOB_POSITION_GROUP_SORT_BYS,
9
+ JOB_POSITION_GROUP_SORT_ORDER,
10
+ JOB_POSITION_GROUP_SORT_ORDERS,
11
+ } from './constants'
12
+ import {createJobPositionGroupEdit} from './edit'
13
+ import {icon as defaultIcon} from './icon'
14
+ import type {JobPositionGroupAttributes, JobPositionGroupOptions} from './types'
15
+
16
+ export type {JobPositionGroupAttributes, JobPositionGroupOptions}
17
+
18
+ export function createJobPositionGroupBlock(options: JobPositionGroupOptions): BlockConfiguration<JobPositionGroupAttributes> {
19
+ return {
20
+ name: options.name,
21
+ title: options.title ?? __('Pracovní pozice', 'brilo-blocks'),
22
+ description: options.description,
23
+ category: options.category ?? 'widgets',
24
+ ...(options.parent && {parent: options.parent}),
25
+ icon: options.icon ?? {src: defaultIcon},
26
+ supports: {html: false, customClassName: false},
27
+ attributes: {
28
+ mode: {
29
+ type: 'string',
30
+ default: JOB_POSITION_GROUP_MODE,
31
+ enum: [...JOB_POSITION_GROUP_MODES],
32
+ },
33
+ selectedPositions: {
34
+ type: 'array',
35
+ default: [],
36
+ items: {type: 'number'},
37
+ },
38
+ perPage: {
39
+ type: 'number',
40
+ default: JOB_POSITION_GROUP_PER_PAGE,
41
+ },
42
+ sortBy: {
43
+ type: 'string',
44
+ default: JOB_POSITION_GROUP_SORT_BY,
45
+ enum: [...JOB_POSITION_GROUP_SORT_BYS],
46
+ },
47
+ sortOrder: {
48
+ type: 'string',
49
+ default: JOB_POSITION_GROUP_SORT_ORDER,
50
+ enum: [...JOB_POSITION_GROUP_SORT_ORDERS],
51
+ },
52
+ },
53
+ edit: createJobPositionGroupEdit(options),
54
+ save: () => null,
55
+ } as unknown as BlockConfiguration<JobPositionGroupAttributes>
56
+ }
@@ -0,0 +1,7 @@
1
+ export const icon = (
2
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <rect x="2" y="6" width="16" height="11" rx="1" stroke="black" fill="none" />
4
+ <path d="M7 6V4C7 3.44772 7.44772 3 8 3H12C12.5523 3 13 3.44772 13 4V6" stroke="black" fill="none" />
5
+ <line x1="2" y1="11" x2="18" y2="11" stroke="black" />
6
+ </svg>
7
+ )
@@ -0,0 +1,15 @@
1
+ export type {
2
+ JobPositionGroupAttributes,
3
+ JobPositionGroupOptions,
4
+ JobPositionGroupMode,
5
+ JobPositionGroupSortBy,
6
+ JobPositionGroupSortOrder,
7
+ } from './types'
8
+ export {createJobPositionGroupBlock} from './factory'
9
+ export {JobPositionsSelectModal} from './JobPositionsSelectModal'
10
+
11
+ import type {JobPositionGroupOptions} from './types'
12
+
13
+ export const jobPositionGroupDefaults: JobPositionGroupOptions = {
14
+ name: 'brilo/job-position-group',
15
+ }
@@ -0,0 +1,23 @@
1
+ import type {BriloBlockType} from '~/types'
2
+ import type {JOB_POSITION_GROUP_MODES, JOB_POSITION_GROUP_SORT_BYS, JOB_POSITION_GROUP_SORT_ORDERS} from './constants'
3
+
4
+ export type JobPositionGroupMode = (typeof JOB_POSITION_GROUP_MODES)[number]
5
+ export type JobPositionGroupSortBy = (typeof JOB_POSITION_GROUP_SORT_BYS)[number]
6
+ export type JobPositionGroupSortOrder = (typeof JOB_POSITION_GROUP_SORT_ORDERS)[number]
7
+
8
+ export interface JobPositionGroupAttributes extends Record<string, unknown> {
9
+ mode: JobPositionGroupMode
10
+ selectedPositions: number[]
11
+ perPage: number
12
+ sortBy: JobPositionGroupSortBy
13
+ sortOrder: JobPositionGroupSortOrder
14
+ }
15
+
16
+ export interface SelectControlProps {
17
+ selectedItems: number[]
18
+ onChange: (ids: number[]) => void
19
+ }
20
+
21
+ export interface JobPositionGroupOptions extends BriloBlockType {
22
+ renderPositionsControl?: (props: SelectControlProps) => JSX.Element
23
+ }
@@ -0,0 +1,9 @@
1
+ export const DOCUMENTS_GRID_MODES = ['manual', 'category'] as const
2
+ export const DOCUMENTS_GRID_LISTING_STYLES = ['classic', 'group-by-category'] as const
3
+ export const DOCUMENTS_GRID_SORT_BYS = ['menu_order', 'date', 'manual-order'] as const
4
+ export const DOCUMENTS_GRID_COLUMN_OPTIONS = [1, 2, 3, 4, 6] as const
5
+
6
+ export const DOCUMENTS_GRID_MODE = DOCUMENTS_GRID_MODES[0]
7
+ export const DOCUMENTS_GRID_LISTING_STYLE = DOCUMENTS_GRID_LISTING_STYLES[0]
8
+ export const DOCUMENTS_GRID_SORT_BY = DOCUMENTS_GRID_SORT_BYS[2]
9
+ export const DOCUMENTS_GRID_COLUMNS = DOCUMENTS_GRID_COLUMN_OPTIONS[0]
@@ -5,20 +5,21 @@ import {
5
5
  __experimentalToggleGroupControlOption as ToggleGroupControlOption,
6
6
  } from '@wordpress/components'
7
7
  import {__} from '@wordpress/i18n'
8
- import {DOCUMENTS_GROUP_COLUMNS} from './constants'
9
- import type {DocumentsGroupAttributes, DocumentsGroupOptions} from './types'
8
+ import clsx from 'clsx'
9
+ import {DOCUMENTS_GRID_COLUMN_OPTIONS} from './constants'
10
+ import type {DocumentsGridAttributes, DocumentsGridOptions} from './types'
10
11
 
11
- export function createDocumentsGroupEdit(options: DocumentsGroupOptions) {
12
+ export function createDocumentsGridEdit(options: DocumentsGridOptions) {
12
13
  return function Edit({
13
14
  attributes,
14
15
  setAttributes,
15
16
  }: {
16
- attributes: DocumentsGroupAttributes
17
- setAttributes: (a: Partial<DocumentsGroupAttributes>) => void
17
+ attributes: DocumentsGridAttributes
18
+ setAttributes: (a: Partial<DocumentsGridAttributes>) => void
18
19
  }) {
19
20
  const {mode, listingStyle, sortBy, columns, selectedDocuments, selectedCategories} = attributes
20
21
 
21
- const blockProps = useBlockProps({className: 'wp-block-section'})
22
+ const blockProps = useBlockProps({className: clsx(options.blockClassName ?? 'g-documents wp-block-section')})
22
23
 
23
24
  return (
24
25
  <>
@@ -28,11 +29,12 @@ export function createDocumentsGroupEdit(options: DocumentsGroupOptions) {
28
29
  label={__('Zdroj dokumentů', 'brilo-blocks')}
29
30
  value={mode}
30
31
  onChange={(value) => {
31
- const nextMode = value as DocumentsGroupAttributes['mode']
32
- setAttributes({
33
- mode: nextMode,
34
- sortBy: 'manual' === nextMode ? sortBy : sortBy === 'manual-order' ? 'menu_order' : sortBy,
35
- })
32
+ const nextMode = value as DocumentsGridAttributes['mode']
33
+ // "manual-order" sorting only makes sense for a manually picked list —
34
+ // fall back to "menu_order" when switching away from manual mode.
35
+ const nextSortBy = 'category' === nextMode && 'manual-order' === sortBy ? 'menu_order' : sortBy
36
+
37
+ setAttributes({mode: nextMode, sortBy: nextSortBy})
36
38
  }}
37
39
  isBlock
38
40
  >
@@ -43,7 +45,7 @@ export function createDocumentsGroupEdit(options: DocumentsGroupOptions) {
43
45
  <ToggleGroupControl
44
46
  label={__('Styl výpisu', 'brilo-blocks')}
45
47
  value={listingStyle}
46
- onChange={(value) => setAttributes({listingStyle: value as DocumentsGroupAttributes['listingStyle']})}
48
+ onChange={(value) => setAttributes({listingStyle: value as DocumentsGridAttributes['listingStyle']})}
47
49
  isBlock
48
50
  >
49
51
  <ToggleGroupControlOption value="classic" label={__('Klasický výpis', 'brilo-blocks')} />
@@ -53,7 +55,7 @@ export function createDocumentsGroupEdit(options: DocumentsGroupOptions) {
53
55
  <ToggleGroupControl
54
56
  label={__('Řazení', 'brilo-blocks')}
55
57
  value={sortBy}
56
- onChange={(value) => setAttributes({sortBy: value as DocumentsGroupAttributes['sortBy']})}
58
+ onChange={(value) => setAttributes({sortBy: value as DocumentsGridAttributes['sortBy']})}
57
59
  isBlock
58
60
  >
59
61
  <ToggleGroupControlOption value="menu_order" label={__('Pořadí', 'brilo-blocks')} />
@@ -67,10 +69,10 @@ export function createDocumentsGroupEdit(options: DocumentsGroupOptions) {
67
69
  'group-by-category' === listingStyle ? __('Platí pro seznam dokumentů uvnitř každé kategorie.', 'brilo-blocks') : undefined
68
70
  }
69
71
  value={String(columns)}
70
- onChange={(value) => setAttributes({columns: Number(value) as DocumentsGroupAttributes['columns']})}
72
+ onChange={(value) => setAttributes({columns: Number(value) as DocumentsGridAttributes['columns']})}
71
73
  isBlock
72
74
  >
73
- {DOCUMENTS_GROUP_COLUMNS.map((c) => (
75
+ {DOCUMENTS_GRID_COLUMN_OPTIONS.map((c) => (
74
76
  <ToggleGroupControlOption key={c} value={String(c)} label={String(c)} />
75
77
  ))}
76
78
  </ToggleGroupControl>
@@ -0,0 +1,63 @@
1
+ import type {BlockConfiguration} from '@wordpress/blocks'
2
+ import {__} from '@wordpress/i18n'
3
+ import {
4
+ DOCUMENTS_GRID_COLUMN_OPTIONS,
5
+ DOCUMENTS_GRID_COLUMNS,
6
+ DOCUMENTS_GRID_LISTING_STYLE,
7
+ DOCUMENTS_GRID_LISTING_STYLES,
8
+ DOCUMENTS_GRID_MODE,
9
+ DOCUMENTS_GRID_MODES,
10
+ DOCUMENTS_GRID_SORT_BY,
11
+ DOCUMENTS_GRID_SORT_BYS,
12
+ } from './constants'
13
+ import {createDocumentsGridEdit} from './edit'
14
+ import {icon as defaultIcon} from './icon'
15
+ import type {DocumentsGridAttributes, DocumentsGridOptions} from './types'
16
+
17
+ export type {DocumentsGridAttributes, DocumentsGridOptions}
18
+
19
+ export function createDocumentsGridBlock(options: DocumentsGridOptions): BlockConfiguration<DocumentsGridAttributes> {
20
+ return {
21
+ name: options.name,
22
+ title: options.title ?? __('Dokumenty', 'brilo-blocks'),
23
+ description: options.description,
24
+ category: options.category ?? 'widgets',
25
+ ...(options.parent && {parent: options.parent}),
26
+ icon: options.icon ?? {src: defaultIcon},
27
+ supports: {html: false, customClassName: false},
28
+ attributes: {
29
+ mode: {
30
+ type: 'string',
31
+ default: DOCUMENTS_GRID_MODE,
32
+ enum: [...DOCUMENTS_GRID_MODES],
33
+ },
34
+ listingStyle: {
35
+ type: 'string',
36
+ default: DOCUMENTS_GRID_LISTING_STYLE,
37
+ enum: [...DOCUMENTS_GRID_LISTING_STYLES],
38
+ },
39
+ sortBy: {
40
+ type: 'string',
41
+ default: DOCUMENTS_GRID_SORT_BY,
42
+ enum: [...DOCUMENTS_GRID_SORT_BYS],
43
+ },
44
+ columns: {
45
+ type: 'number',
46
+ default: DOCUMENTS_GRID_COLUMNS,
47
+ enum: [...DOCUMENTS_GRID_COLUMN_OPTIONS],
48
+ },
49
+ selectedDocuments: {
50
+ type: 'array',
51
+ default: [],
52
+ items: {type: 'number'},
53
+ },
54
+ selectedCategories: {
55
+ type: 'array',
56
+ default: [],
57
+ items: {type: 'number'},
58
+ },
59
+ },
60
+ edit: createDocumentsGridEdit(options),
61
+ save: () => null,
62
+ } as unknown as BlockConfiguration<DocumentsGridAttributes>
63
+ }
@@ -0,0 +1,15 @@
1
+ export type {
2
+ DocumentsGridAttributes,
3
+ DocumentsGridOptions,
4
+ DocumentsGridListingStyle,
5
+ DocumentsGridMode,
6
+ DocumentsGridSortBy,
7
+ } from './types'
8
+ export {createDocumentsGridBlock} from './factory'
9
+ export {DocumentsSelectModal} from './DocumentsSelectModal'
10
+
11
+ import type {DocumentsGridOptions} from './types'
12
+
13
+ export const documentsGridDefaults: DocumentsGridOptions = {
14
+ name: 'brilo/documents-grid',
15
+ }
@@ -0,0 +1,31 @@
1
+ import type {BriloBlockType} from '~/types'
2
+ import type {
3
+ DOCUMENTS_GRID_COLUMN_OPTIONS,
4
+ DOCUMENTS_GRID_LISTING_STYLES,
5
+ DOCUMENTS_GRID_MODES,
6
+ DOCUMENTS_GRID_SORT_BYS,
7
+ } from './constants'
8
+
9
+ export type DocumentsGridMode = (typeof DOCUMENTS_GRID_MODES)[number]
10
+ export type DocumentsGridListingStyle = (typeof DOCUMENTS_GRID_LISTING_STYLES)[number]
11
+ export type DocumentsGridSortBy = (typeof DOCUMENTS_GRID_SORT_BYS)[number]
12
+ export type DocumentsGridColumns = (typeof DOCUMENTS_GRID_COLUMN_OPTIONS)[number]
13
+
14
+ export interface DocumentsGridAttributes extends Record<string, unknown> {
15
+ mode: DocumentsGridMode
16
+ listingStyle: DocumentsGridListingStyle
17
+ sortBy: DocumentsGridSortBy
18
+ columns: DocumentsGridColumns
19
+ selectedDocuments: number[]
20
+ selectedCategories: number[]
21
+ }
22
+
23
+ export interface SelectControlProps {
24
+ selectedItems: number[]
25
+ onChange: (ids: number[]) => void
26
+ }
27
+
28
+ export interface DocumentsGridOptions extends BriloBlockType {
29
+ renderCategoryControl?: (props: SelectControlProps) => JSX.Element
30
+ renderDocumentsControl?: (props: SelectControlProps) => JSX.Element
31
+ }
@@ -0,0 +1,18 @@
1
+ import {useBlockProps} from '@wordpress/block-editor'
2
+ import {__} from '@wordpress/i18n'
3
+ import type {PostContentAttributes, PostContentOptions} from './types'
4
+
5
+ export function createPostContentEdit(_options: PostContentOptions) {
6
+ return function Edit(_props: {attributes: PostContentAttributes; setAttributes: (a: Partial<PostContentAttributes>) => void}) {
7
+ const blockProps = useBlockProps({className: 'wp-block-section'})
8
+
9
+ return (
10
+ <div {...blockProps}>
11
+ <div className="components-placeholder">
12
+ <div className="components-placeholder__label">{__('Obsah postu', 'brilo-blocks')}</div>
13
+ <div className="components-placeholder__instructions">{__('Zobrazí obsah aktuální postu.', 'brilo-blocks')}</div>
14
+ </div>
15
+ </div>
16
+ )
17
+ }
18
+ }