1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-24 21:07:17 +00:00

System page list wiki (#7195)

* add All wikis

optimize

* update

* optimize

* select wiki info by sql

* optimize publish wiki

* update

* optimize ui

* update

* Update repos.js

* optimize varname

* Update wiki-card-item.js

---------

Co-authored-by: 孙永强 <11704063+s-yongqiang@user.noreply.gitee.com>
Co-authored-by: r350178982 <32759763+r350178982@users.noreply.github.com>
This commit is contained in:
awu0403
2024-12-25 15:43:07 +08:00
committed by GitHub
parent 9b8b7c9324
commit 4f8047f498
12 changed files with 416 additions and 41 deletions

View File

@@ -31,7 +31,7 @@ class DeleteRepoDialog extends Component {
}
componentDidMount() {
seafileAPI.getRepoFolderShareInfo(this.props.repo.repo_id).then((res) => {
seafileAPI.getRepoFolderShareInfo(this.props.repo.id).then((res) => {
this.setState({
sharedToUserCount: res.data['shared_user_emails'].length,
sharedToGroupCount: res.data['shared_group_ids'].length,

View File

@@ -13,6 +13,7 @@ const propTypes = {
wiki: PropTypes.object,
onPublish: PropTypes.func.isRequired,
toggleCancel: PropTypes.func.isRequired,
handleCustomUrl: PropTypes.func.isRequired
};
const DEFAULT_URL = serviceURL + '/wiki/publish/';
@@ -22,7 +23,7 @@ class PublishWikiDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
url: this.props.customUrl,
url: this.props.customUrlString,
errMessage: '',
isSubmitBtnActive: false,
};
@@ -62,6 +63,7 @@ class PublishWikiDialog extends React.Component {
let wiki_id = this.props.wiki.id;
wikiAPI.deletePublishWikiLink(wiki_id).then((res) => {
this.setState({ url: '' });
this.props.handleCustomUrl('');
toaster.success(gettext('Wiki custom URL deleted'));
}).catch((error) => {
if (error.response) {
@@ -128,7 +130,7 @@ class PublishWikiDialog extends React.Component {
{this.state.errMessage && <Alert color="danger" className="mt-2">{this.state.errMessage}</Alert>}
</ModalBody>
<ModalFooter>
{this.props.customUrl !== '' &&
{this.props.customUrlString !== '' &&
<Button color="secondary" onClick={this.deleteCustomUrl}>{gettext('Unpublish')}</Button>
}
<Button color="primary" onClick={this.handleSubmit} disabled={!this.state.isSubmitBtnActive}>{gettext('Submit')}</Button>

View File

@@ -36,7 +36,7 @@ class WikiCardItem extends Component {
isShowShareDialog: false,
isShowPublishDialog: false,
isShowConvertDialog: false,
customUrl: '',
customUrlString: this.props.wiki.public_url_suffix,
};
}
@@ -66,8 +66,15 @@ class WikiCardItem extends Component {
});
};
onPublishToggle = (e) => {
this.getPublishWikiLink();
onPublishToggle = () => {
this.setState({
isShowPublishDialog: !this.state.isShowPublishDialog,
});
};
handleCustomUrl = (url) => {
this.setState({
customUrlString: url,
});
};
onDeleteCancel = () => {
@@ -104,7 +111,7 @@ class WikiCardItem extends Component {
const publish_url = url.substring(urlIndex + '/publish/'.length);
wikiAPI.publishWiki(this.props.wiki.id, publish_url).then((res) => {
const { publish_url } = res.data;
this.setState({ customUrl: publish_url });
this.setState({ customUrlString: publish_url });
toaster.success(gettext('Wiki published'));
}).catch((error) => {
if (error.response) {
@@ -114,24 +121,6 @@ class WikiCardItem extends Component {
});
};
getPublishWikiLink = () => {
wikiAPI.getPublishWikiLink(this.props.wiki.id).then((res) => {
const { publish_url } = res.data;
this.setState({
customUrl: publish_url,
isShowPublishDialog: !this.state.isShowPublishDialog,
});
}).catch((error) => {
this.setState({
isShowPublishDialog: !this.state.isShowPublishDialog,
});
if (error.response) {
let errorMsg = error.response.data.error_msg;
toaster.danger(errorMsg);
}
});
};
clickWikiCard = (link) => {
window.open(link);
};
@@ -272,7 +261,7 @@ class WikiCardItem extends Component {
</div>
<div className="wiki-item-bottom">
{dayjs(wiki.updated_at).fromNow()}
{wiki.is_published && (<span>{gettext('Published')}</span>)}
{this.state.customUrlString && (<span>{gettext('Published')}</span>)}
</div>
</div>
{this.state.isShowDeleteDialog &&
@@ -341,9 +330,10 @@ class WikiCardItem extends Component {
<ModalPortal>
<PublishWikiDialog
toggleCancel={this.onPublishToggle}
handleCustomUrl={this.handleCustomUrl}
onPublish={this.publishWiki}
wiki={wiki}
customUrl={this.state.customUrl}
customUrlString={this.state.customUrlString}
/>
</ModalPortal>
}

View File

@@ -35,6 +35,7 @@ import UserLinks from './users/user-links';
import UserGroups from './users/user-groups';
import AllRepos from './repos/all-repos';
import AllWikis from './repos/all-wikis';
import SystemRepo from './repos/system-repo';
import TrashRepos from './repos/trash-repos';
import SearchRepos from './repos/search-repos';
@@ -225,6 +226,7 @@ class SysAdmin extends React.Component {
<MobileDevices path={siteRoot + 'sys/mobile-devices'} {...commonProps} />
<DeviceErrors path={siteRoot + 'sys/device-errors'} {...commonProps} />
<AllRepos path={siteRoot + 'sys/all-libraries'} {...commonProps} />
<AllWikis path={siteRoot + 'sys/all-wikis'} {...commonProps} />
<SystemRepo path={siteRoot + 'sys/system-library'} {...commonProps} />
<TrashRepos path={siteRoot + 'sys/trash-libraries'} {...commonProps} />
<SearchRepos path={siteRoot + 'sys/search-libraries'} {...commonProps} />

View File

@@ -0,0 +1,123 @@
import React, { Component, Fragment } from 'react';
import { navigate } from '@gatsbyjs/reach-router';
import { Utils } from '../../../utils/utils';
import { systemAdminAPI } from '../../../utils/system-admin-api';
import MainPanelTopbar from '../main-panel-topbar';
import ReposNav from './repos-nav';
import Content from './repos';
class AllWikis extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
errorMsg: '',
wikis: [],
pageInfo: {},
perPage: 100,
sortBy: '',
};
}
componentDidMount() {
let urlParams = (new URL(window.location)).searchParams;
const { currentPage = 1, perPage, sortBy } = this.state;
this.setState({
sortBy: urlParams.get('order_by') || sortBy,
perPage: parseInt(urlParams.get('per_page') || perPage),
currentPage: parseInt(urlParams.get('page') || currentPage)
}, () => {
this.getWikisByPage(this.state.currentPage);
});
}
getWikisByPage = (page) => {
const { perPage, sortBy } = this.state;
systemAdminAPI.sysAdminListAllWikis(page, perPage, sortBy).then((res) => {
this.setState({
loading: false,
wikis: res.data.wikis,
pageInfo: res.data.page_info
});
}).catch((error) => {
this.setState({
loading: false,
errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403
});
});
};
sortItems = (sortBy) => {
this.setState({
currentPage: 1,
sortBy: sortBy
}, () => {
let url = new URL(location.href);
let searchParams = new URLSearchParams(url.search);
const { currentPage, sortBy } = this.state;
searchParams.set('page', currentPage);
searchParams.set('order_by', sortBy);
url.search = searchParams.toString();
navigate(url.toString());
this.getWikisByPage(currentPage);
});
};
resetPerPage = (perPage) => {
this.setState({
perPage: perPage
}, () => {
this.getWikisByPage(1);
});
};
onDeleteWiki = (targetRepo) => {
let wikis = this.state.wikis.filter(repo => {
return repo.id != targetRepo.id;
});
this.setState({
wikis: wikis
});
};
onTransferWiki = (targetRepo) => {
let wikis = this.state.wikis.map((item) => {
return item.id == targetRepo.id ? targetRepo : item;
});
this.setState({
wikis: wikis
});
};
render() {
return (
<Fragment>
<MainPanelTopbar {...this.props} />
<div className="main-panel-center flex-row">
<div className="cur-view-container">
<ReposNav currentItem="wikis" />
<div className="cur-view-content">
<Content
loading={this.state.loading}
errorMsg={this.state.errorMsg}
items={this.state.wikis}
sortBy={this.state.sortBy}
sortItems={this.sortItems}
pageInfo={this.state.pageInfo}
curPerPage={this.state.perPage}
getListByPage={this.getWikisByPage}
resetPerPage={this.resetPerPage}
onDeleteRepo={this.onDeleteWiki}
onTransferRepo={this.onTransferWiki}
isWiki={true}
/>
</div>
</div>
</div>
</Fragment>
);
}
}
export default AllWikis;

View File

@@ -13,6 +13,7 @@ class Nav extends React.Component {
super(props);
this.navItems = [
{ name: 'all', urlPart: 'all-libraries', text: gettext('All') },
{ name: 'wikis', urlPart: 'all-wikis', text: gettext('Wikis') },
{ name: 'system', urlPart: 'system-library', text: gettext('System') },
{ name: 'trash', urlPart: 'trash-libraries', text: gettext('Trash') }
];

View File

@@ -83,9 +83,11 @@ class Content extends Component {
gettext('Files') / gettext('Size')
}
</th>
<th width="32%">ID</th>
<th width="18%">{gettext('Owner')}</th>
<th width="5%">{/* Operations*/}</th>
<Fragment>
<th width="32%">ID</th>
<th width="18%">{gettext('Owner')}</th>
<th width="5%">{/* Operations*/}</th>
</Fragment>
</tr>
</thead>
<tbody>
@@ -98,6 +100,7 @@ class Content extends Component {
onUnfreezedItem={this.onUnfreezedItem}
onDeleteRepo={this.props.onDeleteRepo}
onTransferRepo={this.props.onTransferRepo}
isWiki={this.props.isWiki}
/>);
})}
</tbody>
@@ -278,6 +281,9 @@ class Item extends Component {
getOperations = () => {
const { repo } = this.props;
if (this.props.isWiki) {
return ['Delete'];
}
let operations = ['Delete', 'Transfer'];
const index = repo.owner_email.indexOf('@seafile_group');
let isGroupOwnedRepo = index != -1;
@@ -309,12 +315,21 @@ class Item extends Component {
if (isGroupOwnedRepo) {
departmentID = repo.owner_email.substring(0, index);
}
let wikiName = '';
if (this.props.isWiki) {
wikiName = this.renderRepoName();
if (repo.is_published) {
wikiName = <><span>{wikiName}</span><a href={repo.public_url} target='_blank' rel='noreferrer'>(Published)</a></>;
}
}
return (
<Fragment>
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
<td>{this.renderRepoName()}</td>
{this.props.isWiki ?
<td>{wikiName}</td> :
<td>{this.renderRepoName()}</td>
}
<td>{`${repo.file_count} / ${Utils.bytesToSize(repo.size)}`}</td>
<td>{repo.id}</td>
<td>

View File

@@ -201,6 +201,18 @@ class SystemAdminAPI {
return this.req.get(url, { params: params });
}
sysAdminListAllWikis(page, perPage, orderBy) {
const url = this.server + '/api/v2.1/admin/wikis/';
let params = {
page: page,
per_page: perPage
};
if (orderBy) {
params.order_by = orderBy;
}
return this.req.get(url, { params: params });
}
sysAdminSearchRepos(name, page, perPage) {
const url = this.server + '/api/v2.1/admin/search-library/';
let params = {