Add title editor and delete button
This commit is contained in:
parent
87490a3220
commit
09b4b025df
6 changed files with 138 additions and 8 deletions
|
@ -113,7 +113,7 @@ export const submitBookmarkCategoryEditor = shouldReset => (dispatch, getState)
|
||||||
export const setupBookmarkCategoryEditor = bookmarkCategoryId => (dispatch, getState) => {
|
export const setupBookmarkCategoryEditor = bookmarkCategoryId => (dispatch, getState) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: BOOKMARK_CATEGORY_EDITOR_SETUP,
|
type: BOOKMARK_CATEGORY_EDITOR_SETUP,
|
||||||
bookmarkCategory: getState().getIn(['bookmarkCategories', bookmarkCategoryId]),
|
bookmarkCategory: getState().getIn(['bookmark_categories', bookmarkCategoryId]),
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatch(fetchBookmarkCategoryStatuses(bookmarkCategoryId));
|
dispatch(fetchBookmarkCategoryStatuses(bookmarkCategoryId));
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { PureComponent } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { changeBookmarkCategoryEditorTitle, submitBookmarkCategoryEditor } from '../../../actions/bookmark_categories';
|
||||||
|
import { IconButton } from '../../../components/icon_button';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
title: { id: 'bookmark_categories.edit.submit', defaultMessage: 'Change title' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
value: state.getIn(['bookmarkCategoryEditor', 'title']),
|
||||||
|
disabled: !state.getIn(['bookmarkCategoryEditor', 'isChanged']) || !state.getIn(['bookmarkCategoryEditor', 'title']),
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
onChange: value => dispatch(changeBookmarkCategoryEditorTitle(value)),
|
||||||
|
onSubmit: () => dispatch(submitBookmarkCategoryEditor(false)),
|
||||||
|
});
|
||||||
|
|
||||||
|
class EditBookmarkCategoryForm extends PureComponent {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
value: PropTypes.string.isRequired,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
onChange: PropTypes.func.isRequired,
|
||||||
|
onSubmit: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
handleChange = e => {
|
||||||
|
this.props.onChange(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
this.props.onSubmit();
|
||||||
|
};
|
||||||
|
|
||||||
|
handleClick = () => {
|
||||||
|
this.props.onSubmit();
|
||||||
|
};
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { value, disabled, intl } = this.props;
|
||||||
|
|
||||||
|
const title = intl.formatMessage(messages.title);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className='column-inline-form' onSubmit={this.handleSubmit}>
|
||||||
|
<input
|
||||||
|
className='setting-text'
|
||||||
|
value={value}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
disabled={disabled}
|
||||||
|
icon='check'
|
||||||
|
title={title}
|
||||||
|
onClick={this.handleClick}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(EditBookmarkCategoryForm));
|
|
@ -10,16 +10,23 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
import { expandBookmarkCategoryStatuses, fetchBookmarkCategory, fetchBookmarkCategoryStatuses } from 'mastodon/actions/bookmark_categories';
|
import { deleteBookmarkCategory, expandBookmarkCategoryStatuses, fetchBookmarkCategory, fetchBookmarkCategoryStatuses , setupBookmarkCategoryEditor } from 'mastodon/actions/bookmark_categories';
|
||||||
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
|
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
|
||||||
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
import ColumnHeader from 'mastodon/components/column_header';
|
import ColumnHeader from 'mastodon/components/column_header';
|
||||||
|
import { Icon } from 'mastodon/components/icon';
|
||||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||||
import StatusList from 'mastodon/components/status_list';
|
import StatusList from 'mastodon/components/status_list';
|
||||||
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
|
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
|
||||||
import Column from 'mastodon/features/ui/components/column';
|
import Column from 'mastodon/features/ui/components/column';
|
||||||
import { getBookmarkCategoryStatusList } from 'mastodon/selectors';
|
import { getBookmarkCategoryStatusList } from 'mastodon/selectors';
|
||||||
|
|
||||||
|
import EditBookmarkCategoryForm from './components/edit_bookmark_category_form';
|
||||||
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
deleteMessage: { id: 'confirmations.delete_bookmary_category.message', defaultMessage: 'Are you sure you want to permanently delete this category?' },
|
||||||
|
deleteConfirm: { id: 'confirmations.delete_bookmark_category.confirm', defaultMessage: 'Delete' },
|
||||||
heading: { id: 'column.bookmarks', defaultMessage: 'Bookmarks' },
|
heading: { id: 'column.bookmarks', defaultMessage: 'Bookmarks' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,11 +34,16 @@ const mapStateToProps = (state, { params }) => ({
|
||||||
bookmarkCategory: state.getIn(['bookmark_categories', params.id]),
|
bookmarkCategory: state.getIn(['bookmark_categories', params.id]),
|
||||||
statusIds: getBookmarkCategoryStatusList(state, params.id),
|
statusIds: getBookmarkCategoryStatusList(state, params.id),
|
||||||
isLoading: state.getIn(['bookmark_categories', params.id, 'isLoading'], true),
|
isLoading: state.getIn(['bookmark_categories', params.id, 'isLoading'], true),
|
||||||
|
isEditing: state.getIn(['bookmarkCategoryEditor', 'bookmarkCategoryId']) === params.id,
|
||||||
hasMore: !!state.getIn(['bookmark_categories', params.id, 'next']),
|
hasMore: !!state.getIn(['bookmark_categories', params.id, 'next']),
|
||||||
});
|
});
|
||||||
|
|
||||||
class BookmarkCategoryStatuses extends ImmutablePureComponent {
|
class BookmarkCategoryStatuses extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
static contextTypes = {
|
||||||
|
router: PropTypes.object,
|
||||||
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
params: PropTypes.object.isRequired,
|
params: PropTypes.object.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
@ -42,6 +54,7 @@ class BookmarkCategoryStatuses extends ImmutablePureComponent {
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn: PropTypes.bool,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
isLoading: PropTypes.bool,
|
isLoading: PropTypes.bool,
|
||||||
|
isEditing: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
UNSAFE_componentWillMount () {
|
UNSAFE_componentWillMount () {
|
||||||
|
@ -68,6 +81,32 @@ class BookmarkCategoryStatuses extends ImmutablePureComponent {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleEditClick = () => {
|
||||||
|
this.props.dispatch(setupBookmarkCategoryEditor(this.props.params.id));
|
||||||
|
};
|
||||||
|
|
||||||
|
handleDeleteClick = () => {
|
||||||
|
const { dispatch, columnId, intl } = this.props;
|
||||||
|
const { id } = this.props.params;
|
||||||
|
|
||||||
|
dispatch(openModal({
|
||||||
|
modalType: 'CONFIRM',
|
||||||
|
modalProps: {
|
||||||
|
message: intl.formatMessage(messages.deleteMessage),
|
||||||
|
confirm: intl.formatMessage(messages.deleteConfirm),
|
||||||
|
onConfirm: () => {
|
||||||
|
dispatch(deleteBookmarkCategory(id));
|
||||||
|
|
||||||
|
if (columnId) {
|
||||||
|
dispatch(removeColumn(columnId));
|
||||||
|
} else {
|
||||||
|
this.context.router.history.push('/bookmark_categories');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
};
|
};
|
||||||
|
@ -77,7 +116,7 @@ class BookmarkCategoryStatuses extends ImmutablePureComponent {
|
||||||
}, 300, { leading: true });
|
}, 300, { leading: true });
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, bookmarkCategory, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
|
const { intl, bookmarkCategory, statusIds, columnId, multiColumn, hasMore, isLoading, isEditing } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
||||||
if (typeof bookmarkCategory === 'undefined') {
|
if (typeof bookmarkCategory === 'undefined') {
|
||||||
|
@ -96,6 +135,10 @@ class BookmarkCategoryStatuses extends ImmutablePureComponent {
|
||||||
|
|
||||||
const emptyMessage = <FormattedMessage id='empty_column.bookmarked_statuses' defaultMessage="You don't have any bookmarked posts yet. When you bookmark one, it will show up here." />;
|
const emptyMessage = <FormattedMessage id='empty_column.bookmarked_statuses' defaultMessage="You don't have any bookmarked posts yet. When you bookmark one, it will show up here." />;
|
||||||
|
|
||||||
|
const editor = isEditing && (
|
||||||
|
<EditBookmarkCategoryForm />
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.heading)}>
|
<Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.heading)}>
|
||||||
<ColumnHeader
|
<ColumnHeader
|
||||||
|
@ -106,7 +149,19 @@ class BookmarkCategoryStatuses extends ImmutablePureComponent {
|
||||||
onClick={this.handleHeaderClick}
|
onClick={this.handleHeaderClick}
|
||||||
pinned={pinned}
|
pinned={pinned}
|
||||||
multiColumn={multiColumn}
|
multiColumn={multiColumn}
|
||||||
/>
|
>
|
||||||
|
<div className='column-settings__row column-header__links'>
|
||||||
|
<button type='button' className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleEditClick}>
|
||||||
|
<Icon id='pencil' /> <FormattedMessage id='bookmark_categories.edit' defaultMessage='Edit category' />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type='button' className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleDeleteClick}>
|
||||||
|
<Icon id='trash' /> <FormattedMessage id='bookmark_categories.delete' defaultMessage='Delete category' />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{editor}
|
||||||
|
</div>
|
||||||
|
</ColumnHeader>
|
||||||
|
|
||||||
<StatusList
|
<StatusList
|
||||||
trackScroll={!pinned}
|
trackScroll={!pinned}
|
||||||
|
|
|
@ -147,7 +147,7 @@ class ListTimeline extends PureComponent {
|
||||||
handleEditAntennaClick = (e) => {
|
handleEditAntennaClick = (e) => {
|
||||||
const id = e.currentTarget.getAttribute('data-id');
|
const id = e.currentTarget.getAttribute('data-id');
|
||||||
this.context.router.history.push(`/antennasw/${id}/edit`);
|
this.context.router.history.push(`/antennasw/${id}/edit`);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleRepliesPolicyChange = ({ target }) => {
|
handleRepliesPolicyChange = ({ target }) => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
|
|
|
@ -49,7 +49,9 @@ const appendToBookmarkCategoryStatuses = (state, bookmarkCategoryId, statuses, n
|
||||||
|
|
||||||
const removeStatusFromAllBookmarkCategories = (state, status) => {
|
const removeStatusFromAllBookmarkCategories = (state, status) => {
|
||||||
state.toList().forEach((bookmarkCategory) => {
|
state.toList().forEach((bookmarkCategory) => {
|
||||||
|
if (state.getIn([bookmarkCategory.get('id'), 'items'])) {
|
||||||
state = state.updateIn([bookmarkCategory.get('id'), 'items'], items => items.delete(status.get('id')));
|
state = state.updateIn([bookmarkCategory.get('id'), 'items'], items => items.delete(status.get('id')));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
@ -58,8 +60,9 @@ export default function bookmarkCategories(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case BOOKMARK_CATEGORY_FETCH_SUCCESS:
|
case BOOKMARK_CATEGORY_FETCH_SUCCESS:
|
||||||
case BOOKMARK_CATEGORY_CREATE_SUCCESS:
|
case BOOKMARK_CATEGORY_CREATE_SUCCESS:
|
||||||
case BOOKMARK_CATEGORY_UPDATE_SUCCESS:
|
|
||||||
return normalizeBookmarkCategory(state, action.bookmarkCategory);
|
return normalizeBookmarkCategory(state, action.bookmarkCategory);
|
||||||
|
case BOOKMARK_CATEGORY_UPDATE_SUCCESS:
|
||||||
|
return state.setIn([action.bookmarkCategory.id, 'title'], action.bookmarkCategory.title);
|
||||||
case BOOKMARK_CATEGORIES_FETCH_SUCCESS:
|
case BOOKMARK_CATEGORIES_FETCH_SUCCESS:
|
||||||
return normalizeBookmarkCategories(state, action.bookmarkCategories);
|
return normalizeBookmarkCategories(state, action.bookmarkCategories);
|
||||||
case BOOKMARK_CATEGORY_DELETE_SUCCESS:
|
case BOOKMARK_CATEGORY_DELETE_SUCCESS:
|
||||||
|
|
|
@ -39,7 +39,6 @@ export default function bookmarkCategoryEditorReducer(state = initialState, acti
|
||||||
return state.withMutations(map => {
|
return state.withMutations(map => {
|
||||||
map.set('bookmarkCategoryId', action.bookmarkCategory.get('id'));
|
map.set('bookmarkCategoryId', action.bookmarkCategory.get('id'));
|
||||||
map.set('title', action.bookmarkCategory.get('title'));
|
map.set('title', action.bookmarkCategory.get('title'));
|
||||||
map.set('isExclusive', action.bookmarkCategory.get('is_exclusive'));
|
|
||||||
map.set('isSubmitting', false);
|
map.set('isSubmitting', false);
|
||||||
});
|
});
|
||||||
case BOOKMARK_CATEGORY_EDITOR_TITLE_CHANGE:
|
case BOOKMARK_CATEGORY_EDITOR_TITLE_CHANGE:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue