add UserHistory component
This commit is contained in:
parent
625a9177ee
commit
d01b893a68
13 changed files with 295 additions and 126 deletions
|
@ -76,8 +76,8 @@ export class FormField extends React.PureComponent<Props> {
|
||||||
);
|
);
|
||||||
} else if (type === 'textarea') {
|
} else if (type === 'textarea') {
|
||||||
input = <textarea type={type} id={name} {...inputProps} />;
|
input = <textarea type={type} id={name} {...inputProps} />;
|
||||||
} else if (type === 'checkbox') {
|
// } else if (type === 'checkbox') {
|
||||||
input = <Toggle id={name} {...inputProps} />;
|
// input = <Toggle id={name} {...inputProps} />;
|
||||||
} else {
|
} else {
|
||||||
input = <input type={type} id={name} {...inputProps} />;
|
input = <input type={type} id={name} {...inputProps} />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
selectRewardContentClaimIds,
|
selectRewardContentClaimIds,
|
||||||
makeSelectContentPositionForUri,
|
makeSelectContentPositionForUri,
|
||||||
} from 'redux/selectors/content';
|
} from 'redux/selectors/content';
|
||||||
import { doClearContentHistoryUri } from 'redux/actions/content';
|
|
||||||
import { selectShowNsfw } from 'redux/selectors/settings';
|
import { selectShowNsfw } from 'redux/selectors/settings';
|
||||||
import { selectPendingPublish } from 'redux/selectors/publish';
|
import { selectPendingPublish } from 'redux/selectors/publish';
|
||||||
import FileCard from './view';
|
import FileCard from './view';
|
||||||
|
|
|
@ -64,7 +64,6 @@ class FileCard extends React.PureComponent<Props> {
|
||||||
claimIsMine,
|
claimIsMine,
|
||||||
pending,
|
pending,
|
||||||
position,
|
position,
|
||||||
lastViewed,
|
|
||||||
clearHistoryUri,
|
clearHistoryUri,
|
||||||
showPrice,
|
showPrice,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -111,20 +110,6 @@ class FileCard extends React.PureComponent<Props> {
|
||||||
{fileInfo && <Icon icon={icons.LOCAL} />}
|
{fileInfo && <Icon icon={icons.LOCAL} />}
|
||||||
{position && <Icon icon={icons.REFRESH} />}
|
{position && <Icon icon={icons.REFRESH} />}
|
||||||
</div>
|
</div>
|
||||||
{lastViewed && (
|
|
||||||
<div className="card__subtitle">
|
|
||||||
{moment(lastViewed).from(moment())}
|
|
||||||
{position && <Icon icon={icons.REFRESH} />}
|
|
||||||
<span
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
clearHistoryUri(uri);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Icon icon={icons.CLOSE} iconColor="red" />
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
27
src/renderer/component/userHistory/index.js
Normal file
27
src/renderer/component/userHistory/index.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { selectHistoryPageCount, makeSelectHistoryForPage } from 'redux/selectors/content';
|
||||||
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
|
import { selectCurrentParams, makeSelectCurrentParam } from 'lbry-redux';
|
||||||
|
import { doClearContentHistoryUri } from 'redux/actions/content';
|
||||||
|
import UserHistory from './view';
|
||||||
|
|
||||||
|
const select = state => {
|
||||||
|
const paramPage = Number(makeSelectCurrentParam('page')(state) || 0);
|
||||||
|
return {
|
||||||
|
pageCount: selectHistoryPageCount(state),
|
||||||
|
page: paramPage,
|
||||||
|
params: selectCurrentParams(state),
|
||||||
|
history: makeSelectHistoryForPage(paramPage)(state),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
navigate: (path, params) => dispatch(doNavigate(path, params)),
|
||||||
|
clearHistoryUri: uri => dispatch(doClearContentHistoryUri(uri)),
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(UserHistory);
|
149
src/renderer/component/userHistory/view.jsx
Normal file
149
src/renderer/component/userHistory/view.jsx
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import FileCard from 'component/fileCard';
|
||||||
|
import Page from 'component/page';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import { FormField, FormRow } from 'component/common/form';
|
||||||
|
import ReactPaginate from 'react-paginate';
|
||||||
|
import UserHistoryItem from 'component/userHistoryItem';
|
||||||
|
|
||||||
|
type HistoryItem = {
|
||||||
|
uri: string,
|
||||||
|
lastViewed: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
history: Array<HistoryItem>,
|
||||||
|
page: number,
|
||||||
|
pageCount: number,
|
||||||
|
navigate: string => void,
|
||||||
|
params: { page: number },
|
||||||
|
};
|
||||||
|
|
||||||
|
class UserHistoryPage extends React.PureComponent<Props> {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
itemsSelected: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectAll = this.selectAll.bind(this);
|
||||||
|
this.unselectAll = this.unselectAll.bind(this);
|
||||||
|
this.removeSelected = this.removeSelected.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
changePage(pageNumber: number) {
|
||||||
|
const { params } = this.props;
|
||||||
|
const newParams = { ...params, page: pageNumber };
|
||||||
|
this.props.navigate('/user_history', newParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
paginate(e: SyntheticKeyboardEvent<*>) {
|
||||||
|
const pageFromInput = Number(e.currentTarget.value);
|
||||||
|
if (
|
||||||
|
pageFromInput &&
|
||||||
|
e.keyCode === 13 &&
|
||||||
|
!Number.isNaN(pageFromInput) &&
|
||||||
|
pageFromInput > 0 &&
|
||||||
|
pageFromInput <= this.props.pageCount
|
||||||
|
) {
|
||||||
|
this.changePage(pageFromInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelect(uri: string) {
|
||||||
|
console.log("onSelect", uri)
|
||||||
|
this.setState({
|
||||||
|
itemsSelected: { ...this.state.itemsSelected, [uri]: !this.state.itemsSelected[uri] }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
selectAll() {
|
||||||
|
const { history } = this.props;
|
||||||
|
const newSelectedState = {};
|
||||||
|
history.forEach(({uri}) => newSelectedState[uri] = true);
|
||||||
|
this.setState({ itemsSelected: newSelectedState });
|
||||||
|
}
|
||||||
|
|
||||||
|
unselectAll() {
|
||||||
|
this.setState({
|
||||||
|
itemsSelected: {}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
removeSelected() {
|
||||||
|
const { clearHistoryUri } = this.props;
|
||||||
|
const { itemsSelected } = this.state;
|
||||||
|
|
||||||
|
Object.keys(itemsSelected).forEach(uri => clearHistoryUri(uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { history, page, pageCount, navigate } = this.props;
|
||||||
|
const { itemsSelected } = this.state;
|
||||||
|
|
||||||
|
const allSelected = Object.keys(itemsSelected).length === history.length;
|
||||||
|
const selectHandler = allSelected ? this.unselectAll : this.selectAll;
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
button="link"
|
||||||
|
label={allSelected ? __("Cancel") : __("Select All")}
|
||||||
|
onClick={selectHandler} />
|
||||||
|
{!!Object.keys(itemsSelected).length && (
|
||||||
|
<Button
|
||||||
|
button="link"
|
||||||
|
label={__("Delete")}
|
||||||
|
onClick={this.removeSelected} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{!!history.length && (
|
||||||
|
<table className="card--section table table--stretch table--history">
|
||||||
|
<tbody>
|
||||||
|
{history.map(item => (
|
||||||
|
<UserHistoryItem
|
||||||
|
key={item.uri}
|
||||||
|
uri={item.uri}
|
||||||
|
lastViewed={item.lastViewed}
|
||||||
|
selected={!!itemsSelected[item.uri]}
|
||||||
|
onSelect={() => {
|
||||||
|
this.onSelect(item.uri)
|
||||||
|
}} />
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
)}
|
||||||
|
{pageCount > 1 && (
|
||||||
|
<FormRow verticallyCentered centered>
|
||||||
|
<ReactPaginate
|
||||||
|
pageCount={pageCount}
|
||||||
|
pageRangeDisplayed={2}
|
||||||
|
previousLabel="‹"
|
||||||
|
nextLabel="›"
|
||||||
|
activeClassName="pagination__item--selected"
|
||||||
|
pageClassName="pagination__item"
|
||||||
|
previousClassName="pagination__item pagination__item--previous"
|
||||||
|
nextClassName="pagination__item pagination__item--next"
|
||||||
|
breakClassName="pagination__item pagination__item--break"
|
||||||
|
marginPagesDisplayed={2}
|
||||||
|
onPageChange={e => this.changePage(e.selected)}
|
||||||
|
forcePage={page}
|
||||||
|
initialPage={page}
|
||||||
|
containerClassName="pagination"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
className="paginate-channel"
|
||||||
|
onKeyUp={e => this.paginate(e)}
|
||||||
|
prefix={__('Go to page:')}
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
</FormRow>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default UserHistoryPage;
|
9
src/renderer/component/userHistoryItem/index.js
Normal file
9
src/renderer/component/userHistoryItem/index.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doResolveUri } from 'lbry-redux';
|
||||||
|
import UserHistoryItem from './view';
|
||||||
|
|
||||||
|
const perform = (dispatch) => ({
|
||||||
|
resolveUri: uri => dispatch(doResolveUri(uri)),
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(null, perform)(UserHistoryItem);
|
53
src/renderer/component/userHistoryItem/view.jsx
Normal file
53
src/renderer/component/userHistoryItem/view.jsx
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import type { Claim } from 'types/claim';
|
||||||
|
import moment from 'moment';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import { FormRow, FormField } from 'component/common/form';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
lastViewed: number,
|
||||||
|
uri: string,
|
||||||
|
claim: ?{}
|
||||||
|
};
|
||||||
|
|
||||||
|
class UserHistoryItem extends React.PureComponent<Props> {
|
||||||
|
componentDidMount() {
|
||||||
|
const { claim, uri, resolveUri } = this.props;
|
||||||
|
|
||||||
|
if (!claim) {
|
||||||
|
console.log("fetch claim")
|
||||||
|
resolveUri(uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { lastViewed, selected, onSelect, claim } = this.props;
|
||||||
|
|
||||||
|
let name;
|
||||||
|
if (claim) {
|
||||||
|
({ name } = claim);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className={classnames({
|
||||||
|
"history__selected": selected
|
||||||
|
})}>
|
||||||
|
<td>
|
||||||
|
<FormField
|
||||||
|
checked={selected}
|
||||||
|
type="checkbox"
|
||||||
|
onClick={onSelect}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{moment(lastViewed).from(moment())}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{name}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default UserHistoryItem;
|
|
@ -89,6 +89,10 @@ class FilePage extends React.Component<Props> {
|
||||||
if (nextProps.fileInfo === undefined) {
|
if (nextProps.fileInfo === undefined) {
|
||||||
fetchFileInfo(uri);
|
fetchFileInfo(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uri !== nextProps.uri) {
|
||||||
|
setViewed(nextProps.uri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAutoplayChange(event: SyntheticInputEvent<*>) {
|
onAutoplayChange(event: SyntheticInputEvent<*>) {
|
||||||
|
|
|
@ -1,24 +1,4 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectHistoryPageCount, makeSelectHistoryForPage } from 'redux/selectors/content';
|
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
|
||||||
import { selectCurrentParams, makeSelectCurrentParam } from 'lbry-redux';
|
|
||||||
import UserHistoryPage from './view';
|
import UserHistoryPage from './view';
|
||||||
|
|
||||||
const select = state => {
|
export default connect(null, null)(UserHistoryPage);
|
||||||
const paramPage = Number(makeSelectCurrentParam('page')(state) || 0);
|
|
||||||
return {
|
|
||||||
pageCount: selectHistoryPageCount(state),
|
|
||||||
page: paramPage,
|
|
||||||
params: selectCurrentParams(state),
|
|
||||||
history: makeSelectHistoryForPage(paramPage)(state),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const perform = dispatch => ({
|
|
||||||
navigate: (path, params) => dispatch(doNavigate(path, params)),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(
|
|
||||||
select,
|
|
||||||
perform
|
|
||||||
)(UserHistoryPage);
|
|
||||||
|
|
|
@ -1,91 +1,13 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import FileCard from 'component/fileCard';
|
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import Button from 'component/button';
|
import UserHistory from 'component/userHistory';
|
||||||
import { FormField, FormRow } from 'component/common/form';
|
|
||||||
import ReactPaginate from 'react-paginate';
|
|
||||||
|
|
||||||
type HistoryItem = {
|
|
||||||
uri: string,
|
|
||||||
lastViewed: number,
|
|
||||||
};
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
history: Array<HistoryItem>,
|
|
||||||
page: number,
|
|
||||||
pageCount: number,
|
|
||||||
navigate: string => void,
|
|
||||||
params: { page: number },
|
|
||||||
};
|
|
||||||
|
|
||||||
class UserHistoryPage extends React.PureComponent<Props> {
|
|
||||||
changePage(pageNumber: number) {
|
|
||||||
const { params } = this.props;
|
|
||||||
const newParams = { ...params, page: pageNumber };
|
|
||||||
this.props.navigate('/user_history', newParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
paginate(e: SyntheticKeyboardEvent<*>) {
|
|
||||||
const pageFromInput = Number(e.currentTarget.value);
|
|
||||||
if (
|
|
||||||
pageFromInput &&
|
|
||||||
e.keyCode === 13 &&
|
|
||||||
!Number.isNaN(pageFromInput) &&
|
|
||||||
pageFromInput > 0 &&
|
|
||||||
pageFromInput <= this.props.pageCount
|
|
||||||
) {
|
|
||||||
this.changePage(pageFromInput);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
class UserHistoryPage extends React.PureComponent {
|
||||||
render() {
|
render() {
|
||||||
const { history, page, pageCount, navigate } = this.props;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<div className="card__list">
|
<UserHistory />
|
||||||
{history && history.length ? (
|
|
||||||
<React.Fragment>
|
|
||||||
{history.map(item => (
|
|
||||||
<FileCard key={item.uri} uri={item.uri} lastViewed={item.lastViewed} />
|
|
||||||
))}
|
|
||||||
{pageCount > 1 && (
|
|
||||||
<FormRow verticallyCentered centered>
|
|
||||||
<ReactPaginate
|
|
||||||
pageCount={pageCount}
|
|
||||||
pageRangeDisplayed={2}
|
|
||||||
previousLabel="‹"
|
|
||||||
nextLabel="›"
|
|
||||||
activeClassName="pagination__item--selected"
|
|
||||||
pageClassName="pagination__item"
|
|
||||||
previousClassName="pagination__item pagination__item--previous"
|
|
||||||
nextClassName="pagination__item pagination__item--next"
|
|
||||||
breakClassName="pagination__item pagination__item--break"
|
|
||||||
marginPagesDisplayed={2}
|
|
||||||
onPageChange={e => this.changePage(e.selected)}
|
|
||||||
forcePage={page}
|
|
||||||
initialPage={page}
|
|
||||||
containerClassName="pagination"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
className="paginate-channel"
|
|
||||||
onKeyUp={e => this.paginate(e)}
|
|
||||||
prefix={__('Go to page:')}
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
</FormRow>
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
|
||||||
) : (
|
|
||||||
<p className="card__subtitle">
|
|
||||||
{__('You have no saved history. Go')}{' '}
|
|
||||||
<Button button="link" label={__('explore')} onClick={() => navigate('/discover')} />{' '}
|
|
||||||
{__('the content available on LBRY!')}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as ACTIONS from 'constants/action_types';
|
||||||
const getCurrentPath = () => {
|
const getCurrentPath = () => {
|
||||||
const { hash } = document.location;
|
const { hash } = document.location;
|
||||||
if (hash !== '') return hash.replace(/^#/, '');
|
if (hash !== '') return hash.replace(/^#/, '');
|
||||||
return '/discover';
|
return '/user_history';
|
||||||
};
|
};
|
||||||
|
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { makeSelectClaimForUri } from 'lbry-redux';
|
import { makeSelectClaimForUri, selectClaimsByUri } from 'lbry-redux';
|
||||||
import { HISTORY_ITEMS_PER_PAGE } from 'constants/content';
|
import { HISTORY_ITEMS_PER_PAGE } from 'constants/content';
|
||||||
|
|
||||||
export const selectState = state => state.content || {};
|
export const selectState = state => state.content || {};
|
||||||
|
@ -47,9 +47,23 @@ export const selectHistoryPageCount = createSelector(selectState, state =>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const makeSelectHistoryForPage = page =>
|
export const makeSelectHistoryForPage = page =>
|
||||||
createSelector(selectState, state => {
|
createSelector(selectState, selectClaimsByUri, (state, claimsByUri) => {
|
||||||
const left = page * HISTORY_ITEMS_PER_PAGE;
|
const left = page * HISTORY_ITEMS_PER_PAGE;
|
||||||
return state.history.slice(left, left + HISTORY_ITEMS_PER_PAGE);
|
const historyItems = state.history.slice(left, left + HISTORY_ITEMS_PER_PAGE);
|
||||||
|
|
||||||
|
// See if we have the claim info for the uris in your history
|
||||||
|
// If not, it will need to be fetched in the component
|
||||||
|
return historyItems.map((historyItem) => {
|
||||||
|
const { uri, lastViewed } = historyItem;
|
||||||
|
const claimAtUri = claimsByUri[uri];
|
||||||
|
|
||||||
|
if (claimAtUri) {
|
||||||
|
return { lastViewed, uri, ...claimAtUri }
|
||||||
|
} else {
|
||||||
|
console.log("jsut returning item")
|
||||||
|
return historyItem;
|
||||||
|
}
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
export const makeSelectHistoryForUri = uri =>
|
export const makeSelectHistoryForUri = uri =>
|
||||||
|
|
|
@ -54,10 +54,10 @@ table.table,
|
||||||
tr {
|
tr {
|
||||||
border-bottom: var(--table-item-border);
|
border-bottom: var(--table-item-border);
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
&:nth-child(even):not(.odd) {
|
&:nth-child(even) {
|
||||||
background-color: var(--table-item-odd);
|
background-color: var(--table-item-odd);
|
||||||
}
|
}
|
||||||
&:nth-child(odd):not(.even) {
|
&:nth-child(odd) {
|
||||||
background-color: var(--table-item-even);
|
background-color: var(--table-item-even);
|
||||||
}
|
}
|
||||||
&.thead {
|
&.thead {
|
||||||
|
@ -107,3 +107,30 @@ table.table--transactions {
|
||||||
width: 15%;
|
width: 15%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.table--history {
|
||||||
|
margin-top: 0;
|
||||||
|
|
||||||
|
tbody {
|
||||||
|
tr {
|
||||||
|
&:nth-child(even),
|
||||||
|
&:nth-child(odd) {
|
||||||
|
background-color: var(--table-item-even);
|
||||||
|
|
||||||
|
&.history__selected {
|
||||||
|
color: red;
|
||||||
|
background-color: var(--table-item-odd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td:nth-of-type(2) {
|
||||||
|
/*Tourniquets text over 20VW*/
|
||||||
|
max-width: 20vw;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: var(--color-help);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue