@eeacms/volto-clms-theme 1.1.130 → 1.1.132
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/CHANGELOG.md +3 -3
- package/package.json +1 -1
- package/src/components/Blocks/CclHelpdeskDocBlock/CclHelpdeskDocBlockEdit.jsx +29 -0
- package/src/components/Blocks/CclHelpdeskDocBlock/CclHelpdeskDocBlockView.jsx +97 -0
- package/src/components/Blocks/CclHelpdeskDocBlock/HelpdeskForm.jsx +47 -0
- package/src/components/Blocks/CclHelpdeskDocBlock/fields/DatasetField.jsx +59 -0
- package/src/components/Blocks/CclHelpdeskDocBlock/fields/DatasetInfoField.jsx +39 -0
- package/src/components/Blocks/CclHelpdeskDocBlock/fields/StringField.jsx +17 -0
- package/src/components/Blocks/CclHelpdeskDocBlock/schema.js +26 -0
- package/src/components/Blocks/CclHelpdeskDocBlock/utils.js +17 -0
- package/src/components/Blocks/CustomTemplates/VoltoTabsBlock/CclVerticalTabsView.jsx +52 -1
- package/src/components/Blocks/customBlocks.js +20 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,11 +4,11 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
-
### [1.1.
|
|
7
|
+
### [1.1.132](https://github.com/eea/volto-clms-theme/compare/1.1.131...1.1.132) - 4 April 2024
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
### [1.1.131](https://github.com/eea/volto-clms-theme/compare/1.1.130...1.1.131) - 27 March 2024
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### [1.1.130](https://github.com/eea/volto-clms-theme/compare/1.1.129...1.1.130) - 27 March 2024
|
|
12
12
|
|
|
13
13
|
### [1.1.129](https://github.com/eea/volto-clms-theme/compare/1.1.128...1.1.129) - 25 March 2024
|
|
14
14
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import SidebarPortal from '@plone/volto/components/manage/Sidebar/SidebarPortal';
|
|
3
|
+
import { InlineForm } from '@plone/volto/components';
|
|
4
|
+
import schema from './schema';
|
|
5
|
+
import CclHelpdeskDocView from './CclHelpdeskDocBlockView';
|
|
6
|
+
|
|
7
|
+
const CclHelpdeskDocEdit = (props) => {
|
|
8
|
+
const { block, data, onChangeBlock, selected } = props;
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<CclHelpdeskDocView data={data} />
|
|
12
|
+
<SidebarPortal selected={selected}>
|
|
13
|
+
<InlineForm
|
|
14
|
+
schema={schema}
|
|
15
|
+
title={schema.title}
|
|
16
|
+
onChangeField={(id, value) => {
|
|
17
|
+
onChangeBlock(block, {
|
|
18
|
+
...data,
|
|
19
|
+
[id]: value,
|
|
20
|
+
});
|
|
21
|
+
}}
|
|
22
|
+
formData={data}
|
|
23
|
+
/>
|
|
24
|
+
</SidebarPortal>
|
|
25
|
+
</>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default CclHelpdeskDocEdit;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Segment, Icon } from 'semantic-ui-react';
|
|
3
|
+
import { HelpdeskForm } from './HelpdeskForm';
|
|
4
|
+
import { toast } from 'react-toastify';
|
|
5
|
+
import { Toast } from '@plone/volto/components';
|
|
6
|
+
const CclHelpdeskDocView = (props) => {
|
|
7
|
+
const { data } = props;
|
|
8
|
+
const [file, setFile] = React.useState('');
|
|
9
|
+
const [endpoint, setEndpoint] = React.useState('');
|
|
10
|
+
const [result, setResult] = React.useState('');
|
|
11
|
+
const [fields, setFields] = React.useState({});
|
|
12
|
+
|
|
13
|
+
const reEndpoint = /\/api\/(@.*)\?/;
|
|
14
|
+
const reParams = /(?=&?)(\w*=[a-zA-Z0-9-]*)/gm;
|
|
15
|
+
React.useEffect(() => {
|
|
16
|
+
data.url &&
|
|
17
|
+
fetch(data.url)
|
|
18
|
+
.then((response) => response.text())
|
|
19
|
+
.then((data) => setFile(data));
|
|
20
|
+
return () => {};
|
|
21
|
+
}, [data.url]);
|
|
22
|
+
|
|
23
|
+
React.useEffect(() => {
|
|
24
|
+
if (file) {
|
|
25
|
+
const endpoint = file.match(reEndpoint);
|
|
26
|
+
if (endpoint[1]) {
|
|
27
|
+
setEndpoint(endpoint[1]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const params = file.match(reParams);
|
|
31
|
+
if (params) {
|
|
32
|
+
const fields = params.map((p) => {
|
|
33
|
+
const s = p.split('=');
|
|
34
|
+
return {
|
|
35
|
+
key: s[0],
|
|
36
|
+
value: s[1],
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
setFields(fields);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
43
|
+
}, [file]);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div>
|
|
47
|
+
{data.title && <h2>{data.title}</h2>}
|
|
48
|
+
<h2>Endpoint:</h2>
|
|
49
|
+
<h3>{endpoint}</h3>
|
|
50
|
+
<Segment color="teal" padded>
|
|
51
|
+
{file.split('\n').map((line, key) => (
|
|
52
|
+
<React.Fragment key={key}>
|
|
53
|
+
{line}
|
|
54
|
+
<br />
|
|
55
|
+
</React.Fragment>
|
|
56
|
+
))}
|
|
57
|
+
</Segment>
|
|
58
|
+
|
|
59
|
+
<Segment color="teal" padded>
|
|
60
|
+
<HelpdeskForm
|
|
61
|
+
fields={fields}
|
|
62
|
+
endpoint={endpoint}
|
|
63
|
+
setResult={setResult}
|
|
64
|
+
></HelpdeskForm>
|
|
65
|
+
</Segment>
|
|
66
|
+
{result && (
|
|
67
|
+
<>
|
|
68
|
+
<Segment color="teal" padded>
|
|
69
|
+
<h2>Endpoint result:</h2>
|
|
70
|
+
<Icon
|
|
71
|
+
color={'olive'}
|
|
72
|
+
name="copy"
|
|
73
|
+
size="large"
|
|
74
|
+
style={{ cursor: 'pointer' }}
|
|
75
|
+
onClick={() => {
|
|
76
|
+
navigator.clipboard.writeText(result);
|
|
77
|
+
toast.success(
|
|
78
|
+
<Toast
|
|
79
|
+
success
|
|
80
|
+
autoClose={5000}
|
|
81
|
+
title={'URL copied to clipboard'}
|
|
82
|
+
content={`The result URL has been successfully copied to clipboard`}
|
|
83
|
+
/>,
|
|
84
|
+
);
|
|
85
|
+
}}
|
|
86
|
+
></Icon>
|
|
87
|
+
<br />
|
|
88
|
+
<br />
|
|
89
|
+
{JSON.stringify(result)}
|
|
90
|
+
</Segment>
|
|
91
|
+
</>
|
|
92
|
+
)}
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export default CclHelpdeskDocView;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Form } from 'semantic-ui-react';
|
|
3
|
+
|
|
4
|
+
import CclButton from '@eeacms/volto-clms-theme/components/CclButton/CclButton';
|
|
5
|
+
|
|
6
|
+
import { getWidget } from './utils';
|
|
7
|
+
|
|
8
|
+
export const HelpdeskForm = ({ fields, endpoint, setResult }) => {
|
|
9
|
+
const [datasetInfo, setDatasetInfo] = React.useState(null);
|
|
10
|
+
const [formData, setFormData] = React.useState({});
|
|
11
|
+
return fields.length > 0 ? (
|
|
12
|
+
<>
|
|
13
|
+
<h2>Form to test the endpoint:</h2>
|
|
14
|
+
<Form>
|
|
15
|
+
{fields.map((f, key) => {
|
|
16
|
+
const Field = getWidget(f.key);
|
|
17
|
+
return (
|
|
18
|
+
<Field
|
|
19
|
+
key={key}
|
|
20
|
+
label={f.key}
|
|
21
|
+
placeholder={f.value}
|
|
22
|
+
dependant={datasetInfo}
|
|
23
|
+
setDependant={setDatasetInfo}
|
|
24
|
+
formData={formData}
|
|
25
|
+
setFormData={setFormData}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
})}
|
|
29
|
+
<CclButton
|
|
30
|
+
onClick={() => {
|
|
31
|
+
fetch(
|
|
32
|
+
`/++api++/${endpoint}?${Object.keys(formData)
|
|
33
|
+
.map((k) => `${k}=${formData[k]}`)
|
|
34
|
+
.join('&')}`,
|
|
35
|
+
)
|
|
36
|
+
.then((response) => response.json())
|
|
37
|
+
.then((data) => setResult(data));
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
Send request
|
|
41
|
+
</CclButton>
|
|
42
|
+
</Form>
|
|
43
|
+
</>
|
|
44
|
+
) : (
|
|
45
|
+
<></>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
3
|
+
import Select from 'react-select';
|
|
4
|
+
import { Segment } from 'semantic-ui-react';
|
|
5
|
+
|
|
6
|
+
import { searchContent } from '@plone/volto/actions';
|
|
7
|
+
import { FormFieldWrapper } from '@plone/volto/components';
|
|
8
|
+
|
|
9
|
+
export const DatasetField = ({
|
|
10
|
+
label,
|
|
11
|
+
setDependant,
|
|
12
|
+
formData,
|
|
13
|
+
setFormData,
|
|
14
|
+
}) => {
|
|
15
|
+
const id = 'helpdesk-block';
|
|
16
|
+
const separator = '===';
|
|
17
|
+
const search = useSelector((state) => state.search.subrequests[id]);
|
|
18
|
+
const dispatch = useDispatch();
|
|
19
|
+
React.useEffect(() => {
|
|
20
|
+
dispatch(
|
|
21
|
+
searchContent(
|
|
22
|
+
'/',
|
|
23
|
+
{
|
|
24
|
+
portal_type: 'DataSet',
|
|
25
|
+
metadata_fields: ['dataset_download_information', 'UID'],
|
|
26
|
+
b_size: 9999,
|
|
27
|
+
},
|
|
28
|
+
id,
|
|
29
|
+
),
|
|
30
|
+
);
|
|
31
|
+
return () => {};
|
|
32
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
|
+
}, []);
|
|
34
|
+
return (
|
|
35
|
+
<FormFieldWrapper title={`${label}:`} id={label} className="text">
|
|
36
|
+
<Segment basic loading={search?.loading}>
|
|
37
|
+
<Select
|
|
38
|
+
type="text"
|
|
39
|
+
onChange={(e) => {
|
|
40
|
+
setDependant(e.value);
|
|
41
|
+
setFormData({ ...formData, [label]: e.value.split(separator)[0] });
|
|
42
|
+
}}
|
|
43
|
+
options={
|
|
44
|
+
search?.items
|
|
45
|
+
? search?.items.map((i) => {
|
|
46
|
+
return {
|
|
47
|
+
value: `${i.UID}${separator}${JSON.stringify(
|
|
48
|
+
i.dataset_download_information?.items,
|
|
49
|
+
)}`,
|
|
50
|
+
label: i.title,
|
|
51
|
+
};
|
|
52
|
+
})
|
|
53
|
+
: []
|
|
54
|
+
}
|
|
55
|
+
/>
|
|
56
|
+
</Segment>
|
|
57
|
+
</FormFieldWrapper>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useSelector } from 'react-redux';
|
|
2
|
+
import Select from 'react-select';
|
|
3
|
+
import { Segment } from 'semantic-ui-react';
|
|
4
|
+
|
|
5
|
+
import { FormFieldWrapper } from '@plone/volto/components';
|
|
6
|
+
|
|
7
|
+
export const DatasetInfoField = ({
|
|
8
|
+
label,
|
|
9
|
+
formData,
|
|
10
|
+
dependant,
|
|
11
|
+
setFormData,
|
|
12
|
+
}) => {
|
|
13
|
+
const id = 'helpdesk-block';
|
|
14
|
+
const search = useSelector((state) => state.search.subrequests[id]);
|
|
15
|
+
const valueItems = dependant ? JSON.parse(dependant.split('===')[1]) : [];
|
|
16
|
+
const options = valueItems.map((v) => {
|
|
17
|
+
return {
|
|
18
|
+
value: v['@id'],
|
|
19
|
+
label: `${v.name ?? ''} ${v.collection ?? ''} ${v.full_source ?? ''} ${
|
|
20
|
+
typeof v.full_format === 'object'
|
|
21
|
+
? v.full_format.title ?? ''
|
|
22
|
+
: v.full_format ?? ''
|
|
23
|
+
}`,
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
return (
|
|
27
|
+
<FormFieldWrapper title={`${label}:`} id={label} className="text">
|
|
28
|
+
<Segment basic loading={search?.loading}>
|
|
29
|
+
<Select
|
|
30
|
+
type="text"
|
|
31
|
+
options={options}
|
|
32
|
+
onChange={(e) => {
|
|
33
|
+
setFormData({ ...formData, [label]: e.value });
|
|
34
|
+
}}
|
|
35
|
+
/>
|
|
36
|
+
</Segment>
|
|
37
|
+
</FormFieldWrapper>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Input } from 'semantic-ui-react';
|
|
2
|
+
|
|
3
|
+
import { FormFieldWrapper } from '@plone/volto/components';
|
|
4
|
+
|
|
5
|
+
export const StringField = ({ label, placeholder, formData, setFormData }) => {
|
|
6
|
+
return (
|
|
7
|
+
<FormFieldWrapper title={`${label}:`} id={label} className="text">
|
|
8
|
+
<Input
|
|
9
|
+
type="text"
|
|
10
|
+
placeholder={placeholder}
|
|
11
|
+
onChange={(e) => {
|
|
12
|
+
setFormData({ ...formData, [label]: e.target.value });
|
|
13
|
+
}}
|
|
14
|
+
/>
|
|
15
|
+
</FormFieldWrapper>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const schema = {
|
|
2
|
+
title: 'Documentation block',
|
|
3
|
+
fieldsets: [
|
|
4
|
+
{
|
|
5
|
+
id: 'default',
|
|
6
|
+
title: 'Default',
|
|
7
|
+
fields: ['title', 'url'],
|
|
8
|
+
},
|
|
9
|
+
],
|
|
10
|
+
properties: {
|
|
11
|
+
title: {
|
|
12
|
+
title: 'Title',
|
|
13
|
+
description: 'Documentation block title',
|
|
14
|
+
type: 'string',
|
|
15
|
+
},
|
|
16
|
+
url: {
|
|
17
|
+
title: 'URL',
|
|
18
|
+
description: 'GitHub documentation .req file raw url',
|
|
19
|
+
mode: 'link',
|
|
20
|
+
allowExternals: true,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
required: ['title', 'url'],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default schema;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { StringField } from './fields/StringField';
|
|
2
|
+
import { DatasetField } from './fields/DatasetField';
|
|
3
|
+
import { DatasetInfoField } from './fields/DatasetInfoField';
|
|
4
|
+
const widgets = {
|
|
5
|
+
default: StringField,
|
|
6
|
+
dataset_uid: DatasetField,
|
|
7
|
+
uid: DatasetField,
|
|
8
|
+
download_information_id: DatasetInfoField,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const getWidget = (id) => {
|
|
12
|
+
if (widgets[id]) {
|
|
13
|
+
return widgets[id];
|
|
14
|
+
} else {
|
|
15
|
+
return widgets['default'];
|
|
16
|
+
}
|
|
17
|
+
};
|
|
@@ -18,6 +18,14 @@ const handleClick = (e, tab, activeTab, setActiveTab, location, tabHash) => {
|
|
|
18
18
|
location.hash = `#${tabHash}`;
|
|
19
19
|
setActiveTab(tab);
|
|
20
20
|
}
|
|
21
|
+
if (tab === 'd7706c16-7c4a-4c0e-9471-90765a302c1c') {
|
|
22
|
+
document.querySelector('#loader').style.display = 'block';
|
|
23
|
+
} else {
|
|
24
|
+
closeSpinner();
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const closeSpinner = () => {
|
|
28
|
+
document.querySelector('#loader').style.display = 'none';
|
|
21
29
|
};
|
|
22
30
|
|
|
23
31
|
function isSpan(subTab, nextSubTab) {
|
|
@@ -34,6 +42,9 @@ const TabsComponent = (props) => {
|
|
|
34
42
|
tabs = {},
|
|
35
43
|
setActiveTab,
|
|
36
44
|
} = props;
|
|
45
|
+
if (activeTab === 'd7706c16-7c4a-4c0e-9471-90765a302c1c') {
|
|
46
|
+
document.querySelector('#loader').style.display = 'block';
|
|
47
|
+
}
|
|
37
48
|
const location = useLocation();
|
|
38
49
|
return (
|
|
39
50
|
<div className="left-content cont-w-25">
|
|
@@ -105,10 +116,50 @@ const PanelsComponent = (props) => {
|
|
|
105
116
|
const tabHash = `tab=${slugify(title)}`;
|
|
106
117
|
return (
|
|
107
118
|
<Route key={index} to={'#' + tabHash}>
|
|
119
|
+
<div
|
|
120
|
+
id="loader"
|
|
121
|
+
className="loading"
|
|
122
|
+
role="alert"
|
|
123
|
+
aria-busy="true"
|
|
124
|
+
aria-live="polite"
|
|
125
|
+
>
|
|
126
|
+
<div>
|
|
127
|
+
<svg
|
|
128
|
+
width="80"
|
|
129
|
+
height="80"
|
|
130
|
+
viewBox="0 0 24 24"
|
|
131
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
132
|
+
>
|
|
133
|
+
<style>
|
|
134
|
+
{`.spinner_ajPY {
|
|
135
|
+
transform-origin: center;
|
|
136
|
+
animation: spinner_AtaB .75s infinite linear;
|
|
137
|
+
fill: #a0b128; stroke-width: 3px; filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.1));
|
|
138
|
+
}
|
|
139
|
+
@keyframes spinner_AtaB {
|
|
140
|
+
100% {
|
|
141
|
+
transform: rotate(360deg);
|
|
142
|
+
}
|
|
143
|
+
}`}
|
|
144
|
+
</style>
|
|
145
|
+
<path
|
|
146
|
+
d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
|
|
147
|
+
opacity=".25"
|
|
148
|
+
/>
|
|
149
|
+
<path
|
|
150
|
+
d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
|
|
151
|
+
className="spinner_ajPY"
|
|
152
|
+
/>
|
|
153
|
+
</svg>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
108
156
|
<div
|
|
109
157
|
className={cx('panel', tab === activeTab && 'panel-selected')}
|
|
110
|
-
role="
|
|
158
|
+
role="button"
|
|
111
159
|
aria-hidden="false"
|
|
160
|
+
onLoad={() => {
|
|
161
|
+
closeSpinner();
|
|
162
|
+
}}
|
|
112
163
|
>
|
|
113
164
|
<RenderBlocks
|
|
114
165
|
{...props}
|
|
@@ -63,6 +63,8 @@ import SubscriptionBlockView from '@eeacms/volto-clms-theme/components/Blocks/Cc
|
|
|
63
63
|
import SubscriptionBlockEdit from '@eeacms/volto-clms-theme/components/Blocks/CclSubscriptionBlock/SubscriptionEdit';
|
|
64
64
|
import CclFAQBlockEdit from '@eeacms/volto-clms-theme/components/Blocks/CclFAQBlock/CclFAQBlockEdit';
|
|
65
65
|
import CclFAQBlockView from '@eeacms/volto-clms-theme/components/Blocks/CclFAQBlock/CclFAQBlockView';
|
|
66
|
+
import CclHelpdeskDocBlockEdit from '@eeacms/volto-clms-theme/components/Blocks/CclHelpdeskDocBlock/CclHelpdeskDocBlockEdit';
|
|
67
|
+
import CclHelpdeskDocBlockView from '@eeacms/volto-clms-theme/components/Blocks/CclHelpdeskDocBlock/CclHelpdeskDocBlockView';
|
|
66
68
|
import containerSVG from '@plone/volto/icons/apps.svg';
|
|
67
69
|
import {
|
|
68
70
|
customIdFieldSchema,
|
|
@@ -76,6 +78,8 @@ import linkSVG from '@plone/volto/icons/link.svg';
|
|
|
76
78
|
import navSVG from '@plone/volto/icons/nav.svg';
|
|
77
79
|
import codeSVG from '@plone/volto/icons/code.svg';
|
|
78
80
|
import upSVG from '@plone/volto/icons/up-key.svg';
|
|
81
|
+
import infoSVG from '@plone/volto/icons/info.svg';
|
|
82
|
+
|
|
79
83
|
import ImageWidget from '@eeacms/volto-clms-theme/components/Widgets/ImageWidget';
|
|
80
84
|
import AttachmentWithSizeLimit from '@eeacms/volto-clms-theme/components/Widgets/AttachmentWithSizeLimit';
|
|
81
85
|
import TextareaWithRequestData from '@eeacms/volto-clms-theme/components/Widgets/TextareaWithRequestData';
|
|
@@ -644,6 +648,22 @@ const customBlocks = (config) => ({
|
|
|
644
648
|
view: [], // Future proof (not implemented yet) view user role(s)
|
|
645
649
|
},
|
|
646
650
|
},
|
|
651
|
+
cclHelpdeskDoc: {
|
|
652
|
+
id: 'cclHelpdeskDoc', // The name (id) of the block
|
|
653
|
+
title: 'Helpdesk Documentation block', // The display name of the block
|
|
654
|
+
icon: infoSVG, // The icon used in the block chooser
|
|
655
|
+
group: 'ccl_blocks', // The group (blocks can be grouped, displayed in the chooser)
|
|
656
|
+
view: CclHelpdeskDocBlockView, // The view mode component
|
|
657
|
+
edit: CclHelpdeskDocBlockEdit, // The edit mode component
|
|
658
|
+
restricted: false, // If the block is restricted, it won't show in the chooser
|
|
659
|
+
mostUsed: false, // A meta group `most used`, appearing at the top of the chooser
|
|
660
|
+
blockHasOwnFocusManagement: false, // Set this to true if the block manages its own focus
|
|
661
|
+
sidebarTab: 1, // The sidebar tab you want to be selected when selecting the block
|
|
662
|
+
security: {
|
|
663
|
+
addPermission: [], // Future proof (not implemented yet) add user permission role(s)
|
|
664
|
+
view: [], // Future proof (not implemented yet) view user role(s)
|
|
665
|
+
},
|
|
666
|
+
},
|
|
647
667
|
teaser: {
|
|
648
668
|
...config.blocks.blocksConfig.teaser,
|
|
649
669
|
blockSchema: (intl) => {
|