mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-15 23:00:57 +00:00
change wikis list style (#6125)
This commit is contained in:
40
frontend/src/components/wiki-card-view/wiki-card-group.js
Normal file
40
frontend/src/components/wiki-card-view/wiki-card-group.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { gettext, username } from '../../utils/constants';
|
||||||
|
import WikiCardItem from './wiki-card-item';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
wikis: PropTypes.array.isRequired,
|
||||||
|
deleteWiki: PropTypes.func.isRequired,
|
||||||
|
owner: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
class WikiCardGroup extends Component {
|
||||||
|
render() {
|
||||||
|
let { wikis, owner } = this.props;
|
||||||
|
return (
|
||||||
|
<div className='wiki-card-group'>
|
||||||
|
<h4 className="sf-heading my-4">
|
||||||
|
<span className={`sf3-font nav-icon sf3-font-${username === owner ? 'mine' : 'department'}`} aria-hidden="true"></span>
|
||||||
|
{username === owner ? gettext('My Wikis') : wikis[0].owner_nickname}
|
||||||
|
</h4>
|
||||||
|
<div className='wiki-card-group-items'>
|
||||||
|
{wikis.map((wiki, index) => {
|
||||||
|
return (
|
||||||
|
<WikiCardItem
|
||||||
|
key={index}
|
||||||
|
wiki={wiki}
|
||||||
|
deleteWiki={this.props.deleteWiki}
|
||||||
|
owner={owner}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WikiCardGroup.propTypes = propTypes;
|
||||||
|
|
||||||
|
export default WikiCardGroup;
|
132
frontend/src/components/wiki-card-view/wiki-card-item.js
Normal file
132
frontend/src/components/wiki-card-view/wiki-card-item.js
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { siteRoot, gettext, appAvatarURL, username } from '../../utils/constants';
|
||||||
|
import ModalPortal from '../modal-portal';
|
||||||
|
import WikiDeleteDialog from '../dialog/wiki-delete-dialog';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
owner: PropTypes.string.isRequired,
|
||||||
|
wiki: PropTypes.object.isRequired,
|
||||||
|
deleteWiki: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
class WikiCardItem extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isShowDeleteDialog: false,
|
||||||
|
isItemMenuShow: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeleteToggle = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
this.setState({
|
||||||
|
isShowDeleteDialog: !this.state.isShowDeleteDialog,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onDeleteCancel = () => {
|
||||||
|
this.setState({
|
||||||
|
isShowDeleteDialog: !this.state.isShowDeleteDialog,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteWiki = () => {
|
||||||
|
let wiki = this.props.wiki;
|
||||||
|
this.props.deleteWiki(wiki);
|
||||||
|
this.setState({
|
||||||
|
isShowDeleteDialog: !this.state.isShowDeleteDialog,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
clickWikiCard = (link) => {
|
||||||
|
window.open(link);
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleDropDownMenu = () => {
|
||||||
|
this.setState({isItemMenuShow: !this.state.isItemMenuShow});
|
||||||
|
};
|
||||||
|
|
||||||
|
onClickDropdown = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
};
|
||||||
|
|
||||||
|
renderAvatar = () => {
|
||||||
|
const { wiki } = this.props;
|
||||||
|
// const userProfileURL = `${siteRoot}profile/${encodeURIComponent(wiki.owner)}/`;
|
||||||
|
return (
|
||||||
|
<div className="wiki-card-item-avatar-container">
|
||||||
|
<img src={appAvatarURL} className="avatar mr-1" alt={gettext('Avatar')} />
|
||||||
|
<span title={wiki.owner_nickname}>{wiki.owner_nickname}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
renderDept = () => {
|
||||||
|
const { wiki } = this.props;
|
||||||
|
return (
|
||||||
|
<div className="wiki-card-item-avatar-container">
|
||||||
|
<span className='sf3-font-department sf3-font nav-icon mr-1'></span>
|
||||||
|
<span title={wiki.owner_nickname}>{wiki.owner_nickname}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { owner, wiki } = this.props;
|
||||||
|
let isOldVersion = wiki.version !== 'v2';
|
||||||
|
let publishedUrl = `${siteRoot}published/${encodeURIComponent(wiki.slug)}/`;
|
||||||
|
let editUrl = `${siteRoot}wikis/${wiki.id}/`;
|
||||||
|
let wikiName = isOldVersion ? <>{wiki.name} (old version)</> : <>{wiki.name}</>;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="wiki-card-item" onClick={this.clickWikiCard.bind(this, isOldVersion ? publishedUrl : editUrl )}>
|
||||||
|
<div className="wiki-card-item-top">
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
<span className="sf3-font-wiki sf3-font" aria-hidden="true"></span>
|
||||||
|
<span className="wiki-card-item-name ml-2 text-truncate">{wikiName}</span>
|
||||||
|
</div>
|
||||||
|
<Dropdown isOpen={this.state.isItemMenuShow} toggle={this.toggleDropDownMenu} onClick={this.onClickDropdown}>
|
||||||
|
<DropdownToggle
|
||||||
|
tag="i"
|
||||||
|
role="button"
|
||||||
|
tabIndex="0"
|
||||||
|
className="sf-dropdown-toggle sf3-font-more sf3-font"
|
||||||
|
title={gettext('More operations')}
|
||||||
|
aria-label={gettext('More operations')}
|
||||||
|
data-toggle="dropdown"
|
||||||
|
aria-expanded={this.state.isItemMenuShow}
|
||||||
|
aria-haspopup={true}
|
||||||
|
style={{'minWidth': '0'}}
|
||||||
|
/>
|
||||||
|
<DropdownMenu right={true} className="dtable-dropdown-menu">
|
||||||
|
{/* <DropdownItem onClick={}>{gettext('Rename')}</DropdownItem> */}
|
||||||
|
<DropdownItem onClick={this.onDeleteToggle}>{gettext('Unpublish')}</DropdownItem>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
<div className="wiki-card-item-bottom">
|
||||||
|
{owner === username ? this.renderAvatar() : this.renderDept()}
|
||||||
|
<span className="wiki-item-updated-time">{moment(wiki.updated_at).fromNow()}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{this.state.isShowDeleteDialog &&
|
||||||
|
<ModalPortal>
|
||||||
|
<WikiDeleteDialog
|
||||||
|
toggleCancel={this.onDeleteCancel}
|
||||||
|
handleSubmit={this.deleteWiki}
|
||||||
|
/>
|
||||||
|
</ModalPortal>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WikiCardItem.propTypes = propTypes;
|
||||||
|
|
||||||
|
export default WikiCardItem;
|
93
frontend/src/components/wiki-card-view/wiki-card-view.css
Normal file
93
frontend/src/components/wiki-card-view/wiki-card-view.css
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
.wiki-card-group-items {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 32.5% 32.5% 32.5%;
|
||||||
|
gap: 16px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item {
|
||||||
|
height: 120px;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #EEEEEE;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item:hover {
|
||||||
|
border: 1px solid #DBDBDB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item .wiki-card-item-top,
|
||||||
|
.wiki-card-item .wiki-card-item-bottom {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item .wiki-item-updated-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item .wiki-card-item-top .sf3-font-wiki.sf3-font {
|
||||||
|
color: #FF8900;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item .wiki-card-item-top .wiki-card-item-name {
|
||||||
|
max-width: 250px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item .wiki-card-item-top .dropdown .sf-dropdown-toggle {
|
||||||
|
border: 1px solid #dbdbdb;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
opacity: 0;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item:hover .wiki-card-item-top .dropdown .sf-dropdown-toggle {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item:hover .wiki-card-item-top .dropdown .sf-dropdown-toggle:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item .wiki-card-item-avatar-container {
|
||||||
|
height: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #EEEEEE;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item .wiki-card-item-avatar-container .avatar {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item .wiki-card-item-avatar-container span {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wiki-card-item .wiki-card-item-avatar-container .sf3-font-department {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.wiki-card-group-items {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 100%;
|
||||||
|
}
|
||||||
|
.wiki-card-item .wiki-card-item-top .dropdown .sf-dropdown-toggle {
|
||||||
|
border: none;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
63
frontend/src/components/wiki-card-view/wiki-card-view.js
Normal file
63
frontend/src/components/wiki-card-view/wiki-card-view.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { username } from '../../utils/constants';
|
||||||
|
import WikiCardGroup from './wiki-card-group';
|
||||||
|
import './wiki-card-view.css';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
data: PropTypes.object.isRequired,
|
||||||
|
deleteWiki: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
class WikiCardView extends Component {
|
||||||
|
|
||||||
|
classifyWikis = (wikis) => {
|
||||||
|
let myWikis = [];
|
||||||
|
let department2WikisMap = {};
|
||||||
|
for (let i = 0; i < wikis.length; i++) {
|
||||||
|
if (wikis[i].owner === username) {
|
||||||
|
myWikis.push(wikis[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!department2WikisMap[wikis[i].owner]) {
|
||||||
|
department2WikisMap[wikis[i].owner] = [];
|
||||||
|
}
|
||||||
|
department2WikisMap[wikis[i].owner].push(wikis[i]);
|
||||||
|
}
|
||||||
|
return { department2WikisMap, myWikis };
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let { loading, errorMsg, wikis } = this.props.data;
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <span className="loading-icon loading-tip"></span>;
|
||||||
|
}
|
||||||
|
if (errorMsg) {
|
||||||
|
return <p className="error text-center">{errorMsg}</p>;
|
||||||
|
}
|
||||||
|
const { myWikis, department2WikisMap } = this.classifyWikis(wikis);
|
||||||
|
let wikiCardGroups = [];
|
||||||
|
wikiCardGroups.push(
|
||||||
|
<WikiCardGroup
|
||||||
|
deleteWiki={this.props.deleteWiki}
|
||||||
|
wikis={myWikis}
|
||||||
|
owner={username}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
for (let key in department2WikisMap) {
|
||||||
|
wikiCardGroups.push(
|
||||||
|
<WikiCardGroup
|
||||||
|
deleteWiki={this.props.deleteWiki}
|
||||||
|
wikis={department2WikisMap[key]}
|
||||||
|
owner={key}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return wikiCardGroups;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WikiCardView.propTypes = propTypes;
|
||||||
|
|
||||||
|
export default WikiCardView;
|
@@ -9,8 +9,8 @@ import ModalPortal from '../../components/modal-portal';
|
|||||||
import EmptyTip from '../../components/empty-tip';
|
import EmptyTip from '../../components/empty-tip';
|
||||||
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
||||||
import AddWikiDialog from '../../components/dialog/add-wiki-dialog';
|
import AddWikiDialog from '../../components/dialog/add-wiki-dialog';
|
||||||
import WikiListView from '../../components/wiki-list-view/wiki-list-view';
|
|
||||||
import wikiAPI from '../../utils/wiki-api';
|
import wikiAPI from '../../utils/wiki-api';
|
||||||
|
import WikiCardView from '../../components/wiki-card-view/wiki-card-view';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
onShowSidePanel: PropTypes.func.isRequired,
|
onShowSidePanel: PropTypes.func.isRequired,
|
||||||
@@ -156,22 +156,24 @@ class Wikis extends Component {
|
|||||||
<h3 className="sf-heading m-0">{gettext('Wikis')}</h3>
|
<h3 className="sf-heading m-0">{gettext('Wikis')}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="cur-view-content">
|
{(this.state.loading || this.state.wikis.length !== 0) &&
|
||||||
{(this.state.loading || this.state.wikis.length !== 0) &&
|
<div className="cur-view-content pb-4">
|
||||||
<WikiListView
|
<WikiCardView
|
||||||
data={this.state}
|
data={this.state}
|
||||||
deleteWiki={this.deleteWiki}
|
deleteWiki={this.deleteWiki}
|
||||||
/>
|
/>
|
||||||
}
|
</div>
|
||||||
{(!this.state.loading && this.state.wikis.length === 0) &&
|
}
|
||||||
|
{(!this.state.loading && this.state.wikis.length === 0) &&
|
||||||
|
<div className="cur-view-content">
|
||||||
<EmptyTip>
|
<EmptyTip>
|
||||||
<h2>{gettext('No Wikis')}</h2>
|
<h2>{gettext('No Wikis')}</h2>
|
||||||
<p>{gettext('You have not any wikis yet.')}</p>
|
<p>{gettext('You have not any wikis yet.')}</p>
|
||||||
<p>{gettext('A wiki can be accessed by anyone, not only users, via its URL.')}</p>
|
<p>{gettext('A wiki can be accessed by anyone, not only users, via its URL.')}</p>
|
||||||
<p>{gettext('You can add a wiki by clicking the "Add Wiki" button in the menu bar.')}</p>
|
<p>{gettext('You can add a wiki by clicking the "Add Wiki" button in the menu bar.')}</p>
|
||||||
</EmptyTip>
|
</EmptyTip>
|
||||||
}
|
</div>
|
||||||
</div>
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
Reference in New Issue
Block a user