mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-24 04:48:03 +00:00
@@ -28,9 +28,8 @@ class CreateDepartmentRepoDialog extends React.Component {
|
||||
let isValid = this.validateRepoName();
|
||||
if (isValid) {
|
||||
let repo = this.createRepo(this.state.repoName);
|
||||
this.props.onCreateRepo(repo);
|
||||
this.props.onCreateRepo(repo, 'department');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleKeyPress = (e) => {
|
||||
|
@@ -14,9 +14,10 @@ class GenerateShareLink extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
passwordVisible: false,
|
||||
showPasswordInput: false,
|
||||
isValidate: false,
|
||||
isShowPasswordInput: false,
|
||||
isPasswordVisible: false,
|
||||
isExpireChecked: false,
|
||||
password: '',
|
||||
passwdnew: '',
|
||||
expireDays: '',
|
||||
@@ -28,6 +29,7 @@ class GenerateShareLink extends React.Component {
|
||||
'can_edit': false,
|
||||
'can_download': true
|
||||
};
|
||||
this.isExpireDaysNoLimit = (parseInt(shareLinkExpireDaysMin) === 0 && parseInt(shareLinkExpireDaysMax) === 0);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -47,9 +49,9 @@ class GenerateShareLink extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
addPassword = () => {
|
||||
onPasswordInputChecked = () => {
|
||||
this.setState({
|
||||
showPasswordInput: !this.state.showPasswordInput,
|
||||
isShowPasswordInput: !this.state.isShowPasswordInput,
|
||||
password: '',
|
||||
passwdnew: '',
|
||||
errorInfo: ''
|
||||
@@ -58,7 +60,7 @@ class GenerateShareLink extends React.Component {
|
||||
|
||||
togglePasswordVisible = () => {
|
||||
this.setState({
|
||||
passwordVisible: !this.state.passwordVisible
|
||||
isPasswordVisible: !this.state.isPasswordVisible
|
||||
});
|
||||
}
|
||||
|
||||
@@ -66,20 +68,18 @@ class GenerateShareLink extends React.Component {
|
||||
let val = Math.random().toString(36).substr(5);
|
||||
this.setState({
|
||||
password: val,
|
||||
passwordnew: val
|
||||
passwdnew: val
|
||||
});
|
||||
}
|
||||
|
||||
inputPassword = (e) => {
|
||||
this.setState({
|
||||
password: e.target.value
|
||||
});
|
||||
let passwd = e.target.value.trim();
|
||||
this.setState({password: passwd});
|
||||
}
|
||||
|
||||
inputPasswordNew = (e) => {
|
||||
this.setState({
|
||||
passwordnew: e.target.value
|
||||
});
|
||||
let passwd = e.target.value.trim();
|
||||
this.setState({passwdnew: passwd});
|
||||
}
|
||||
|
||||
setPermission = (permission) => {
|
||||
@@ -97,35 +97,14 @@ class GenerateShareLink extends React.Component {
|
||||
}
|
||||
|
||||
generateShareLink = () => {
|
||||
let path = this.props.itemPath;
|
||||
let repoID = this.props.repoID;
|
||||
if (this.state.showPasswordInput && (this.state.password == '')) {
|
||||
this.setState({
|
||||
errorInfo: gettext('Please enter password')
|
||||
});
|
||||
}
|
||||
else if (this.state.showPasswordInput && (this.state.showPasswordInput && this.state.password.length < 8)) {
|
||||
this.setState({
|
||||
errorInfo: gettext('Password is too short')
|
||||
});
|
||||
}
|
||||
else if (this.state.showPasswordInput && (this.state.password !== this.state.passwordnew)) {
|
||||
this.setState({
|
||||
errorInfo: gettext('Passwords don\'t match')
|
||||
});
|
||||
}
|
||||
else if (this.state.expireDays === '') {
|
||||
this.setState({
|
||||
errorInfo: gettext('Please enter days')
|
||||
});
|
||||
} else if (!this.state.isValidate) {
|
||||
// errMessage had been setted
|
||||
return;
|
||||
} else {
|
||||
let isValid = this.validateParamsInput();
|
||||
if (isValid) {
|
||||
this.setState({errorInfo: ''});
|
||||
let { itemPath, repoID } = this.props;
|
||||
let { password, expireDays } = this.state;
|
||||
let permissions = this.permissions;
|
||||
permissions = JSON.stringify(permissions);
|
||||
seafileAPI.createShareLink(repoID, path, password, expireDays, permissions).then((res) => {
|
||||
seafileAPI.createShareLink(repoID, itemPath, password, expireDays, permissions).then((res) => {
|
||||
this.setState({
|
||||
link: res.data.link,
|
||||
token: res.data.token
|
||||
@@ -139,49 +118,102 @@ class GenerateShareLink extends React.Component {
|
||||
this.setState({
|
||||
link: '',
|
||||
token: '',
|
||||
showPasswordInput: false,
|
||||
password: '',
|
||||
passwordnew: '',
|
||||
isShowPasswordInput: false,
|
||||
expireDays: '',
|
||||
isExpireChecked: false,
|
||||
errorInfo: '',
|
||||
});
|
||||
this.permissions = {
|
||||
'can_edit': false,
|
||||
'can_download': true
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onExpireHandler = (e) => {
|
||||
let day = e.target.value;
|
||||
onExpireChecked = (e) => {
|
||||
this.setState({isExpireChecked: e.target.checked});
|
||||
}
|
||||
|
||||
onExpireDaysChanged = (e) => {
|
||||
let day = e.target.value.trim();
|
||||
this.setState({expireDays: day});
|
||||
}
|
||||
|
||||
validateParamsInput = () => {
|
||||
let { isShowPasswordInput , password, passwdnew, isExpireChecked, expireDays } = this.state;
|
||||
// validate password
|
||||
if (isShowPasswordInput) {
|
||||
if (password.length === 0) {
|
||||
this.setState({errorInfo: 'Please enter password'});
|
||||
return false;
|
||||
}
|
||||
if (password.length < 8) {
|
||||
this.setState({errorInfo: 'Password is too short'});
|
||||
return false;
|
||||
}
|
||||
if (password !== passwdnew) {
|
||||
this.setState({errorInfo: 'Passwords don\'t match'});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// validate days
|
||||
// no limit
|
||||
let reg = /^\d+$/;
|
||||
let flag = reg.test(day);
|
||||
if (!flag) {
|
||||
this.setState({
|
||||
isValidate: false,
|
||||
errorInfo: gettext('Please enter a non-negative integer'),
|
||||
expireDays: day,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
day = parseInt(day);
|
||||
if (this.isExpireDaysNoLimit) {
|
||||
if (isExpireChecked) {
|
||||
if (!expireDays) {
|
||||
this.setState({errorInfo: 'Please enter days'});
|
||||
return false;
|
||||
}
|
||||
let flag = reg.test(expireDays);
|
||||
if (!flag) {
|
||||
this.setState({errorInfo: 'Please enter a non-negative integer'});
|
||||
return false;
|
||||
}
|
||||
this.setState({expireDays: parseInt(expireDays)});
|
||||
}
|
||||
} else {
|
||||
if (!expireDays) {
|
||||
this.setState({errorInfo: 'Please enter days'});
|
||||
return false;
|
||||
}
|
||||
let flag = reg.test(expireDays);
|
||||
if (!flag) {
|
||||
this.setState({errorInfo: 'Please enter a non-negative integer'});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (day < shareLinkExpireDaysMin || day > shareLinkExpireDaysMax) {
|
||||
let errorMessage = gettext('Please enter a value between day1 and day2');
|
||||
errorMessage = errorMessage.replace('day1', shareLinkExpireDaysMin);
|
||||
errorMessage = errorMessage.replace('day2', shareLinkExpireDaysMax);
|
||||
this.setState({
|
||||
isValidate: false,
|
||||
errorInfo: errorMessage,
|
||||
expireDays: day
|
||||
});
|
||||
return;
|
||||
expireDays = parseInt(expireDays);
|
||||
let minDays = parseInt(shareLinkExpireDaysMin);
|
||||
let maxDays = parseInt(shareLinkExpireDaysMax);
|
||||
|
||||
if (minDays !== 0 && maxDays !== maxDays) {
|
||||
if (expireDays < minDays) {
|
||||
this.setState({errorInfo: 'Please enter valid days'});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (minDays === 0 && maxDays !== 0 ) {
|
||||
if (expireDays > maxDays) {
|
||||
this.setState({errorInfo: 'Please enter valid days'});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (minDays !== 0 && maxDays !== 0) {
|
||||
if (expireDays < minDays || expireDays < maxDays) {
|
||||
this.setState({errorInfo: 'Please enter valid days'});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.setState({expireDays: expireDays});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isValidate: true,
|
||||
errorInfo: '',
|
||||
expireDays: day
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -197,35 +229,48 @@ class GenerateShareLink extends React.Component {
|
||||
<Form className="generate-share-link">
|
||||
<FormGroup check>
|
||||
<Label check>
|
||||
<Input type="checkbox" onChange={this.addPassword}/>{' '}{gettext('Add password protection')}
|
||||
<Input type="checkbox" onChange={this.onPasswordInputChecked}/>{' '}{gettext('Add password protection')}
|
||||
</Label>
|
||||
</FormGroup>
|
||||
{this.state.showPasswordInput &&
|
||||
{this.state.isShowPasswordInput &&
|
||||
<FormGroup className="link-operation-content">
|
||||
<Label>{gettext('Password')}</Label><span className="tip"> ({gettext('at least 8 characters')}) </span>
|
||||
<InputGroup className="passwd">
|
||||
<Input type={this.state.passwordVisible ? 'text' : 'password'} value={this.state.password || ''} onChange={this.inputPassword}/>
|
||||
<Input type={this.state.isPasswordVisible ? 'text' : 'password'} value={this.state.password || ''} onChange={this.inputPassword}/>
|
||||
<InputGroupAddon addonType="append">
|
||||
<Button onClick={this.togglePasswordVisible}><i className={`link-operation-icon fas ${this.state.passwordVisible ? 'fa-eye': 'fa-eye-slash'}`}></i></Button>
|
||||
<Button onClick={this.togglePasswordVisible}><i className={`link-operation-icon fas ${this.state.isPasswordVisible ? 'fa-eye': 'fa-eye-slash'}`}></i></Button>
|
||||
<Button onClick={this.generatePassword}><i className="link-operation-icon fas fa-magic"></i></Button>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<Label>{gettext('Password again')}</Label>
|
||||
<Input className="passwd" type={this.state.passwordVisible ? 'text' : 'password'} value={this.state.passwordnew || ''} onChange={this.inputPasswordNew} />
|
||||
<Input className="passwd" type={this.state.isPasswordVisible ? 'text' : 'password'} value={this.state.passwdnew || ''} onChange={this.inputPasswordNew} />
|
||||
</FormGroup>
|
||||
}
|
||||
<FormGroup check>
|
||||
<Label check>
|
||||
<Input className="expire-checkbox" type="checkbox" checked readOnly/>{' '}{gettext('Add auto expiration')}
|
||||
<Input className="expire-input" type="text" value={this.state.expireDays} onChange={this.onExpireHandler}/> <span>{gettext('days')}</span>
|
||||
{parseInt(shareLinkExpireDaysMin) === 0 && parseInt(shareLinkExpireDaysMax) === 0 && (
|
||||
<span> ({gettext('no limit')})</span>
|
||||
)}
|
||||
{parseInt(shareLinkExpireDaysMax) !== 0 && (
|
||||
<span> ({shareLinkExpireDaysMin} - {shareLinkExpireDaysMax}{gettext('days')})</span>
|
||||
)}
|
||||
</Label>
|
||||
</FormGroup>
|
||||
{this.isExpireDaysNoLimit && (
|
||||
<FormGroup check>
|
||||
<Label check>
|
||||
<Input className="expire-checkbox" type="checkbox" onChange={this.onExpireChecked}/>{' '}{gettext('Add auto expiration')}
|
||||
<Input className="expire-input" type="text" value={this.state.expireDays} onChange={this.onExpireDaysChanged} readOnly={!this.state.isExpireChecked}/><span>{gettext('days')}</span>
|
||||
</Label>
|
||||
</FormGroup>
|
||||
)}
|
||||
{!this.isExpireDaysNoLimit && (
|
||||
<FormGroup check>
|
||||
<Label check>
|
||||
<Input className="expire-checkbox" type="checkbox" onChange={this.onExpireChecked} checked readOnly/>{' '}{gettext('Add auto expiration')}
|
||||
<Input className="expire-input" type="text" value={this.state.expireDays} onChange={this.onExpireDaysChanged} /> <span>{gettext('days')}</span>
|
||||
{(parseInt(shareLinkExpireDaysMin) !== 0 && parseInt(shareLinkExpireDaysMax) !== 0) && (
|
||||
<span> ({shareLinkExpireDaysMin} - {shareLinkExpireDaysMax}{' '}{gettext('days')})</span>
|
||||
)}
|
||||
{(parseInt(shareLinkExpireDaysMin) !== 0 && parseInt(shareLinkExpireDaysMax) === 0) && (
|
||||
<span> ({gettext('Greater than or equal to')} {shareLinkExpireDaysMin}{' '}{gettext('days')})</span>
|
||||
)}
|
||||
{(parseInt(shareLinkExpireDaysMin) === 0 && parseInt(shareLinkExpireDaysMax) !== 0) && (
|
||||
<span> ({gettext('Less than or equal to')} {shareLinkExpireDaysMax}{' '}{gettext('days')})</span>
|
||||
)}
|
||||
</Label>
|
||||
</FormGroup>
|
||||
)}
|
||||
<FormGroup check>
|
||||
<Label check>
|
||||
<Input type="checkbox" checked readOnly/>{' '}{gettext('Set permission')}
|
||||
@@ -241,7 +286,7 @@ class GenerateShareLink extends React.Component {
|
||||
<Input type="radio" name="radio1" onChange={this.setPermission('preview')} />{' '}{gettext('Preview only')}
|
||||
</Label>
|
||||
</FormGroup>
|
||||
<Label className="err-message">{this.state.errorInfo}</Label><br />
|
||||
<Label className="err-message">{gettext(this.state.errorInfo)}</Label><br />
|
||||
<Button onClick={this.generateShareLink}>{gettext('Generate')}</Button>
|
||||
</Form>
|
||||
);
|
||||
|
@@ -9,10 +9,11 @@ import GenerateUploadLink from './generate-upload-link';
|
||||
import '../../css/share-link-dialog.css';
|
||||
|
||||
const propTypes = {
|
||||
itemPath: PropTypes.string.isRequired,
|
||||
isGroupOwnedRepo: PropTypes.bool,
|
||||
itemType: PropTypes.string.isRequired, // there will be three choose: ['library', 'dir', 'file']
|
||||
itemName: PropTypes.string.isRequired,
|
||||
itemPath: PropTypes.string.isRequired,
|
||||
toggleDialog: PropTypes.func.isRequired,
|
||||
isDir: PropTypes.bool.isRequired,
|
||||
repoID: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
@@ -67,10 +68,10 @@ class ShareDialog extends React.Component {
|
||||
<GenerateUploadLink itemPath={this.props.itemPath} repoID={this.props.repoID} />
|
||||
</TabPane>
|
||||
<TabPane tabId="shareToUser">
|
||||
<ShareToUser itemPath={this.props.itemPath} repoID={this.props.repoID} />
|
||||
<ShareToUser isGroupOwnedRepo={this.props.isGroupOwnedRepo} itemPath={this.props.itemPath} repoID={this.props.repoID} />
|
||||
</TabPane>
|
||||
<TabPane tabId="shareToGroup">
|
||||
<ShareToGroup itemPath={this.props.itemPath} repoID={this.props.repoID} />
|
||||
<ShareToGroup isGroupOwnedRepo={this.props.isGroupOwnedRepo} itemPath={this.props.itemPath} repoID={this.props.repoID} />
|
||||
</TabPane>
|
||||
</TabContent>
|
||||
</div>
|
||||
@@ -79,14 +80,13 @@ class ShareDialog extends React.Component {
|
||||
}
|
||||
|
||||
renderFileContent = () => {
|
||||
let activeTab = this.state.activeTab;
|
||||
return (
|
||||
<Fragment>
|
||||
<div className="share-dialog-side">
|
||||
<Nav pills vertical>
|
||||
<NavItem>
|
||||
<NavLink
|
||||
className={activeTab === 'shareLink' ? 'active' : ''} onClick={() => {this.toggle.bind(this, 'shareLink');}}>
|
||||
className="active" onClick={() => {this.toggle.bind(this, 'shareLink');}}>
|
||||
{gettext('Share Link')}
|
||||
</NavLink>
|
||||
</NavItem>
|
||||
@@ -104,15 +104,14 @@ class ShareDialog extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let itemName = this.props.itemName;
|
||||
|
||||
let { itemType, itemName } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<Modal isOpen={true} style={{maxWidth: '720px'}} className="share-dialog">
|
||||
<ModalHeader toggle={this.props.toggleDialog}>Share <span className="sf-font" title={itemName}>{itemName}</span></ModalHeader>
|
||||
<ModalHeader toggle={this.props.toggleDialog}>{gettext('Share')} <span className="sf-font" title={itemName}>{itemName}</span></ModalHeader>
|
||||
<ModalBody className="share-dialog-content">
|
||||
{this.props.isDir && this.renderDirContent()}
|
||||
{!this.props.isDir && this.renderFileContent()}
|
||||
{(itemType === 'library' || itemType === 'dir') && this.renderDirContent()}
|
||||
{itemType === 'file' && this.renderFileContent()}
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
</div>
|
||||
|
@@ -8,6 +8,7 @@ import { Utils } from '../../utils/utils';
|
||||
import { seafileAPI } from '../../utils/seafile-api.js';
|
||||
|
||||
const propTypes = {
|
||||
isGroupOwnedRepo: PropTypes.bool,
|
||||
itemPath: PropTypes.string.isRequired,
|
||||
repoID: PropTypes.string.isRequired
|
||||
};
|
||||
@@ -26,9 +27,7 @@ class ShareToGroup extends React.Component {
|
||||
}
|
||||
|
||||
handleSelectChange = (option) => {
|
||||
this.setState({
|
||||
selectedOption: option,
|
||||
});
|
||||
this.setState({selectedOption: option});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -85,37 +84,76 @@ class ShareToGroup extends React.Component {
|
||||
let groups = [];
|
||||
let path = this.props.itemPath;
|
||||
let repoID = this.props.repoID;
|
||||
let isGroupOwnedRepo = this.props.isGroupOwnedRepo;
|
||||
if (this.state.selectedOption.length > 0 ) {
|
||||
for (let i = 0; i < this.state.selectedOption.length; i ++) {
|
||||
groups[i] = this.state.selectedOption[i].id;
|
||||
}
|
||||
}
|
||||
seafileAPI.shareFolder(repoID, path, 'group', this.state.permission, groups).then(res => {
|
||||
if (res.data.failed.length > 0) {
|
||||
let errorMsg = [];
|
||||
for (let i = 0 ; i < res.data.failed.length ; i++) {
|
||||
errorMsg[i] = res.data.failed[i];
|
||||
if (isGroupOwnedRepo) {
|
||||
seafileAPI.shareGroupOwnedRepoToGroup(repoID, this.state.permission, groups).then(res => {
|
||||
if (res.data.failed.length > 0) {
|
||||
let errorMsg = [];
|
||||
for (let i = 0 ; i < res.data.failed.length ; i++) {
|
||||
errorMsg[i] = res.data.failed[i];
|
||||
}
|
||||
this.setState({
|
||||
errorMsg: errorMsg
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
errorMsg: errorMsg
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.concat(res.data.success)
|
||||
// todo modify api
|
||||
let items = res.data.success.map(item => {
|
||||
let sharedItem = {
|
||||
'group_info': { 'id': item.group_id, 'name': item.group_name},
|
||||
'permission': item.permission,
|
||||
'share_type': 'group',
|
||||
};
|
||||
return sharedItem;
|
||||
});
|
||||
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.concat(items),
|
||||
selectedOption: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
seafileAPI.shareFolder(repoID, path, 'group', this.state.permission, groups).then(res => {
|
||||
if (res.data.failed.length > 0) {
|
||||
let errorMsg = [];
|
||||
for (let i = 0 ; i < res.data.failed.length ; i++) {
|
||||
errorMsg[i] = res.data.failed[i];
|
||||
}
|
||||
this.setState({
|
||||
errorMsg: errorMsg
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.concat(res.data.success),
|
||||
selectedOption: null,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
deleteShareItem = (e, groupID) => {
|
||||
e.preventDefault();
|
||||
let path = this.props.itemPath;
|
||||
let repoID = this.props.repoID;
|
||||
seafileAPI.deleteShareToGroupItem(repoID, path, 'group', groupID).then(() => {
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.filter(item => { return item.group_info.id !== groupID; })
|
||||
if (this.props.isGroupOwnedRepo) {
|
||||
seafileAPI.deleteGroupOwnedRepoSharedGroupItem(repoID, groupID).then(() => {
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.filter(item => { return item.group_info.id !== groupID; })
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
seafileAPI.deleteShareToGroupItem(repoID, path, 'group', groupID).then(() => {
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.filter(item => { return item.group_info.id !== groupID; })
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -135,6 +173,7 @@ class ShareToGroup extends React.Component {
|
||||
options={this.options}
|
||||
components={makeAnimated()}
|
||||
inputId={'react-select-2-input'}
|
||||
value={this.state.selectedOption}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
@@ -150,14 +189,16 @@ class ShareToGroup extends React.Component {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
{this.state.errorMsg.length > 0 &&
|
||||
this.state.errorMsg.map((item, index = 0, arr) => {
|
||||
return (
|
||||
<p className="error" key={index}>{this.state.errorMsg[index].group_name}
|
||||
{': '}{this.state.errorMsg[index].error_msg}</p>
|
||||
);
|
||||
})
|
||||
}
|
||||
<td colSpan={3}>
|
||||
{this.state.errorMsg.length > 0 &&
|
||||
this.state.errorMsg.map((item, index = 0, arr) => {
|
||||
return (
|
||||
<p className="error" key={index}>{this.state.errorMsg[index].group_name}
|
||||
{': '}{this.state.errorMsg[index].error_msg}</p>
|
||||
);
|
||||
})
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<GroupList items={this.state.sharedItems} deleteShareItem={this.deleteShareItem} />
|
||||
@@ -173,7 +214,7 @@ function GroupList(props) {
|
||||
<tr key={index}>
|
||||
<td>{item.group_info.name}</td>
|
||||
<td>{Utils.sharePerms[item.permission]}</td>
|
||||
<td><i onClick={(e) => {props.deleteShareItem(e, item.group_info.id);}} className="sf2-icon-delete" title="Delete"></i></td>
|
||||
<td><a href="#" onClick={(e) => {props.deleteShareItem(e, item.group_info.id);}} className="sf2-icon-x3 sf2-x op-icon" title={gettext('Delete')}></a></td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
@@ -7,6 +7,7 @@ import { Button, Input } from 'reactstrap';
|
||||
import { seafileAPI } from '../../utils/seafile-api.js';
|
||||
|
||||
const propTypes = {
|
||||
isGroupOwnedRepo: PropTypes.bool,
|
||||
itemPath: PropTypes.string.isRequired,
|
||||
repoID: PropTypes.string.isRequired
|
||||
};
|
||||
@@ -92,29 +93,64 @@ class ShareToUser extends React.Component {
|
||||
users[i] = this.state.selectedOption[i].email;
|
||||
}
|
||||
}
|
||||
seafileAPI.shareFolder(repoID, path, 'user', this.state.permission, users).then(res => {
|
||||
if (res.data.failed.length > 0) {
|
||||
let errorMsg = [];
|
||||
for (let i = 0 ; i < res.data.failed.length ; i++) {
|
||||
errorMsg[i] = res.data.failed[i];
|
||||
if (this.props.isGroupOwnedRepo) {
|
||||
seafileAPI.shareGroupOwnedRepoToUser(repoID, this.state.permission, users).then(res => {
|
||||
if (res.data.failed.length > 0) {
|
||||
let errorMsg = [];
|
||||
for (let i = 0 ; i < res.data.failed.length ; i++) {
|
||||
errorMsg[i] = res.data.failed[i];
|
||||
}
|
||||
this.setState({errorMsg: errorMsg});
|
||||
}
|
||||
this.setState({errorMsg: errorMsg});
|
||||
}
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.concat(res.data.success)
|
||||
// todo modify api
|
||||
|
||||
let items = res.data.success.map(item => {
|
||||
let sharedItem = {
|
||||
'user_info': { 'nickname': item.user_name, 'name': item.user_email},
|
||||
'permission': item.permission,
|
||||
'share_type': 'user',
|
||||
};
|
||||
return sharedItem;
|
||||
});
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.concat(items),
|
||||
selectedOption: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
seafileAPI.shareFolder(repoID, path, 'user', this.state.permission, users).then(res => {
|
||||
if (res.data.failed.length > 0) {
|
||||
let errorMsg = [];
|
||||
for (let i = 0 ; i < res.data.failed.length ; i++) {
|
||||
errorMsg[i] = res.data.failed[i];
|
||||
}
|
||||
this.setState({errorMsg: errorMsg});
|
||||
}
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.concat(res.data.success),
|
||||
selectedOption: null,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
deleteShareItem = (e, username) => {
|
||||
e.preventDefault();
|
||||
let path = this.props.itemPath;
|
||||
let repoID = this.props.repoID;
|
||||
seafileAPI.deleteShareToUserItem(repoID, path, 'user', username).then(res => {
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.filter( item => { return item.user_info.name !== username; })
|
||||
if (this.props.isGroupOwnedRepo) {
|
||||
seafileAPI.deleteGroupOwnedRepoSharedUserItem(repoID, username).then(res => {
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.filter( item => { return item.user_info.name !== username; })
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
seafileAPI.deleteShareToUserItem(repoID, path, 'user', username).then(res => {
|
||||
this.setState({
|
||||
sharedItems: this.state.sharedItems.filter( item => { return item.user_info.name !== username; })
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -130,12 +166,16 @@ class ShareToUser extends React.Component {
|
||||
<tr>
|
||||
<td>
|
||||
<AsyncSelect
|
||||
className='reviewer-select' isMulti isFocused
|
||||
loadOptions={this.loadOptions}
|
||||
placeholder={gettext('Please enter 1 or more character')}
|
||||
onChange={this.handleSelectChange}
|
||||
isClearable classNamePrefix
|
||||
inputId={'react-select-1-input'}
|
||||
className='reviewer-select'
|
||||
placeholder={gettext('Please enter 1 or more character')}
|
||||
loadOptions={this.loadOptions}
|
||||
onChange={this.handleSelectChange}
|
||||
value={this.state.selectedOption}
|
||||
isMulti
|
||||
isFocused
|
||||
isClearable
|
||||
classNamePrefix
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
@@ -152,14 +192,16 @@ class ShareToUser extends React.Component {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
{this.state.errorMsg.length > 0 &&
|
||||
this.state.errorMsg.map((item, index = 0, arr) => {
|
||||
return (
|
||||
<p className="error" key={index}>{this.state.errorMsg[index].email}
|
||||
{': '}{this.state.errorMsg[index].error_msg}</p>
|
||||
);
|
||||
})
|
||||
}
|
||||
<td colSpan={3}>
|
||||
{this.state.errorMsg.length > 0 &&
|
||||
this.state.errorMsg.map((item, index = 0, arr) => {
|
||||
return (
|
||||
<p className="error" key={index}>{this.state.errorMsg[index].email}
|
||||
{': '}{this.state.errorMsg[index].error_msg}</p>
|
||||
);
|
||||
})
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<UserList items={sharedItems} deleteShareItem={this.deleteShareItem} />
|
||||
@@ -175,7 +217,7 @@ function UserList(props) {
|
||||
<tr key={index}>
|
||||
<td>{item.user_info.nickname}</td>
|
||||
<td>{Utils.sharePerms[item.permission]}</td>
|
||||
<td><i onClick={(e) => {props.deleteShareItem(e, item.user_info.name);}} className="sf2-icon-delete" title="Delete"></i></td>
|
||||
<td><a href="#" onClick={(e) => {props.deleteShareItem(e, item.user_info.name);}} className="sf2-icon-x3 sf2-x op-icon" title={gettext('Delete')}></a></td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
Reference in New Issue
Block a user