1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-13 22:01:06 +00:00

feat: add new page (#6160)

* feat: add new page

* rename duplicated page

* feat: wiki add new page

---------

Co-authored-by: ‘JoinTyang’ <yangtong1009@163.com>
This commit is contained in:
Libra
2024-06-05 13:52:33 +08:00
committed by GitHub
parent e25512a20a
commit 530647b4e1
11 changed files with 83 additions and 16 deletions

View File

@@ -3,18 +3,29 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
background-color: #F7F7F5;; background-color: #F7F7F5;
border-right: 1px solid #F1F1EF; border-right: 1px solid #F1F1EF;
} }
.wiki2-side-panel .wiki2-side-panel-top { .wiki2-side-panel .wiki2-side-panel-top {
padding: 8px 20px; padding: 8px 20px;
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
flex-shrink: 0; flex-shrink: 0;
height: 44px; height: 44px;
} }
.wiki2-side-panel .wiki2-side-panel-top .add-new-page {
padding: 0 4px;
cursor: pointer;
border-radius: 4px;
}
.wiki2-side-panel .wiki2-side-panel-top .add-new-page:hover {
background-color: #DFDFDD;
}
.wiki2-side-panel .wiki2-side-nav { .wiki2-side-panel .wiki2-side-nav {
flex: auto; flex: auto;
display: flex; display: flex;

View File

@@ -1,6 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import deepCopy from 'deep-copy'; import deepCopy from 'deep-copy';
import { UncontrolledTooltip } from 'reactstrap';
import { gettext, isWiki2, wikiId } from '../../utils/constants'; import { gettext, isWiki2, wikiId } from '../../utils/constants';
import toaster from '../../components/toast'; import toaster from '../../components/toast';
import Loading from '../../components/loading'; import Loading from '../../components/loading';
@@ -14,6 +15,7 @@ import Folder from './models/folder';
import Page from './models/page'; import Page from './models/page';
import wikiAPI from '../../utils/wiki-api'; import wikiAPI from '../../utils/wiki-api';
import { FOLDER } from './constant'; import { FOLDER } from './constant';
import { Utils } from '../../utils/utils';
import './side-panel.css'; import './side-panel.css';
@@ -339,12 +341,38 @@ class SidePanel extends Component {
); );
}; };
handleAddNewPage = () => {
const pageName = 'Untitled'; // default page name
const voidFn = () => void 0;
wikiAPI.createWiki2Page(wikiId, pageName).then(res => {
const { obj_name, parent_dir, doc_uuid,page_name } = res.data;
this.onAddNewPage({
name: page_name,
icon: '',
path: parent_dir === '/' ? `/${obj_name}` : `${parent_dir}/${obj_name}`,
docUuid: doc_uuid,
successCallback: voidFn,
errorCallback: voidFn,
});
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
this.onError();
});
};
render() { render() {
const { isLoading, config } = this.props; const { isLoading, config } = this.props;
return ( return (
<div className={`wiki2-side-panel${this.props.closeSideBar ? '' : ' left-zero'}`}> <div className={`wiki2-side-panel${this.props.closeSideBar ? '' : ' left-zero'}`}>
<div className="wiki2-side-panel-top"> <div className="wiki2-side-panel-top">
<h4 className="text-truncate ml-0 mb-0" title={repoName}>{repoName}</h4> <h4 className="text-truncate ml-0 mb-0" title={repoName}>{repoName}</h4>
<div id='wiki-add-new-page' className='add-new-page' onClick={this.handleAddNewPage}>
<i className='sf3-font sf3-font-new-page'></i>
</div>
<UncontrolledTooltip target="wiki-add-new-page">
{gettext('New page')}
</UncontrolledTooltip>
</div> </div>
<div className="wiki2-side-nav"> <div className="wiki2-side-nav">
{isLoading ? <Loading /> : (isObjectNotEmpty(config) ? this.renderFolderView() : this.renderNoFolder())} {isLoading ? <Loading /> : (isObjectNotEmpty(config) ? this.renderFolderView() : this.renderNoFolder())}

View File

@@ -1,11 +1,11 @@
@font-face { @font-face {
font-family: "sf3-font"; /* Project id 1230969 */ font-family: "sf3-font"; /* Project id 1230969 */
src: url('iconfont.eot?t=1716779999367'); /* IE9 */ src: url('iconfont.eot?t=1716950761276'); /* IE9 */
src: url('iconfont.eot?t=1716779999367#iefix') format('embedded-opentype'), /* IE6-IE8 */ src: url('iconfont.eot?t=1716950761276#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('iconfont.woff2?t=1716779999367') format('woff2'), url('iconfont.woff2?t=1716950761276') format('woff2'),
url('iconfont.woff?t=1716779999367') format('woff'), url('iconfont.woff?t=1716950761276') format('woff'),
url('iconfont.ttf?t=1716779999367') format('truetype'), url('iconfont.ttf?t=1716950761276') format('truetype'),
url('iconfont.svg?t=1716779999367#sf3-font') format('svg'); url('iconfont.svg?t=1716950761276#sf3-font') format('svg');
} }
.sf3-font { .sf3-font {
@@ -16,6 +16,10 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.sf3-font-new-page:before {
content: "\e823";
}
.sf3-font-upload-files:before { .sf3-font-upload-files:before {
content: "\e821"; content: "\e821";
} }

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -14,6 +14,8 @@
/> />
<missing-glyph /> <missing-glyph />
<glyph glyph-name="new-page" unicode="&#59427;" d="M560 864c19.2 0 48-16 48-48S579.2 768 560 768H160c-19.2 0-32-12.8-32-32v-704c0-19.2 12.8-32 32-32h704c19.2 0 32 12.8 32 32V432c0 16 6.4 48 48 48s48-32 48-48V0c0-54.4-41.6-96-96-96H128c-54.4 0-96 41.6-96 96V768c0 54.4 41.6 96 96 96h432z m179.2-124.8l140.8-147.2-348.8-348.8c-12.8-12.8-28.8-22.4-44.8-28.8-80-28.8-124.8-44.8-134.4-44.8-12.8 0-25.6 0-32 6.4-9.6 6.4-9.6 22.4-6.4 32 0 6.4 12.8 44.8 32 118.4 6.4 22.4 19.2 41.6 35.2 57.6L739.2 739.2z m92.8 96C870.4 873.6 934.4 870.4 969.6 832c38.4-41.6 38.4-105.6 0-147.2l-38.4-38.4-144 140.8L832 835.2z" horiz-adv-x="1024" />
<glyph glyph-name="upload-files" unicode="&#59425;" d="M160 160v-160h704v160h96v-192c0-35.2-25.6-60.8-57.6-64H128c-35.2 0-64 28.8-64 64v192h96zM518.4 864l278.4-268.8-80-76.8-156.8 150.4v-585.6h-96V656L320 518.4 240 595.2 518.4 864z" horiz-adv-x="1024" /> <glyph glyph-name="upload-files" unicode="&#59425;" d="M160 160v-160h704v160h96v-192c0-35.2-25.6-60.8-57.6-64H128c-35.2 0-64 28.8-64 64v192h96zM518.4 864l278.4-268.8-80-76.8-156.8 150.4v-585.6h-96V656L320 518.4 240 595.2 518.4 864z" horiz-adv-x="1024" />
<glyph glyph-name="share" unicode="&#59424;" d="M800 832c-70.4 0-128-54.4-128-128s57.6-128 128-128 128 54.4 128 128-57.6 128-128 128zM224 512c-70.4 0-128-54.4-128-128s57.6-128 128-128 128 54.4 128 128-57.6 128-128 128z m576-320c-70.4 0-128-54.4-128-128s57.6-128 128-128 128 54.4 128 128-60.8 128-128 128z m-425.6 307.2l217.6 134.4 48-83.2-217.6-134.4-48 83.2z m60.8-169.6l220.8-131.2-48-80-220.8 131.2 48 80z" horiz-adv-x="1024" /> <glyph glyph-name="share" unicode="&#59424;" d="M800 832c-70.4 0-128-54.4-128-128s57.6-128 128-128 128 54.4 128 128-57.6 128-128 128zM224 512c-70.4 0-128-54.4-128-128s57.6-128 128-128 128 54.4 128 128-57.6 128-128 128z m576-320c-70.4 0-128-54.4-128-128s57.6-128 128-128 128 54.4 128 128-60.8 128-128 128z m-425.6 307.2l217.6 134.4 48-83.2-217.6-134.4-48 83.2z m60.8-169.6l220.8-131.2-48-80-220.8 131.2 48 80z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -24,9 +24,9 @@ from seahub.api2.utils import api_error, to_python_boolean
from seahub.wiki2.models import Wiki2 as Wiki from seahub.wiki2.models import Wiki2 as Wiki
from seahub.wiki2.utils import is_valid_wiki_name, can_edit_wiki, get_wiki_dirs_by_path, \ from seahub.wiki2.utils import is_valid_wiki_name, can_edit_wiki, get_wiki_dirs_by_path, \
get_wiki_config, WIKI_PAGES_DIR, WIKI_CONFIG_PATH, WIKI_CONFIG_FILE_NAME, is_group_wiki, \ get_wiki_config, WIKI_PAGES_DIR, WIKI_CONFIG_PATH, WIKI_CONFIG_FILE_NAME, is_group_wiki, \
check_wiki_admin_permission, check_wiki_permission check_wiki_admin_permission, check_wiki_permission, get_page_ids_in_folder
from seahub.utils import is_org_context, get_user_repos, gen_inner_file_get_url, gen_file_upload_url, \ from seahub.utils import is_org_context, get_user_repos, gen_inner_file_get_url, gen_file_upload_url, \
normalize_dir_path, is_pro_version, check_filename_with_rename, is_valid_dirent_name normalize_dir_path, is_pro_version, check_filename_with_rename, is_valid_dirent_name, get_no_duplicate_obj_name
from seahub.views import check_folder_permission from seahub.views import check_folder_permission
from seahub.views.file import send_file_access_msg from seahub.views.file import send_file_access_msg
from seahub.base.templatetags.seahub_tags import email2nickname from seahub.base.templatetags.seahub_tags import email2nickname
@@ -424,19 +424,29 @@ class Wiki2PagesView(APIView):
error_msg = 'Library %s not found.' % repo_id error_msg = 'Library %s not found.' % repo_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg) return api_error(status.HTTP_404_NOT_FOUND, error_msg)
sdoc_uuid = uuid.uuid4() folder_id = request.data.get('folder_id', None)
file_name = page_name + '.sdoc' wiki_config = get_wiki_config(repo_id, request.user.username)
parent_dir = os.path.join(WIKI_PAGES_DIR, str(sdoc_uuid))
path = os.path.join(parent_dir, file_name)
navigation = wiki_config.get('navigation')
if not folder_id:
page_ids = {element.get('id') for element in navigation if element.get('type') != 'folder'}
else:
page_ids = get_page_ids_in_folder(navigation, folder_id)
pages = wiki_config.get('pages', [])
exist_page_names = [page.get('name') for page in pages if page.get('id') in page_ids]
page_name = get_no_duplicate_obj_name(page_name, exist_page_names)
sdoc_uuid = uuid.uuid4()
new_file_name = page_name + '.sdoc'
parent_dir = os.path.join(WIKI_PAGES_DIR, str(sdoc_uuid))
path = os.path.join(parent_dir, new_file_name)
seafile_api.mkdir_with_parents(repo_id, '/', parent_dir.strip('/'), request.user.username) seafile_api.mkdir_with_parents(repo_id, '/', parent_dir.strip('/'), request.user.username)
new_file_name = check_filename_with_rename(repo_id, parent_dir, file_name)
# create new empty file # create new empty file
if not is_valid_dirent_name(new_file_name): if not is_valid_dirent_name(new_file_name):
return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.')
new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name)
try: try:
seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, request.user.username) seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, request.user.username)
except Exception as e: except Exception as e:
@@ -451,6 +461,7 @@ class Wiki2PagesView(APIView):
new_file_path = posixpath.join(parent_dir, new_file_name) new_file_path = posixpath.join(parent_dir, new_file_name)
file_info = self.get_file_info(repo_id, new_file_path) file_info = self.get_file_info(repo_id, new_file_path)
file_info['doc_uuid'] = sdoc_uuid file_info['doc_uuid'] = sdoc_uuid
file_info['page_name'] = page_name
filename = os.path.basename(path) filename = os.path.basename(path)
try: try:

View File

@@ -88,3 +88,14 @@ def check_wiki_permission(wiki, username):
if username == wiki.owner: if username == wiki.owner:
return True return True
return False return False
def get_page_ids_in_folder(navigation, folder_id):
for directory in navigation:
if directory.get('type') == 'folder' and directory.get('id') == folder_id:
children = directory.get('children', [])
page_ids = {child.get('id') for child in children if child.get('type') == 'page'}
return page_ids
elif directory.get('type') == 'folder':
navigation = directory.get('children', [])
return get_page_ids_in_folder(navigation, folder_id)