at the end of the day, it was inevitable
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { translate } from 'react-i18next';
|
||||
import {
|
||||
Button,
|
||||
Modal,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
Label,
|
||||
Input,
|
||||
ModalFooter
|
||||
} from 'reactstrap';
|
||||
|
||||
export class AddCategoryPopup extends React.Component {
|
||||
state = {
|
||||
folderName: ''
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
parentId: PropTypes.number.isRequired,
|
||||
hideAddCategoryPopup: PropTypes.func.isRequired,
|
||||
addCategory: PropTypes.func.isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
onChangeName = (e) => {
|
||||
const { value } = e.target; // need validation
|
||||
this.setState({ folderName: value });
|
||||
};
|
||||
|
||||
hidePopup = () => {
|
||||
this.props.hideAddCategoryPopup();
|
||||
};
|
||||
|
||||
onSubmit = () => {
|
||||
const { folderName } = this.state;
|
||||
this.props.addCategory(folderName, this.props.parentId);
|
||||
this.props.hideAddCategoryPopup();
|
||||
};
|
||||
|
||||
render() {
|
||||
const { t } = this.props;
|
||||
const { folderName } = this.state;
|
||||
|
||||
return (
|
||||
<Modal isOpen toggle={this.hidePopup} backdrop="static">
|
||||
<ModalHeader toggle={this.hidePopup}>
|
||||
{t('sidebarPopup.addFolderBtn')}
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<Label>{t('sidebarPopup.enterFolderName')}</Label>
|
||||
<Input type="text" value={folderName} onChange={this.onChangeName} />
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="light" onClick={this.hidePopup}>
|
||||
{t('commonWords.Cancel')}
|
||||
</Button>
|
||||
<Button color="primary" onClick={this.onSubmit}>
|
||||
{t('sidebarPopup.addFolderBtn')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(['common'], { wait: true })(AddCategoryPopup);
|
||||
@@ -0,0 +1,121 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { translate } from 'react-i18next';
|
||||
import Select from 'react-select';
|
||||
import {
|
||||
Button,
|
||||
Modal,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
FormGroup,
|
||||
Label,
|
||||
Input,
|
||||
ModalFooter
|
||||
} from 'reactstrap';
|
||||
|
||||
export class AddClippingsFeedPopup extends React.Component {
|
||||
static propTypes = {
|
||||
parentId: PropTypes.number.isRequired,
|
||||
hidePopup: PropTypes.func.isRequired,
|
||||
addClippingsFeed: PropTypes.func.isRequired,
|
||||
addAlert: PropTypes.func.isRequired,
|
||||
categories: PropTypes.array.isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
parentId: props.parentId,
|
||||
feedName: ''
|
||||
};
|
||||
}
|
||||
|
||||
onChangeName = (e) => {
|
||||
const { value } = e.target;
|
||||
this.setState({ feedName: value });
|
||||
};
|
||||
|
||||
hidePopup = () => {
|
||||
this.props.hidePopup();
|
||||
};
|
||||
|
||||
onSubmit = () => {
|
||||
const { parentId } = this.state;
|
||||
const { addAlert, addClippingsFeed, hidePopup } = this.props;
|
||||
const { feedName } = this.state;
|
||||
if (feedName) {
|
||||
addClippingsFeed(feedName, parentId);
|
||||
hidePopup();
|
||||
} else {
|
||||
addAlert({
|
||||
type: 'error',
|
||||
transKey: 'feedNameEmpty'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
flattenCategories = (categories, level = '') => {
|
||||
return categories.reduce((result, category) => {
|
||||
result.push({
|
||||
label:
|
||||
level +
|
||||
this.props.t(`sidebar.${category.name}`, {
|
||||
defaultValue: category.name
|
||||
}),
|
||||
value: category.id
|
||||
});
|
||||
if (category.childes && category.childes.length) {
|
||||
return result.concat(
|
||||
this.flattenCategories(category.childes, '- ' + level)
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}, []);
|
||||
};
|
||||
|
||||
onParentCategorySelect = (value) => {
|
||||
this.setState({ parentId: value });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { t, categories } = this.props;
|
||||
const { parentId, feedName } = this.state;
|
||||
const options = this.flattenCategories(categories);
|
||||
|
||||
return (
|
||||
<Modal isOpen toggle={this.hidePopup} backdrop="static">
|
||||
<ModalHeader toggle={this.hidePopup}>
|
||||
{t('sidebarPopup.addClippingsFeed')}
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<FormGroup>
|
||||
<Label>{t('sidebarPopup.feedName')}</Label>
|
||||
<Input type="text" value={feedName} onChange={this.onChangeName} />
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Label>{t('sidebarPopup.folder')}</Label>
|
||||
<Select
|
||||
onChange={this.onParentCategorySelect}
|
||||
options={options}
|
||||
value={parentId}
|
||||
editable={false}
|
||||
clearable={false}
|
||||
simpleValue
|
||||
/>
|
||||
</FormGroup>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="light" onClick={this.hidePopup}>
|
||||
{t('commonWords.Cancel')}
|
||||
</Button>
|
||||
<Button color="primary" onClick={this.onSubmit}>
|
||||
{t('sidebarPopup.addClippingsFeed')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(['common'], { wait: true })(AddClippingsFeedPopup);
|
||||
@@ -0,0 +1,58 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import Category from './Category'
|
||||
|
||||
export class Categories extends React.Component {
|
||||
static propTypes = {
|
||||
actions: PropTypes.object.isRequired,
|
||||
areCategoriesLoaded: PropTypes.bool.isRequired,
|
||||
areFeedsFiltered: PropTypes.bool.isRequired,
|
||||
categories: PropTypes.array.isRequired,
|
||||
filteredCategories: PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
hideParentCategoryDrop = () => {}; //empty func for first level categories
|
||||
|
||||
render () {
|
||||
const { areCategoriesLoaded, areFeedsFiltered, actions } = this.props
|
||||
const {
|
||||
showDeletePopup, showRenamePopup, showAddCategoryPopup,
|
||||
showAddClippingsFeedPopup, getFeedResults,
|
||||
moveCategory, moveFeed, toggleExportFeed,
|
||||
toggleExportCategory, clipArticles
|
||||
} = actions
|
||||
|
||||
const categories = areFeedsFiltered ? this.props.filteredCategories : this.props.categories
|
||||
|
||||
return (
|
||||
<div className='sidebar-categories'>
|
||||
|
||||
{areCategoriesLoaded &&
|
||||
categories.map((category, i) => {
|
||||
return (
|
||||
<Category
|
||||
hideParentCategoryDrop={this.hideParentCategoryDrop} //set empty func
|
||||
parentId={-1} //set empty parent category for first level categories
|
||||
category={category}
|
||||
categories={categories}
|
||||
showDeletePopup={showDeletePopup}
|
||||
showRenamePopup={showRenamePopup}
|
||||
showAddCategoryPopup={showAddCategoryPopup}
|
||||
showAddClippingsFeedPopup={showAddClippingsFeedPopup}
|
||||
getFeedResults={getFeedResults}
|
||||
moveCategory={moveCategory}
|
||||
moveFeed={moveFeed}
|
||||
clipArticles={clipArticles}
|
||||
key={'main-category' + i}
|
||||
toggleExportFeed={toggleExportFeed}
|
||||
toggleExportCategory={toggleExportCategory}
|
||||
/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Categories
|
||||
@@ -0,0 +1,219 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { DropTarget, DragSource } from 'react-dnd';
|
||||
import { compose } from 'redux';
|
||||
import onClickOutside from 'react-onclickoutside';
|
||||
import Feed from './Feed';
|
||||
import CategoryHead from './CategoryHead';
|
||||
import { TYPES } from '../../../redux/modules/appState/sidebar';
|
||||
import cx from 'classnames';
|
||||
|
||||
const folderSource = {
|
||||
beginDrag(props) {
|
||||
return {
|
||||
type: TYPES.FOLDER,
|
||||
id: props.category.id,
|
||||
category: props.category
|
||||
};
|
||||
},
|
||||
|
||||
canDrag(props) {
|
||||
return props.category.type === 'directory';
|
||||
}
|
||||
};
|
||||
|
||||
const targetTypes = [TYPES.FEED, TYPES.FOLDER];
|
||||
const categoryTarget = {
|
||||
drop(props, monitor) {
|
||||
if (monitor.didDrop()) return;
|
||||
const { category, moveCategory, moveFeed } = props;
|
||||
|
||||
const item = monitor.getItem();
|
||||
const draggedCategoryId = item.id;
|
||||
const newCategoryId = category.id;
|
||||
|
||||
if (item.type === TYPES.FOLDER) {
|
||||
moveCategory(item.category, newCategoryId);
|
||||
} else if (item.type === TYPES.FEED) {
|
||||
moveFeed(draggedCategoryId, newCategoryId);
|
||||
}
|
||||
},
|
||||
|
||||
canDrop(props, monitor) {
|
||||
const categoryType = props.category.type;
|
||||
return (
|
||||
categoryType !== 'deleted_content' && categoryType !== 'shared_content'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export class CategoryClass extends React.Component {
|
||||
static propTypes = {
|
||||
parentId: PropTypes.number.isRequired,
|
||||
category: PropTypes.object.isRequired,
|
||||
showDeletePopup: PropTypes.func.isRequired,
|
||||
showRenamePopup: PropTypes.func.isRequired,
|
||||
showAddCategoryPopup: PropTypes.func.isRequired,
|
||||
showAddClippingsFeedPopup: PropTypes.func.isRequired,
|
||||
hideParentCategoryDrop: PropTypes.func.isRequired,
|
||||
categories: PropTypes.array.isRequired,
|
||||
connectDropTarget: PropTypes.func.isRequired,
|
||||
connectDragSource: PropTypes.func.isRequired,
|
||||
getFeedResults: PropTypes.func.isRequired,
|
||||
moveFeed: PropTypes.func.isRequired,
|
||||
moveCategory: PropTypes.func.isRequired,
|
||||
clipArticles: PropTypes.func.isRequired,
|
||||
toggleExportFeed: PropTypes.func.isRequired,
|
||||
toggleExportCategory: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isCategoryActive: true, // sub menus
|
||||
isCategoryDropActive: false // more options
|
||||
};
|
||||
}
|
||||
|
||||
// hide category dropdown if there was click outside
|
||||
handleClickOutside = () => {
|
||||
this.state.isCategoryDropActive && this.hideCategoryDropdown();
|
||||
};
|
||||
|
||||
toggleCollapse = (e) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
this.setState((prev) => ({
|
||||
isCategoryActive: !prev.isCategoryActive
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
toggleCategoryDropdown = (e) => {
|
||||
e.preventDefault();
|
||||
// this.props.hideParentCategoryDrop();
|
||||
this.setState((prev) => ({
|
||||
isCategoryDropActive: !prev.isCategoryDropActive
|
||||
}));
|
||||
};
|
||||
|
||||
hideCategoryDropdown = () => {
|
||||
this.setState({
|
||||
isCategoryDropActive: false
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
category,
|
||||
categories,
|
||||
connectDropTarget,
|
||||
connectDragSource,
|
||||
hideParentCategoryDrop,
|
||||
parentId,
|
||||
showDeletePopup,
|
||||
getFeedResults,
|
||||
showRenamePopup,
|
||||
showAddCategoryPopup,
|
||||
moveCategory,
|
||||
moveFeed,
|
||||
showAddClippingsFeedPopup,
|
||||
clipArticles,
|
||||
toggleExportFeed,
|
||||
toggleExportCategory
|
||||
} = this.props;
|
||||
|
||||
const isFeeds = category.feeds.length > 0;
|
||||
const isChildes = category.childes.length > 0;
|
||||
const categoryType = category.type;
|
||||
|
||||
let categoryActiveClass = this.state.isCategoryActive
|
||||
? ' active-category'
|
||||
: '';
|
||||
|
||||
return connectDragSource(
|
||||
connectDropTarget(
|
||||
<li
|
||||
className={'metismenu-item ' + categoryType + categoryActiveClass}
|
||||
onClick={hideParentCategoryDrop}
|
||||
>
|
||||
<CategoryHead
|
||||
toggleCollapse={this.toggleCollapse}
|
||||
toggleCategoryDropdown={this.toggleCategoryDropdown}
|
||||
isCategoryDropActive={this.state.isCategoryDropActive}
|
||||
isCategoryActive={this.state.isCategoryActive}
|
||||
hideDropDown={this.hideCategoryDropdown}
|
||||
parentId={parentId}
|
||||
category={category}
|
||||
showDeletePopup={showDeletePopup}
|
||||
showRenamePopup={showRenamePopup}
|
||||
showAddCategoryPopup={showAddCategoryPopup}
|
||||
toggleExportCategory={toggleExportCategory}
|
||||
showAddClippingsFeedPopup={showAddClippingsFeedPopup}
|
||||
categories={categories}
|
||||
/>
|
||||
|
||||
<ul
|
||||
className={cx('metismenu-container', {
|
||||
visible: this.state.isCategoryActive
|
||||
})}
|
||||
>
|
||||
{isFeeds &&
|
||||
category.feeds.map((feed, i) => {
|
||||
return (
|
||||
<Feed
|
||||
key={'feed' + i}
|
||||
feed={feed}
|
||||
showDeletePopup={showDeletePopup}
|
||||
showRenamePopup={showRenamePopup}
|
||||
categories={categories}
|
||||
categoryId={category.id}
|
||||
hideParentCategoryDrop={this.hideCategoryDropdown}
|
||||
getFeedResults={getFeedResults}
|
||||
clipArticles={clipArticles}
|
||||
toggleExportFeed={toggleExportFeed}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
{isChildes &&
|
||||
category.childes.map((_category, i) => {
|
||||
return (
|
||||
<Category
|
||||
key={'category' + i}
|
||||
showDeletePopup={showDeletePopup}
|
||||
showRenamePopup={showRenamePopup}
|
||||
showAddCategoryPopup={showAddCategoryPopup}
|
||||
showAddClippingsFeedPopup={showAddClippingsFeedPopup}
|
||||
parentId={category.id}
|
||||
category={_category}
|
||||
categories={categories}
|
||||
hideParentCategoryDrop={this.hideCategoryDropdown}
|
||||
getFeedResults={getFeedResults}
|
||||
connectDropTarget={connectDropTarget}
|
||||
connectDragSource={connectDragSource}
|
||||
moveCategory={moveCategory}
|
||||
moveFeed={moveFeed}
|
||||
clipArticles={clipArticles}
|
||||
toggleExportFeed={toggleExportFeed}
|
||||
toggleExportCategory={toggleExportCategory}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</li>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const Category = compose(
|
||||
DropTarget(targetTypes, categoryTarget, (connect, monitor) => ({
|
||||
connectDropTarget: connect.dropTarget(),
|
||||
itemType: monitor.getItemType()
|
||||
})),
|
||||
DragSource(TYPES.FOLDER, folderSource, (connect) => ({
|
||||
connectDragSource: connect.dragSource()
|
||||
}))
|
||||
)(onClickOutside(CategoryClass));
|
||||
|
||||
export default Category;
|
||||
@@ -0,0 +1,105 @@
|
||||
import React from 'react';
|
||||
import cx from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import SidebarDropdown from './SidebarDropdown';
|
||||
import { translate } from 'react-i18next';
|
||||
|
||||
class CategoryHead extends React.Component {
|
||||
static propTypes = {
|
||||
t: PropTypes.func.isRequired,
|
||||
showDeletePopup: PropTypes.func.isRequired,
|
||||
showRenamePopup: PropTypes.func.isRequired,
|
||||
showAddCategoryPopup: PropTypes.func.isRequired,
|
||||
showAddClippingsFeedPopup: PropTypes.func.isRequired,
|
||||
toggleCollapse: PropTypes.func.isRequired,
|
||||
toggleCategoryDropdown: PropTypes.func.isRequired,
|
||||
toggleExportCategory: PropTypes.func.isRequired,
|
||||
isCategoryDropActive: PropTypes.bool.isRequired,
|
||||
isCategoryActive: PropTypes.bool.isRequired,
|
||||
hideDropDown: PropTypes.func.isRequired,
|
||||
parentId: PropTypes.number.isRequired,
|
||||
category: PropTypes.object.isRequired,
|
||||
categories: PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
getSidebarName(name) {
|
||||
const catName = this.props.t(`sidebar.${name}`);
|
||||
if (catName === `sidebar.${name}`) {
|
||||
return name;
|
||||
}
|
||||
return catName;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
isCategoryActive,
|
||||
isCategoryDropActive,
|
||||
category,
|
||||
categories,
|
||||
showDeletePopup,
|
||||
showRenamePopup,
|
||||
showAddCategoryPopup,
|
||||
showAddClippingsFeedPopup,
|
||||
toggleExportCategory,
|
||||
hideDropDown
|
||||
} = this.props;
|
||||
|
||||
const isCategoryDeletedType = category.subType === 'deleted_content';
|
||||
const categoryAttrId = 'sidebar-category' + category.id;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="metismenu-link"
|
||||
id={categoryAttrId}
|
||||
onClick={this.props.toggleCollapse}
|
||||
>
|
||||
{/* <i className="sidebar-category__closed-icon" onClick={this.props.toggleCollapse}> </i>
|
||||
<i className="sidebar-category__open-icon" onClick={this.props.toggleCollapse}> </i> */}
|
||||
|
||||
{isCategoryDeletedType ? (
|
||||
<i className="metismenu-icon pe-7s-trash"></i>
|
||||
) : (
|
||||
<i className="metismenu-icon pe-7s-folder"></i>
|
||||
)}
|
||||
|
||||
{this.getSidebarName(category.name)}
|
||||
|
||||
{!isCategoryDeletedType && (
|
||||
<i
|
||||
tabIndex="0"
|
||||
className="metismenu-state-icon font-size-lg opacity-10 pe-7s-more mr-4"
|
||||
onClick={this.props.toggleCategoryDropdown}
|
||||
/>
|
||||
)}
|
||||
<i
|
||||
className={cx(
|
||||
'metismenu-state-icon pe-7s-angle-down pointer-events-none opacity-10',
|
||||
{
|
||||
'rotate-minus-90': isCategoryActive
|
||||
}
|
||||
)}
|
||||
/>
|
||||
|
||||
{isCategoryDropActive && (
|
||||
<SidebarDropdown
|
||||
parentAttrId={categoryAttrId}
|
||||
categories={categories}
|
||||
itemId={category.id}
|
||||
itemSubType={category.subType}
|
||||
itemType={category.type}
|
||||
itemName={category.name}
|
||||
parentId={this.props.parentId}
|
||||
showDeletePopup={showDeletePopup}
|
||||
showRenamePopup={showRenamePopup}
|
||||
showAddCategoryPopup={showAddCategoryPopup}
|
||||
showAddClippingsPopup={showAddClippingsFeedPopup}
|
||||
hideDropDown={hideDropDown}
|
||||
toggleExportCategory={toggleExportCategory}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(['common'], { wait: true })(CategoryHead);
|
||||
@@ -0,0 +1,65 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { translate } from 'react-i18next';
|
||||
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
|
||||
|
||||
export class DeletePopup extends React.Component {
|
||||
static propTypes = {
|
||||
itemToDelete: PropTypes.object.isRequired,
|
||||
hideDeletePopup: PropTypes.func.isRequired,
|
||||
deleteFeed: PropTypes.func.isRequired,
|
||||
deleteCategory: PropTypes.func.isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
hidePopup = () => {
|
||||
this.props.hideDeletePopup();
|
||||
};
|
||||
|
||||
onSubmit = () => {
|
||||
const {
|
||||
itemToDelete,
|
||||
deleteCategory,
|
||||
deleteFeed,
|
||||
hideDeletePopup
|
||||
} = this.props;
|
||||
switch (this.props.itemToDelete.itemType) {
|
||||
case 'feed':
|
||||
deleteFeed(itemToDelete.itemId, itemToDelete.parentId);
|
||||
break;
|
||||
case 'directory':
|
||||
deleteCategory(itemToDelete.itemId);
|
||||
break;
|
||||
}
|
||||
hideDeletePopup();
|
||||
};
|
||||
|
||||
render() {
|
||||
const itemName = this.props.itemToDelete.itemName;
|
||||
const itemType = this.props.itemToDelete.itemType;
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<Modal isOpen toggle={this.hidePopup} backdrop="static">
|
||||
<ModalHeader toggle={this.hidePopup}>
|
||||
{t('commonWords.Confirm')}
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<p>
|
||||
{t('messages.deleteMessage')} {itemType + ' "' + itemName + '"'}
|
||||
</p>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="light" onClick={this.hidePopup}>
|
||||
{t('commonWords.Cancel')}
|
||||
</Button>
|
||||
<Button color="danger" onClick={this.onSubmit}>
|
||||
{t('commonWords.Delete')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(['common'], { wait: true })(DeletePopup);
|
||||
@@ -0,0 +1,162 @@
|
||||
/** DRAG SOURCE **/
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose } from 'redux';
|
||||
import SidebarDropdown from './SidebarDropdown';
|
||||
import { DragSource, DropTarget } from 'react-dnd';
|
||||
import onClickOutside from 'react-onclickoutside';
|
||||
import { TYPES } from '../../../redux/modules/appState/sidebar';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
const feedSource = {
|
||||
beginDrag(props) {
|
||||
return {
|
||||
type: TYPES.FEED,
|
||||
id: props.feed.id,
|
||||
feed: props.feed,
|
||||
currentCategoryId: props.categoryId
|
||||
};
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Specifies which props to inject into component from Drag n Drop.
|
||||
*/
|
||||
function dragCollect(connect) {
|
||||
return {
|
||||
// Call this function inside render()
|
||||
// to let React DnD handle the drag events:
|
||||
connectDragSource: connect.dragSource()
|
||||
};
|
||||
}
|
||||
|
||||
/** DROP TARGET **/
|
||||
const feedTarget = {
|
||||
drop(props, monitor) {
|
||||
if (monitor.didDrop()) return;
|
||||
const { feed, clipArticles } = props;
|
||||
clipArticles(feed.id);
|
||||
},
|
||||
|
||||
canDrop(props, monitor) {
|
||||
return props.feed.subType === 'clip_feed';
|
||||
}
|
||||
};
|
||||
|
||||
function dropCollect(connect, monitor) {
|
||||
return {
|
||||
connectDropTarget: connect.dropTarget()
|
||||
};
|
||||
}
|
||||
|
||||
export class Feed extends React.Component {
|
||||
static propTypes = {
|
||||
feed: PropTypes.object.isRequired,
|
||||
categoryId: PropTypes.number.isRequired,
|
||||
categories: PropTypes.array.isRequired,
|
||||
showDeletePopup: PropTypes.func.isRequired,
|
||||
showRenamePopup: PropTypes.func.isRequired,
|
||||
hideParentCategoryDrop: PropTypes.func.isRequired,
|
||||
connectDragSource: PropTypes.func.isRequired,
|
||||
connectDropTarget: PropTypes.func.isRequired,
|
||||
getFeedResults: PropTypes.func.isRequired,
|
||||
clipArticles: PropTypes.func.isRequired,
|
||||
toggleExportFeed: PropTypes.func.isRequired,
|
||||
history: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isItemDropActive: false
|
||||
};
|
||||
}
|
||||
|
||||
//hide feed dropdown if there was click outside
|
||||
handleClickOutside = () => {
|
||||
this.state.isItemDropActive && this.hideDropDown();
|
||||
};
|
||||
|
||||
hideDropDown = () => {
|
||||
this.setState({
|
||||
isItemDropActive: false
|
||||
});
|
||||
};
|
||||
|
||||
toggleItemDropdown = (e) => {
|
||||
e.preventDefault();
|
||||
this.setState({
|
||||
isItemDropActive: !this.state.isItemDropActive
|
||||
});
|
||||
};
|
||||
|
||||
onFeedClick = (e) => {
|
||||
const { history, getFeedResults, feed } = this.props;
|
||||
e.preventDefault();
|
||||
history.push('/app/search/search');
|
||||
getFeedResults({ page: 1 }, feed.id);
|
||||
window.scrollTo(0, 0);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
feed,
|
||||
categoryId,
|
||||
categories,
|
||||
connectDragSource,
|
||||
connectDropTarget,
|
||||
showDeletePopup,
|
||||
showRenamePopup,
|
||||
toggleExportFeed
|
||||
} = this.props;
|
||||
const feedAttrId = 'sidebar-feed' + feed.id;
|
||||
const dragAndDrop = compose(connectDragSource, connectDropTarget);
|
||||
|
||||
return dragAndDrop(
|
||||
<li
|
||||
id={feedAttrId}
|
||||
onClick={this.props.hideParentCategoryDrop}
|
||||
className="metismenu-item"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
className={`metismenu-link feed-icon ${feed.class}`}
|
||||
onClick={this.onFeedClick}
|
||||
>
|
||||
{feed.name}
|
||||
</a>
|
||||
|
||||
<i
|
||||
tabIndex="0"
|
||||
className="metismenu-state-icon font-size-lg opacity-10 pe-7s-more"
|
||||
onClick={this.toggleItemDropdown}
|
||||
></i>
|
||||
|
||||
{this.state.isItemDropActive && (
|
||||
<SidebarDropdown
|
||||
parentAttrId={feedAttrId}
|
||||
categories={categories}
|
||||
itemId={feed.id}
|
||||
itemType={feed.type}
|
||||
itemSubType={feed.subType}
|
||||
itemName={feed.name}
|
||||
itemExported={feed.exported}
|
||||
parentId={categoryId}
|
||||
showDeletePopup={showDeletePopup}
|
||||
showRenamePopup={showRenamePopup}
|
||||
toggleExportFeed={toggleExportFeed}
|
||||
hideDropDown={this.hideDropDown}
|
||||
/>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const applyDecorators = compose(
|
||||
withRouter,
|
||||
DragSource(TYPES.FEED, feedSource, dragCollect),
|
||||
DropTarget([TYPES.CLIP_ARTICLE], feedTarget, dropCollect),
|
||||
onClickOutside
|
||||
);
|
||||
|
||||
export default applyDecorators(Feed);
|
||||
@@ -0,0 +1,106 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
|
||||
export class Filter extends React.Component {
|
||||
static propTypes = {
|
||||
t: PropTypes.func.isRequired,
|
||||
areFeedsFiltered: PropTypes.bool.isRequired,
|
||||
categories: PropTypes.array.isRequired,
|
||||
setFilteredCategories: PropTypes.func.isRequired,
|
||||
clearFilteredCategories: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
sidebarAnimationDisabled: true,
|
||||
activeSearch: false
|
||||
}
|
||||
}
|
||||
|
||||
activeSearchFunc = () => {
|
||||
this.setState({ activeSearch: !this.state.activeSearch })
|
||||
this.clearFilter()
|
||||
}
|
||||
|
||||
filterCategoriesList = (
|
||||
categories,
|
||||
searchQuery,
|
||||
setParentBranchMatchFromParent
|
||||
) => {
|
||||
// show category if there is feed
|
||||
return categories.filter((category) => {
|
||||
category.branchMatch = false
|
||||
|
||||
//function that sets parent branchMatch prop
|
||||
function setParentBranchMatch (flag) {
|
||||
category.branchMatch = flag
|
||||
}
|
||||
|
||||
if (category.childes.length > 0) {
|
||||
category.childes = this.filterCategoriesList(
|
||||
category.childes,
|
||||
searchQuery,
|
||||
setParentBranchMatch
|
||||
)
|
||||
}
|
||||
|
||||
// filter feeds in category
|
||||
category.feeds = category.feeds.filter((feed) => {
|
||||
return feed.name.toLowerCase().indexOf(searchQuery) !== -1
|
||||
})
|
||||
// if this category is a child and it has matched feeds or its child have, then we set branchMatch prop of parent
|
||||
if (
|
||||
(category.feeds.length > 0 && setParentBranchMatchFromParent) ||
|
||||
(category.branchMatch && setParentBranchMatchFromParent)
|
||||
) {
|
||||
setParentBranchMatchFromParent(true)
|
||||
}
|
||||
|
||||
return category.branchMatch || category.feeds.length > 0
|
||||
})
|
||||
}
|
||||
|
||||
filterSidebarItems = (e) => {
|
||||
const searchQuery = e.target.value.toLowerCase()
|
||||
const categoriesCopy = this.props.categories.slice(0)
|
||||
|
||||
if (searchQuery.length) {
|
||||
const filteredCat = this.filterCategoriesList(categoriesCopy, searchQuery)
|
||||
this.props.setFilteredCategories(filteredCat)
|
||||
} else {
|
||||
this.props.clearFilteredCategories()
|
||||
}
|
||||
}
|
||||
|
||||
clearFilter = () => {
|
||||
this.props.clearFilteredCategories()
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div
|
||||
className={classnames('search-wrapper mb-1', {
|
||||
active: this.state.activeSearch
|
||||
})}
|
||||
>
|
||||
<div className="input-holder">
|
||||
<input
|
||||
type="text"
|
||||
className="search-input"
|
||||
placeholder={this.props.t('common:sidebar.typeToSearch')}
|
||||
onKeyUp={this.filterSidebarItems}
|
||||
id="sidebar-search"
|
||||
/>
|
||||
<button onClick={this.activeSearchFunc} className="search-icon">
|
||||
<span />
|
||||
</button>
|
||||
</div>
|
||||
<button onClick={this.activeSearchFunc} className="close"></button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Filter
|
||||
@@ -0,0 +1,90 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { translate } from 'react-i18next'
|
||||
import {
|
||||
Button,
|
||||
Input,
|
||||
Label,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
ModalHeader
|
||||
} from 'reactstrap'
|
||||
|
||||
export class RenamePopup extends React.Component {
|
||||
static propTypes = {
|
||||
itemToRename: PropTypes.object.isRequired,
|
||||
hideRenamePopup: PropTypes.func.isRequired,
|
||||
renameFeed: PropTypes.func.isRequired,
|
||||
renameCategory: PropTypes.func.isRequired,
|
||||
addAlert: PropTypes.func.isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
itemName: props.itemToRename.itemName
|
||||
}
|
||||
}
|
||||
|
||||
hidePopup = () => {
|
||||
this.props.hideRenamePopup()
|
||||
}
|
||||
|
||||
onSubmit = () => {
|
||||
const newName = this.state.itemName
|
||||
const {
|
||||
itemToRename,
|
||||
renameFeed,
|
||||
renameCategory,
|
||||
hideRenamePopup
|
||||
} = this.props
|
||||
|
||||
switch (this.props.itemToRename.itemType) {
|
||||
case 'feed':
|
||||
renameFeed(itemToRename.itemId, newName, itemToRename.parentId)
|
||||
break
|
||||
case 'directory':
|
||||
renameCategory(itemToRename.itemId, newName, itemToRename.parentId)
|
||||
break
|
||||
}
|
||||
|
||||
hideRenamePopup()
|
||||
}
|
||||
|
||||
onChangeName = (e) => {
|
||||
const { value } = e.target // validation needed
|
||||
|
||||
this.setState({
|
||||
itemName: value
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const itemName = this.state.itemName
|
||||
const { t } = this.props
|
||||
|
||||
return (
|
||||
<Modal isOpen toggle={this.hidePopup} backdrop="static">
|
||||
<ModalHeader toggle={this.hidePopup}>
|
||||
{t('commonWords.Rename')}
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<Label>{t('sidebarPopup.enterNamelabel')}</Label>
|
||||
<Input type="text" value={itemName} onChange={this.onChangeName} />
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="light" onClick={this.hidePopup}>
|
||||
{t('commonWords.Cancel')}
|
||||
</Button>
|
||||
<Button color="primary" onClick={this.onSubmit}>
|
||||
{t('commonWords.Rename')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(['common'], { wait: true })(RenamePopup)
|
||||
@@ -0,0 +1,155 @@
|
||||
import React, { Fragment } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import cx from 'classnames'
|
||||
import Categories from './Categories'
|
||||
import Filter from './Filter'
|
||||
import DeletePopup from './DeletePopup'
|
||||
import RenamePopup from './RenamePopup'
|
||||
import AddCategoryPopup from './AddCategoryPopup'
|
||||
import AddClippingsFeedPopup from './AddClippingsFeedPopup'
|
||||
import LoadersAdvanced from '../../common/Loader/Loader'
|
||||
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'
|
||||
import PerfectScrollbar from 'react-perfect-scrollbar'
|
||||
import HeaderLogo from '../AppHeader/HeaderLogo'
|
||||
|
||||
export class Sidebar extends React.Component {
|
||||
static propTypes = {
|
||||
actions: PropTypes.object.isRequired,
|
||||
themeOptions: PropTypes.object.isRequired,
|
||||
backgroundColor: PropTypes.string,
|
||||
backgroundImage: PropTypes.any,
|
||||
backgroundImageOpacity: PropTypes.any,
|
||||
enableBackgroundImage: PropTypes.any,
|
||||
enableMobileMenu: PropTypes.any,
|
||||
enableSidebarShadow: PropTypes.any,
|
||||
setEnableMobileMenu: PropTypes.func,
|
||||
t: PropTypes.func,
|
||||
sidebarState: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
sidebarAnimationDisabled: true,
|
||||
activeSearch: false
|
||||
}
|
||||
}
|
||||
|
||||
toggleMobileSidebar = () => {
|
||||
let { enableMobileMenu, setEnableMobileMenu } = this.props
|
||||
setEnableMobileMenu(!enableMobileMenu)
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.props.actions.getSidebarCategories()
|
||||
}
|
||||
|
||||
activeSearchFunc = () => {
|
||||
this.setState({ activeSearch: !this.state.activeSearch })
|
||||
}
|
||||
|
||||
render () {
|
||||
let {
|
||||
backgroundColor,
|
||||
enableBackgroundImage,
|
||||
enableSidebarShadow,
|
||||
backgroundImage,
|
||||
backgroundImageOpacity
|
||||
} = this.props.themeOptions
|
||||
|
||||
const { sidebarState, actions } = this.props
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div
|
||||
className="sidebar-mobile-overlay"
|
||||
onClick={this.toggleMobileSidebar}
|
||||
/>
|
||||
<CSSTransitionGroup
|
||||
component="div"
|
||||
className={cx('app-sidebar', backgroundColor, {
|
||||
'sidebar-shadow': enableSidebarShadow
|
||||
})}
|
||||
transitionName="SidebarAnimation"
|
||||
transitionAppear
|
||||
transitionAppearTimeout={1500}
|
||||
transitionEnter={false}
|
||||
transitionLeave={false}
|
||||
>
|
||||
<HeaderLogo />
|
||||
{!sidebarState.areCategoriesLoaded && <LoadersAdvanced />}
|
||||
<PerfectScrollbar>
|
||||
<div className="app-sidebar__inner mt-3">
|
||||
<div className="vertical-nav-menu" data-tour="left-panel">
|
||||
<div className="metismenu-container">
|
||||
<Filter
|
||||
t={this.props.t}
|
||||
categories={sidebarState.categories}
|
||||
areFeedsFiltered={sidebarState.areFeedsFiltered}
|
||||
setFilteredCategories={actions.setFilteredCategories}
|
||||
clearFilteredCategories={actions.clearFilteredCategories}
|
||||
/>
|
||||
|
||||
<Categories
|
||||
actions={actions}
|
||||
areCategoriesLoaded={sidebarState.areCategoriesLoaded}
|
||||
areFeedsFiltered={sidebarState.areFeedsFiltered}
|
||||
categories={sidebarState.categories}
|
||||
filteredCategories={sidebarState.filteredCategories}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{sidebarState.popupVisible.delete && (
|
||||
<DeletePopup
|
||||
hideDeletePopup={actions.hideDeletePopup}
|
||||
deleteFeed={actions.deleteFeed}
|
||||
deleteCategory={actions.deleteCategory}
|
||||
itemToDelete={sidebarState.popupItems.delete}
|
||||
/>
|
||||
)}
|
||||
|
||||
{sidebarState.popupVisible.rename && (
|
||||
<RenamePopup
|
||||
addAlert={actions.addAlert}
|
||||
hideRenamePopup={actions.hideRenamePopup}
|
||||
renameFeed={actions.renameFeed}
|
||||
renameCategory={actions.renameCategory}
|
||||
itemToRename={sidebarState.popupItems.rename}
|
||||
/>
|
||||
)}
|
||||
|
||||
{sidebarState.popupVisible.addCategory && (
|
||||
<AddCategoryPopup
|
||||
hideAddCategoryPopup={actions.hideAddCategoryPopup}
|
||||
addCategory={actions.addCategory}
|
||||
parentId={sidebarState.popupItems.addCategory.parentId}
|
||||
/>
|
||||
)}
|
||||
|
||||
{sidebarState.popupVisible.addClippingsFeed && (
|
||||
<AddClippingsFeedPopup
|
||||
parentId={sidebarState.popupItems.addClippingsFeed.parentId}
|
||||
hidePopup={actions.hideAddClippingsFeedPopup}
|
||||
addClippingsFeed={actions.addClippingsFeed}
|
||||
addAlert={actions.addAlert}
|
||||
categories={sidebarState.categories}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</PerfectScrollbar>
|
||||
<div
|
||||
className={cx('app-sidebar-bg', backgroundImageOpacity)}
|
||||
style={{
|
||||
backgroundImage: enableBackgroundImage
|
||||
? 'url(' + backgroundImage + ')'
|
||||
: null
|
||||
}}
|
||||
></div>
|
||||
</CSSTransitionGroup>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default React.memo(Sidebar)
|
||||
@@ -0,0 +1,154 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import $ from 'jquery'
|
||||
import { translate } from 'react-i18next'
|
||||
|
||||
export class SidebarDropdown extends React.Component {
|
||||
static propTypes = {
|
||||
itemName: PropTypes.string.isRequired,
|
||||
itemSubType: PropTypes.string.isRequired,
|
||||
itemType: PropTypes.string.isRequired,
|
||||
itemId: PropTypes.number.isRequired,
|
||||
itemExported: PropTypes.bool,
|
||||
parentId: PropTypes.number.isRequired,
|
||||
parentAttrId: PropTypes.string.isRequired,
|
||||
showDeletePopup: PropTypes.func.isRequired,
|
||||
showRenamePopup: PropTypes.func.isRequired,
|
||||
showAddCategoryPopup: PropTypes.func,
|
||||
showAddClippingsPopup: PropTypes.func,
|
||||
toggleExportFeed: PropTypes.func,
|
||||
toggleExportCategory: PropTypes.func,
|
||||
t: PropTypes.func.isRequired,
|
||||
hideDropDown: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
dropdownTopPos: 'auto',
|
||||
dropdownBottomPos: 'auto',
|
||||
dropdownOpacity: 0
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
const topPos = $('#' + this.props.parentAttrId).offset().top - $(document).scrollTop()
|
||||
const dropdownHeight = $('#sidebar-category-dropdown').height()
|
||||
|
||||
if ($(window).height() - topPos >= dropdownHeight) {
|
||||
this.setState({
|
||||
dropdownTopPos: topPos,
|
||||
dropdownOpacity: 1
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
dropdownBottomPos: 5,
|
||||
dropdownOpacity: 1
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
onExportToggle = () => {
|
||||
const {itemId, toggleExportFeed, itemExported, hideDropDown} = this.props
|
||||
toggleExportFeed(itemId, !itemExported)
|
||||
hideDropDown()
|
||||
};
|
||||
|
||||
onExportCategoryToggle = () => {
|
||||
const {itemId, toggleExportCategory, itemExported, hideDropDown} = this.props
|
||||
toggleExportCategory(itemId, !itemExported)
|
||||
hideDropDown()
|
||||
};
|
||||
|
||||
onDelete = () => {
|
||||
this.props.showDeletePopup(this.props.itemId, this.props.itemType, this.props.itemName, this.props.parentId)
|
||||
};
|
||||
|
||||
onRename = () => {
|
||||
this.props.showRenamePopup(this.props.itemId, this.props.itemType, this.props.itemName, this.props.parentId)
|
||||
};
|
||||
|
||||
onAddCategory = () => {
|
||||
// set this item id as parent of new category
|
||||
this.props.showAddCategoryPopup(this.props.itemId)
|
||||
};
|
||||
|
||||
onAddClippingsFeedPopup = () => {
|
||||
this.props.showAddClippingsPopup(this.props.itemId)
|
||||
};
|
||||
|
||||
render () {
|
||||
const { itemSubType, t, itemExported } = this.props
|
||||
let dropdown
|
||||
|
||||
switch (itemSubType) {
|
||||
case 'my_content':
|
||||
dropdown = <ul id="sidebar-category-dropdown" className="sidebar-category__dropdown" style={{top: this.state.dropdownTopPos, bottom: this.state.dropdownBottomPos, opacity: this.state.dropdownOpacity}}>
|
||||
<li><a href="#" onClick={this.onAddClippingsFeedPopup}>{t('sidebarDropdown.AddClippingsFeed')}</a></li>
|
||||
<li><a href="#" onClick={this.onAddCategory}>{t('sidebarDropdown.AddFolder')}</a></li>
|
||||
{/*<li><a href="#">{t('sidebarDropdown.DownloadSearchCriteria')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.EditSearchTemplate')}</a></li>*/}
|
||||
<li><a href="#" onClick={this.onExportCategoryToggle}>{t(itemExported ? 'sidebarDropdown.UnexportFeeds' : 'sidebarDropdown.ExportFeeds')}</a></li>
|
||||
{/*<li><a href="#">{t('sidebarDropdown.ViewUserComments')}</a></li>*/}
|
||||
</ul>
|
||||
break
|
||||
|
||||
case 'shared_content':
|
||||
dropdown = <ul id="sidebar-category-dropdown" className="sidebar-category__dropdown" style={{top: this.state.dropdownTopPos, bottom: this.state.dropdownBottomPos, opacity: this.state.dropdownOpacity}}>
|
||||
<li><a href="#" onClick={this.onAddClippingsFeedPopup}>{t('sidebarDropdown.AddClippingsFeed')}</a></li>
|
||||
<li><a href="#" onClick={this.onAddCategory}>{t('sidebarDropdown.AddFolder')}</a></li>
|
||||
{/*<li><a href="#">{t('sidebarDropdown.DownloadSearchCriteria')}</a></li>*/}
|
||||
<li><a href="#" onClick={this.onExportCategoryToggle}>{t(itemExported ? 'sidebarDropdown.UnexportFeeds' : 'sidebarDropdown.ExportFeeds')}</a></li>
|
||||
{/*<li><a href="#">{t('sidebarDropdown.ViewUserComments')}</a></li>*/}
|
||||
</ul>
|
||||
break
|
||||
|
||||
case 'custom':
|
||||
dropdown = <ul id="sidebar-category-dropdown" className="sidebar-category__dropdown" style={{top: this.state.dropdownTopPos, bottom: this.state.dropdownBottomPos, opacity: this.state.dropdownOpacity}}>
|
||||
<li><a href="#" onClick={this.onAddClippingsFeedPopup}>{t('sidebarDropdown.AddClippingsFeed')}</a></li>
|
||||
<li><a href="#" onClick={this.onAddCategory}>{t('sidebarDropdown.AddFolder')}</a></li>
|
||||
{/*<li><a href="#">{t('sidebarDropdown.DownloadSearchCriteria')}</a></li>*/}
|
||||
<li><a href="#" onClick={this.onExportCategoryToggle}>{t(itemExported ? 'sidebarDropdown.UnexportFeeds' : 'sidebarDropdown.ExportFeeds')}</a></li>
|
||||
<li><a href="#" onClick={this.onRename}>{t('sidebarDropdown.RenameFolder')}</a></li>
|
||||
{/*<li><a href="#">{t('sidebarDropdown.ViewUserComments')}</a></li>*/}
|
||||
<li><a href="#" onClick={this.onDelete}>{t('sidebarDropdown.DeleteFolder')}</a></li>
|
||||
</ul>
|
||||
break
|
||||
|
||||
case 'query_feed':
|
||||
dropdown = <ul id="sidebar-category-dropdown" className="sidebar-category__dropdown" style={{top: this.state.dropdownTopPos, bottom: this.state.dropdownBottomPos, opacity: this.state.dropdownOpacity}}>
|
||||
{/*<li><a href="#">{t('sidebarDropdown.AddArticle')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.AddToDashboard')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.AnalyzeFeed')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.DownloadArticleData')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.DownloadFeedStatistics')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.DownloadSearchCriteria')}</a></li>*/}
|
||||
<li><a href="#" onClick={this.onExportToggle}>{t(itemExported ? 'sidebarDropdown.UnexportFeed' : 'sidebarDropdown.ExportFeed')}</a></li>
|
||||
<li><a href="#" onClick={this.onRename}>{t('sidebarDropdown.RenameFeed')}</a></li>
|
||||
<li><a href="#" onClick={this.onDelete}>{t('sidebarDropdown.DeleteFeed')}</a></li>
|
||||
</ul>
|
||||
break
|
||||
|
||||
case 'clip_feed':
|
||||
dropdown = <ul id="sidebar-category-dropdown" className="sidebar-category__dropdown" style={{top: this.state.dropdownTopPos, bottom: this.state.dropdownBottomPos, opacity: this.state.dropdownOpacity}}>
|
||||
{/*<li><a href="#">{t('sidebarDropdown.AddArticle')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.AddToDashboard')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.AnalyzeFeed')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.DownloadArticleData')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.DownloadFeedStatistics')}</a></li>
|
||||
<li><a href="#">{t('sidebarDropdown.DownloadSearchCriteria')}</a></li>*/}
|
||||
<li><a href="#" onClick={this.onExportToggle}>{t(itemExported ? 'sidebarDropdown.UnexportFeed' : 'sidebarDropdown.ExportFeed')}</a></li>
|
||||
<li><a href="#" onClick={this.onRename}>{t('sidebarDropdown.RenameFeed')}</a></li>
|
||||
<li><a href="#" onClick={this.onDelete}>{t('sidebarDropdown.DeleteFeed')}</a></li>
|
||||
</ul>
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
dropdown
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(['common'], { wait: true })(SidebarDropdown)
|
||||
Reference in New Issue
Block a user