@brilo/base-blocks 0.1.27 → 0.1.29
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.
- package/build/.tsbuildinfo +1 -1
- package/build/blocks/career/career-header/edit.d.ts +6 -0
- package/build/blocks/career/career-header/edit.d.ts.map +1 -0
- package/build/blocks/career/career-header/edit.js +11 -0
- package/build/blocks/career/career-header/factory.d.ts +5 -0
- package/build/blocks/career/career-header/factory.d.ts.map +1 -0
- package/build/blocks/career/career-header/factory.js +24 -0
- package/build/blocks/career/career-header/icon.d.ts +2 -0
- package/build/blocks/career/career-header/icon.d.ts.map +1 -0
- package/build/blocks/career/career-header/icon.js +2 -0
- package/build/blocks/career/career-header/index.d.ts +5 -0
- package/build/blocks/career/career-header/index.d.ts.map +1 -0
- package/build/blocks/career/career-header/index.js +4 -0
- package/build/blocks/career/career-header/types.d.ts +10 -0
- package/build/blocks/career/career-header/types.d.ts.map +1 -0
- package/build/blocks/career/career-header/types.js +1 -0
- package/build/blocks/career/job-position-group/JobPositionsSelectModal.d.ts +9 -0
- package/build/blocks/career/job-position-group/JobPositionsSelectModal.d.ts.map +1 -0
- package/build/blocks/career/job-position-group/JobPositionsSelectModal.js +123 -0
- package/build/blocks/career/job-position-group/constants.d.ts +10 -0
- package/build/blocks/career/job-position-group/constants.d.ts.map +1 -0
- package/build/blocks/career/job-position-group/constants.js +9 -0
- package/build/blocks/career/job-position-group/edit.d.ts +6 -0
- package/build/blocks/career/job-position-group/edit.d.ts.map +1 -0
- package/build/blocks/career/job-position-group/edit.js +17 -0
- package/build/blocks/career/job-position-group/factory.d.ts +5 -0
- package/build/blocks/career/job-position-group/factory.d.ts.map +1 -0
- package/build/blocks/career/job-position-group/factory.js +44 -0
- package/build/blocks/career/job-position-group/icon.d.ts +2 -0
- package/build/blocks/career/job-position-group/icon.d.ts.map +1 -0
- package/build/blocks/career/job-position-group/icon.js +2 -0
- package/build/blocks/career/job-position-group/index.d.ts +6 -0
- package/build/blocks/career/job-position-group/index.d.ts.map +1 -0
- package/build/blocks/career/job-position-group/index.js +5 -0
- package/build/blocks/career/job-position-group/types.d.ts +20 -0
- package/build/blocks/career/job-position-group/types.d.ts.map +1 -0
- package/build/blocks/career/job-position-group/types.js +1 -0
- package/build/blocks/document/documents-group/DocumentsSelectModal.d.ts +12 -0
- package/build/blocks/document/documents-group/DocumentsSelectModal.d.ts.map +1 -0
- package/build/blocks/document/documents-group/DocumentsSelectModal.js +153 -0
- package/build/blocks/document/documents-group/constants.d.ts +7 -0
- package/build/blocks/document/documents-group/constants.d.ts.map +1 -0
- package/build/blocks/document/documents-group/constants.js +5 -0
- package/build/blocks/document/documents-group/edit.d.ts +6 -0
- package/build/blocks/document/documents-group/edit.d.ts.map +1 -0
- package/build/blocks/document/documents-group/edit.js +27 -0
- package/build/blocks/document/documents-group/factory.d.ts +5 -0
- package/build/blocks/document/documents-group/factory.d.ts.map +1 -0
- package/build/blocks/document/documents-group/factory.js +50 -0
- package/build/blocks/document/documents-group/icon.d.ts +2 -0
- package/build/blocks/document/documents-group/icon.d.ts.map +1 -0
- package/build/blocks/document/documents-group/icon.js +2 -0
- package/build/blocks/document/documents-group/index.d.ts +6 -0
- package/build/blocks/document/documents-group/index.d.ts.map +1 -0
- package/build/blocks/document/documents-group/index.js +5 -0
- package/build/blocks/document/documents-group/types.d.ts +22 -0
- package/build/blocks/document/documents-group/types.d.ts.map +1 -0
- package/build/blocks/document/documents-group/types.js +1 -0
- package/build/blocks/layout/layout-aside/factory.d.ts.map +1 -1
- package/build/blocks/layout/layout-aside/icon.d.ts.map +1 -1
- package/build/blocks/layout/layout-content/factory.d.ts.map +1 -1
- package/build/blocks/layout/layout-content/icon.d.ts.map +1 -1
- package/build/blocks/layout/layout-content-w-aside/edit.d.ts.map +1 -1
- package/build/blocks/layout/layout-content-w-aside/edit.js +1 -1
- package/build/blocks/layout/layout-content-w-aside/factory.d.ts.map +1 -1
- package/build/blocks/layout/layout-content-w-aside/icon.d.ts.map +1 -1
- package/build/blocks/post/post-content/edit.d.ts +6 -0
- package/build/blocks/post/post-content/edit.d.ts.map +1 -0
- package/build/blocks/post/post-content/edit.js +9 -0
- package/build/blocks/post/post-content/factory.d.ts +5 -0
- package/build/blocks/post/post-content/factory.d.ts.map +1 -0
- package/build/blocks/post/post-content/factory.js +18 -0
- package/build/blocks/post/post-content/icon.d.ts +2 -0
- package/build/blocks/post/post-content/icon.d.ts.map +1 -0
- package/build/blocks/post/post-content/icon.js +2 -0
- package/build/blocks/post/post-content/index.d.ts +5 -0
- package/build/blocks/post/post-content/index.d.ts.map +1 -0
- package/build/blocks/post/post-content/index.js +4 -0
- package/build/blocks/post/post-content/types.d.ts +5 -0
- package/build/blocks/post/post-content/types.d.ts.map +1 -0
- package/build/blocks/post/post-content/types.js +1 -0
- package/build/blocks/sections/base-section/controls.d.ts.map +1 -1
- package/build/blocks/sections/base-section/controls.js +1 -1
- package/build/blocks/share/share/constants.d.ts +2 -0
- package/build/blocks/share/share/constants.d.ts.map +1 -0
- package/build/blocks/share/share/constants.js +1 -0
- package/build/blocks/share/share/edit.d.ts +6 -0
- package/build/blocks/share/share/edit.d.ts.map +1 -0
- package/build/blocks/share/share/edit.js +18 -0
- package/build/blocks/share/share/factory.d.ts +5 -0
- package/build/blocks/share/share/factory.d.ts.map +1 -0
- package/build/blocks/share/share/factory.js +26 -0
- package/build/blocks/share/share/icon.d.ts +2 -0
- package/build/blocks/share/share/icon.d.ts.map +1 -0
- package/build/blocks/share/share/icon.js +2 -0
- package/build/blocks/share/share/index.d.ts +5 -0
- package/build/blocks/share/share/index.d.ts.map +1 -0
- package/build/blocks/share/share/index.js +4 -0
- package/build/blocks/share/share/types.d.ts +11 -0
- package/build/blocks/share/share/types.d.ts.map +1 -0
- package/build/blocks/share/share/types.js +1 -0
- package/build/index.d.ts +10 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -0
- package/package.json +6 -1
- package/src/blocks/career/career-header/edit.tsx +61 -0
- package/src/blocks/career/career-header/factory.tsx +28 -0
- package/src/blocks/career/career-header/icon.tsx +8 -0
- package/src/blocks/career/career-header/index.ts +8 -0
- package/src/blocks/career/career-header/types.ts +11 -0
- package/src/blocks/career/job-position-group/JobPositionsSelectModal.tsx +238 -0
- package/src/blocks/career/job-position-group/constants.ts +11 -0
- package/src/blocks/career/job-position-group/edit.tsx +93 -0
- package/src/blocks/career/job-position-group/factory.tsx +56 -0
- package/src/blocks/career/job-position-group/icon.tsx +7 -0
- package/src/blocks/career/job-position-group/index.ts +15 -0
- package/src/blocks/career/job-position-group/types.ts +23 -0
- package/src/blocks/document/documents-group/DocumentsSelectModal.tsx +273 -0
- package/src/blocks/document/documents-group/constants.ts +7 -0
- package/src/blocks/document/documents-group/edit.tsx +96 -0
- package/src/blocks/document/documents-group/factory.tsx +59 -0
- package/src/blocks/document/documents-group/icon.tsx +9 -0
- package/src/blocks/document/documents-group/index.ts +15 -0
- package/src/blocks/document/documents-group/types.ts +25 -0
- package/src/blocks/layout/layout-aside/factory.tsx +1 -3
- package/src/blocks/layout/layout-aside/icon.tsx +1 -6
- package/src/blocks/layout/layout-content/editor.scss +1 -1
- package/src/blocks/layout/layout-content/factory.tsx +1 -3
- package/src/blocks/layout/layout-content/icon.tsx +1 -6
- package/src/blocks/layout/layout-content-w-aside/edit.tsx +5 -1
- package/src/blocks/layout/layout-content-w-aside/factory.tsx +1 -3
- package/src/blocks/layout/layout-content-w-aside/icon.tsx +1 -6
- package/src/blocks/post/post-content/edit.tsx +18 -0
- package/src/blocks/post/post-content/factory.tsx +22 -0
- package/src/blocks/post/post-content/icon.tsx +9 -0
- package/src/blocks/post/post-content/index.ts +8 -0
- package/src/blocks/post/post-content/types.ts +6 -0
- package/src/blocks/sections/base-section/controls.tsx +7 -1
- package/src/blocks/share/share/constants.ts +1 -0
- package/src/blocks/share/share/edit.tsx +57 -0
- package/src/blocks/share/share/factory.tsx +30 -0
- package/src/blocks/share/share/icon.tsx +9 -0
- package/src/blocks/share/share/index.ts +8 -0
- package/src/blocks/share/share/types.ts +12 -0
- package/src/index.ts +22 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {InspectorControls, useBlockProps} from '@wordpress/block-editor'
|
|
2
|
+
import {PanelBody, ToggleControl} from '@wordpress/components'
|
|
3
|
+
import {__} from '@wordpress/i18n'
|
|
4
|
+
import type {CareerHeaderAttributes, CareerHeaderOptions} from './types'
|
|
5
|
+
|
|
6
|
+
export function createCareerHeaderEdit(_options: CareerHeaderOptions) {
|
|
7
|
+
return function Edit({
|
|
8
|
+
attributes,
|
|
9
|
+
setAttributes,
|
|
10
|
+
}: {
|
|
11
|
+
attributes: CareerHeaderAttributes
|
|
12
|
+
setAttributes: (a: Partial<CareerHeaderAttributes>) => void
|
|
13
|
+
}) {
|
|
14
|
+
const {showExcerpt, showLocation, showSalary, showBenefits, showEmploymentType} = attributes
|
|
15
|
+
|
|
16
|
+
const blockProps = useBlockProps({className: 'wp-block-section'})
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<>
|
|
20
|
+
<InspectorControls>
|
|
21
|
+
<PanelBody title={__('Zobrazené údaje', 'brilo-blocks')} initialOpen>
|
|
22
|
+
<ToggleControl
|
|
23
|
+
label={__('Zobrazit perex', 'brilo-blocks')}
|
|
24
|
+
checked={showExcerpt}
|
|
25
|
+
onChange={(value) => setAttributes({showExcerpt: value})}
|
|
26
|
+
/>
|
|
27
|
+
<ToggleControl
|
|
28
|
+
label={__('Zobrazit lokalitu', 'brilo-blocks')}
|
|
29
|
+
checked={showLocation}
|
|
30
|
+
onChange={(value) => setAttributes({showLocation: value})}
|
|
31
|
+
/>
|
|
32
|
+
<ToggleControl
|
|
33
|
+
label={__('Zobrazit plat', 'brilo-blocks')}
|
|
34
|
+
checked={showSalary}
|
|
35
|
+
onChange={(value) => setAttributes({showSalary: value})}
|
|
36
|
+
/>
|
|
37
|
+
<ToggleControl
|
|
38
|
+
label={__('Zobrazit benefity', 'brilo-blocks')}
|
|
39
|
+
checked={showBenefits}
|
|
40
|
+
onChange={(value) => setAttributes({showBenefits: value})}
|
|
41
|
+
/>
|
|
42
|
+
<ToggleControl
|
|
43
|
+
label={__('Zobrazit typ úvazku', 'brilo-blocks')}
|
|
44
|
+
checked={showEmploymentType}
|
|
45
|
+
onChange={(value) => setAttributes({showEmploymentType: value})}
|
|
46
|
+
/>
|
|
47
|
+
</PanelBody>
|
|
48
|
+
</InspectorControls>
|
|
49
|
+
|
|
50
|
+
<div {...blockProps}>
|
|
51
|
+
<div className="components-placeholder">
|
|
52
|
+
<div className="components-placeholder__label">{__('Hlavička kariéry', 'brilo-blocks')}</div>
|
|
53
|
+
<div className="components-placeholder__instructions">
|
|
54
|
+
{__('Zobrazí data aktuální pozice — název, perex, lokalitu, plat, benefity a typ úvazku.', 'brilo-blocks')}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type {BlockConfiguration} from '@wordpress/blocks'
|
|
2
|
+
import {__} from '@wordpress/i18n'
|
|
3
|
+
import {createCareerHeaderEdit} from './edit'
|
|
4
|
+
import {icon as defaultIcon} from './icon'
|
|
5
|
+
import type {CareerHeaderAttributes, CareerHeaderOptions} from './types'
|
|
6
|
+
|
|
7
|
+
export type {CareerHeaderAttributes, CareerHeaderOptions}
|
|
8
|
+
|
|
9
|
+
export function createCareerHeaderBlock(options: CareerHeaderOptions): BlockConfiguration<CareerHeaderAttributes> {
|
|
10
|
+
return {
|
|
11
|
+
name: options.name,
|
|
12
|
+
title: options.title ?? __('Hlavička kariéry', 'brilo-blocks'),
|
|
13
|
+
description: options.description,
|
|
14
|
+
category: options.category ?? 'widgets',
|
|
15
|
+
...(options.parent && {parent: options.parent}),
|
|
16
|
+
icon: options.icon ?? {src: defaultIcon},
|
|
17
|
+
supports: {html: false, customClassName: false},
|
|
18
|
+
attributes: {
|
|
19
|
+
showExcerpt: {type: 'boolean', default: true},
|
|
20
|
+
showLocation: {type: 'boolean', default: true},
|
|
21
|
+
showSalary: {type: 'boolean', default: true},
|
|
22
|
+
showBenefits: {type: 'boolean', default: true},
|
|
23
|
+
showEmploymentType: {type: 'boolean', default: true},
|
|
24
|
+
},
|
|
25
|
+
edit: createCareerHeaderEdit(options),
|
|
26
|
+
save: () => null,
|
|
27
|
+
} as unknown as BlockConfiguration<CareerHeaderAttributes>
|
|
28
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
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="3" width="16" height="4" rx="1" stroke="black" fill="none" />
|
|
4
|
+
<line x1="2" y1="10" x2="14" y2="10" stroke="black" />
|
|
5
|
+
<line x1="2" y1="13" x2="18" y2="13" stroke="black" />
|
|
6
|
+
<line x1="2" y1="16" x2="10" y2="16" stroke="black" />
|
|
7
|
+
</svg>
|
|
8
|
+
)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type {CareerHeaderAttributes, CareerHeaderOptions} from './types'
|
|
2
|
+
export {createCareerHeaderBlock} from './factory'
|
|
3
|
+
|
|
4
|
+
import type {CareerHeaderOptions} from './types'
|
|
5
|
+
|
|
6
|
+
export const careerHeaderDefaults: CareerHeaderOptions = {
|
|
7
|
+
name: 'brilo/career-header',
|
|
8
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type {BriloBlockType} from '~/types'
|
|
2
|
+
|
|
3
|
+
export interface CareerHeaderAttributes extends Record<string, unknown> {
|
|
4
|
+
showExcerpt: boolean
|
|
5
|
+
showLocation: boolean
|
|
6
|
+
showSalary: boolean
|
|
7
|
+
showBenefits: boolean
|
|
8
|
+
showEmploymentType: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type CareerHeaderOptions = BriloBlockType
|
|
@@ -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
|
+
}
|