UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

161 lines (156 loc) • 8.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const material_1 = require("@mui/material"); const api_services_1 = require("@selfcommunity/api-services"); const react_core_1 = require("@selfcommunity/react-core"); const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton")); const Category_1 = tslib_1.__importDefault(require("../Category")); const react_intl_1 = require("react-intl"); const classnames_1 = tslib_1.__importDefault(require("classnames")); const system_1 = require("@mui/system"); const Errors_1 = require("../../constants/Errors"); const utils_1 = require("@selfcommunity/utils"); const HiddenPlaceholder_1 = tslib_1.__importDefault(require("../../shared/HiddenPlaceholder")); const constants_1 = require("./constants"); const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js")); const PubSub_1 = require("../../constants/PubSub"); const classes = { root: `${constants_1.PREFIX}-root`, filters: `${constants_1.PREFIX}-filter`, categories: `${constants_1.PREFIX}-categories`, category: `${constants_1.PREFIX}-category`, noResults: `${constants_1.PREFIX}-no-results` }; const Root = (0, material_1.styled)(material_1.Box, { name: constants_1.PREFIX, slot: 'Root' })(() => ({})); /** * > API documentation for the Community-JS Categories component. Learn about the available props and the CSS API. * * * The Categories component renders the list of all available categories. * Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/AccountRecover) #### Import ```jsx import {Categories} from '@selfcommunity/react-ui'; ``` #### Component Name The name `SCCategories` can be used when providing style overrides in the theme. #### CSS |Rule Name|Global class|Description| |---|---|---| |root|.SCCategories-root|Styles applied to the root element.| |filters|.SCCategories-filter|Styles applied to the filter.| |categories|.SCCategories-categories|Styles applied to the list of categories.| |category|.SCCategories-category|Styles applied to the of category element.| |noResults|.SCCategories-no-results|Styles applied to no results section.| * @param inProps */ function Categories(inProps) { // PROPS const props = (0, system_1.useThemeProps)({ props: inProps, name: constants_1.PREFIX }); const { className, CategoryComponent = Category_1.default, CategoryComponentProps = { variant: 'outlined', ButtonBaseProps: { disableRipple: true, component: material_1.Box } }, CategoriesSkeletonComponent = Skeleton_1.default, CategoriesSkeletonProps = {}, showFilters = false, filters, handleFilterCategories, prefetchedCategories = [] } = props, rest = tslib_1.__rest(props, ["className", "CategoryComponent", "CategoryComponentProps", "CategoriesSkeletonComponent", "CategoriesSkeletonProps", "showFilters", "filters", "handleFilterCategories", "prefetchedCategories"]); // STATE const [categories, setCategories] = (0, react_1.useState)([]); const [loading, setLoading] = (0, react_1.useState)(true); const [filterName, setFilterName] = (0, react_1.useState)(''); // CONTEXT const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext); const scPreferencesContext = (0, react_1.useContext)(react_core_1.SCPreferencesContext); const contentAvailability = react_core_1.SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY in scPreferencesContext.preferences && scPreferencesContext.preferences[react_core_1.SCPreferences.CONFIGURATIONS_CONTENT_AVAILABILITY].value; // CONST const authUserId = scUserContext.user ? scUserContext.user.id : null; // REFS const isMountedRef = (0, react_core_1.useIsComponentMountedRef)(); const updatesSubscription = (0, react_1.useRef)(null); /** * Fetches categories list */ const fetchCategories = (next = api_services_1.Endpoints.CategoryList.url({})) => tslib_1.__awaiter(this, void 0, void 0, function* () { const data = yield api_services_1.CategoryService.getAllCategories({ active: true }, { url: next }); return data.next ? data.results.concat(yield fetchCategories(data.next)) : data.results; }); /** * On mount, fetches categories list */ (0, react_1.useEffect)(() => { if (!contentAvailability && !authUserId) { return; } else if (prefetchedCategories.length) { setCategories(prefetchedCategories); setLoading(false); } else { fetchCategories() .then((data) => { if (isMountedRef.current) { setCategories(data); setLoading(false); } }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); }); } }, [contentAvailability, authUserId, prefetchedCategories.length]); /** * Subscriber for pubsub callback */ const onEditCategoryHandler = (0, react_1.useCallback)((_msg, edited) => { setCategories((prev) => { return prev.map((c) => (c.id === edited.id ? Object.assign(Object.assign({}, c), edited) : c)); }); }, [categories]); /** * On mount, subscribe to receive event updates (only edit) */ (0, react_1.useEffect)(() => { if (categories) { updatesSubscription.current = pubsub_js_1.default.subscribe(`${PubSub_1.SCTopicType.CATEGORY}.${PubSub_1.SCCategoryEventType.EDIT}`, onEditCategoryHandler); } return () => { updatesSubscription.current && pubsub_js_1.default.unsubscribe(updatesSubscription.current); }; }, [categories]); /** * Get categories filtered */ const getFilteredCategories = () => { if (handleFilterCategories) { return handleFilterCategories(categories); } if (filterName) { return categories.filter((c) => c.name.toLowerCase().includes(filterName.toLowerCase())); } return categories; }; /** * Handle change filter name * @param event */ const handleOnChangeFilterName = (event) => { setFilterName(event.target.value); }; /** * Renders categories list */ const filteredCategories = (0, utils_1.sortByAttr)(getFilteredCategories(), 'order'); const c = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showFilters && ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ container: true, direction: "row", justifyContent: "center", alignItems: "center", className: classes.filters }, { children: filters ? (filters) : ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ item: true, xs: 12, md: 6 }, { children: (0, jsx_runtime_1.jsx)(material_1.TextField, { fullWidth: true, value: filterName, label: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.categories.filterByName", defaultMessage: "ui.categories.filterByName" }), variant: "outlined", onChange: handleOnChangeFilterName, disabled: loading }) }))) }))), loading ? ((0, jsx_runtime_1.jsx)(CategoriesSkeletonComponent, Object.assign({}, CategoriesSkeletonProps))) : ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ container: true, spacing: { xs: 3 }, className: classes.categories }, { children: !filteredCategories.length ? ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ item: true }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.noResults, variant: "body2" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.categories.noResults", defaultMessage: "ui.categories.noResults" }) })) }))) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: filteredCategories.map((category) => ((0, jsx_runtime_1.jsx)(material_1.Grid, Object.assign({ item: true, xs: 12, sm: 6, md: 6, lg: 4 }, { children: (0, jsx_runtime_1.jsx)(CategoryComponent, Object.assign({ category: category }, CategoryComponentProps, { showTooltip: true, className: classes.category })) }), category.id))) })) })))] })); /** * Renders root object (if content availability community option is false and user is anonymous, component is hidden) */ if (!contentAvailability && !scUserContext.user) { return (0, jsx_runtime_1.jsx)(HiddenPlaceholder_1.default, {}); } return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: c }))); } exports.default = Categories;