2021-05-15 07:59:11 +00:00
|
|
|
import React, { useState } from 'react';
|
|
|
|
|
import { DraggableBox } from './DraggableBox';
|
|
|
|
|
import Fuse from 'fuse.js';
|
2021-09-01 13:11:17 +00:00
|
|
|
import { isEmpty } from 'lodash';
|
2022-09-14 08:04:49 +00:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2021-05-15 07:59:11 +00:00
|
|
|
|
2023-05-11 07:02:21 +00:00
|
|
|
export const WidgetManager = function WidgetManager({
|
|
|
|
|
componentTypes,
|
|
|
|
|
zoomLevel,
|
|
|
|
|
currentLayout,
|
|
|
|
|
darkMode,
|
|
|
|
|
isVersionReleased,
|
|
|
|
|
}) {
|
2021-06-18 12:23:02 +00:00
|
|
|
const [filteredComponents, setFilteredComponents] = useState(componentTypes);
|
2021-11-15 06:19:27 +00:00
|
|
|
const [searchQuery, setSearchQuery] = useState('');
|
2022-09-14 08:04:49 +00:00
|
|
|
const { t } = useTranslation();
|
2021-11-15 06:19:27 +00:00
|
|
|
|
|
|
|
|
function handleSearchQueryChange(e) {
|
|
|
|
|
const { value } = e.target;
|
|
|
|
|
|
|
|
|
|
setSearchQuery(value);
|
|
|
|
|
filterComponents(value);
|
|
|
|
|
}
|
2021-05-15 07:59:11 +00:00
|
|
|
|
2021-06-18 12:23:02 +00:00
|
|
|
function filterComponents(value) {
|
2021-10-14 08:17:30 +00:00
|
|
|
if (value !== '') {
|
2021-09-13 15:55:57 +00:00
|
|
|
const fuse = new Fuse(componentTypes, { keys: ['component'] });
|
2021-06-18 12:23:02 +00:00
|
|
|
const results = fuse.search(value);
|
|
|
|
|
setFilteredComponents(results.map((result) => result.item));
|
|
|
|
|
} else {
|
|
|
|
|
setFilteredComponents(componentTypes);
|
2021-05-15 07:59:11 +00:00
|
|
|
}
|
2021-06-18 12:23:02 +00:00
|
|
|
}
|
2021-05-15 07:59:11 +00:00
|
|
|
|
2021-06-18 12:23:02 +00:00
|
|
|
function renderComponentCard(component, index) {
|
|
|
|
|
return (
|
|
|
|
|
<DraggableBox
|
|
|
|
|
key={index}
|
|
|
|
|
index={index}
|
|
|
|
|
component={component}
|
|
|
|
|
zoomLevel={zoomLevel}
|
|
|
|
|
currentLayout={currentLayout}
|
2021-05-15 07:59:11 +00:00
|
|
|
/>
|
2021-06-18 12:23:02 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-01 13:11:17 +00:00
|
|
|
function renderList(header, items) {
|
|
|
|
|
if (isEmpty(items)) return null;
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<span className="m-1 widget-header">{header}</span>
|
|
|
|
|
{items.map((component, i) => renderComponentCard(component, i))}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function segregateSections() {
|
|
|
|
|
if (filteredComponents.length === 0) {
|
|
|
|
|
return (
|
2021-09-21 13:48:28 +00:00
|
|
|
<div className="empty">
|
2021-09-01 13:11:17 +00:00
|
|
|
{/* <div class="empty-img">
|
|
|
|
|
<img src="./static/illustrations/undraw_printing_invoices_5r4r.svg" height="128" alt="" />
|
|
|
|
|
</div> */}
|
2022-09-14 08:04:49 +00:00
|
|
|
<p className="empty-title">{t('widgetManager.noResults', 'No results found')}</p>
|
2021-10-11 09:36:04 +00:00
|
|
|
<p className={`empty-subtitle ${darkMode ? 'text-white-50' : 'text-secondary'}`}>
|
2022-09-14 08:04:49 +00:00
|
|
|
{t(
|
|
|
|
|
'widgetManager.tryAdjustingFilterMessage',
|
|
|
|
|
"Try adjusting your search or filter to find what you're looking for."
|
|
|
|
|
)}
|
2021-09-21 13:48:28 +00:00
|
|
|
</p>
|
2021-11-15 06:19:27 +00:00
|
|
|
<button
|
|
|
|
|
className="btn btn-sm btn-outline-azure mt-3"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setFilteredComponents(componentTypes);
|
|
|
|
|
setSearchQuery('');
|
|
|
|
|
}}
|
|
|
|
|
>
|
2022-09-14 08:04:49 +00:00
|
|
|
{t('widgetManager.clearQuery', 'clear query')}
|
2021-11-15 06:19:27 +00:00
|
|
|
</button>
|
2021-09-01 13:11:17 +00:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-09-14 08:04:49 +00:00
|
|
|
const commonSection = { title: t('widgetManager.commonlyUsed', 'commonly used'), items: [] };
|
|
|
|
|
const layoutsSection = { title: t('widgetManager.layouts', 'layouts'), items: [] };
|
|
|
|
|
const formSection = { title: t('widgetManager.forms', 'forms'), items: [] };
|
|
|
|
|
const integrationSection = { title: t('widgetManager.integrations', 'integrations'), items: [] };
|
|
|
|
|
const otherSection = { title: t('widgetManager.others', 'others'), items: [] };
|
2022-03-15 06:46:46 +00:00
|
|
|
const allWidgets = [];
|
2021-09-01 13:11:17 +00:00
|
|
|
|
|
|
|
|
const commonItems = ['Table', 'Chart', 'Button', 'Text', 'Datepicker'];
|
2021-09-13 15:55:57 +00:00
|
|
|
const formItems = [
|
|
|
|
|
'TextInput',
|
|
|
|
|
'NumberInput',
|
2021-12-23 16:49:57 +00:00
|
|
|
'PasswordInput',
|
2021-09-13 15:55:57 +00:00
|
|
|
'Textarea',
|
2021-12-23 16:49:57 +00:00
|
|
|
'ToggleSwitch',
|
2021-09-13 15:55:57 +00:00
|
|
|
'Dropdown',
|
|
|
|
|
'Multiselect',
|
|
|
|
|
'RichTextEditor',
|
|
|
|
|
'Checkbox',
|
|
|
|
|
'Radio-button',
|
|
|
|
|
'Datepicker',
|
2022-01-27 10:52:46 +00:00
|
|
|
'DateRangePicker',
|
|
|
|
|
'FilePicker',
|
|
|
|
|
'StarRating',
|
2021-09-13 15:55:57 +00:00
|
|
|
];
|
2021-09-01 13:11:17 +00:00
|
|
|
const integrationItems = ['Map'];
|
2022-01-27 10:52:46 +00:00
|
|
|
const layoutItems = ['Container', 'Listview', 'Tabs', 'Modal'];
|
2021-09-01 13:11:17 +00:00
|
|
|
|
2021-10-14 02:31:11 +00:00
|
|
|
filteredComponents.forEach((f) => {
|
2022-03-15 06:46:46 +00:00
|
|
|
if (searchQuery) allWidgets.push(f);
|
2021-09-01 13:11:17 +00:00
|
|
|
if (commonItems.includes(f.name)) commonSection.items.push(f);
|
2021-09-05 06:27:22 +00:00
|
|
|
if (formItems.includes(f.name)) formSection.items.push(f);
|
2021-09-01 13:11:17 +00:00
|
|
|
else if (integrationItems.includes(f.name)) integrationSection.items.push(f);
|
2022-01-27 10:52:46 +00:00
|
|
|
else if (layoutItems.includes(f.name)) layoutsSection.items.push(f);
|
2021-09-01 13:11:17 +00:00
|
|
|
else otherSection.items.push(f);
|
|
|
|
|
});
|
|
|
|
|
|
2022-03-15 06:46:46 +00:00
|
|
|
if (allWidgets.length > 0) {
|
|
|
|
|
return <>{renderList(undefined, allWidgets)}</>;
|
|
|
|
|
} else {
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
{renderList(commonSection.title, commonSection.items)}
|
|
|
|
|
{renderList(layoutsSection.title, layoutsSection.items)}
|
|
|
|
|
{renderList(formSection.title, formSection.items)}
|
|
|
|
|
{renderList(otherSection.title, otherSection.items)}
|
|
|
|
|
{renderList(integrationSection.title, integrationSection.items)}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|
2021-09-01 13:11:17 +00:00
|
|
|
}
|
|
|
|
|
|
2021-06-18 12:23:02 +00:00
|
|
|
return (
|
2023-05-11 07:02:21 +00:00
|
|
|
<div className={`components-container mx-3 ${isVersionReleased && 'disabled'}`}>
|
2021-06-18 12:23:02 +00:00
|
|
|
<div className="input-icon">
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
2022-09-12 08:47:04 +00:00
|
|
|
className={`form-control mt-3 mb-2 ${darkMode && 'dark-theme-placeholder'}`}
|
2022-09-14 08:04:49 +00:00
|
|
|
placeholder={t('globals.search', 'Search') + '...'}
|
2021-11-15 06:19:27 +00:00
|
|
|
value={searchQuery}
|
|
|
|
|
onChange={(e) => handleSearchQueryChange(e)}
|
2022-05-16 10:09:10 +00:00
|
|
|
data-cy="widget-search-box"
|
2021-06-18 12:23:02 +00:00
|
|
|
/>
|
|
|
|
|
</div>
|
2021-09-01 13:11:17 +00:00
|
|
|
<div className="widgets-list col-sm-12 col-lg-12 row">{segregateSections()}</div>
|
2021-05-15 07:59:11 +00:00
|
|
|
</div>
|
2021-06-18 12:23:02 +00:00
|
|
|
);
|
|
|
|
|
};
|