mirror of https://github.com/sualko/cloud_bbb
parent
971df674ec
commit
f13f28afde
|
@ -0,0 +1,33 @@
|
|||
.bbb-selection-container {
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.bbb-selection {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid var(--color-border-dark);
|
||||
max-height: 88px;
|
||||
overflow: auto;
|
||||
box-shadow: 0 5px 10px -5px var(--color-box-shadow);
|
||||
z-index: 100;
|
||||
|
||||
li {
|
||||
color: var(--color-text-lighter);
|
||||
padding: 0 1em;
|
||||
line-height: 44px;
|
||||
|
||||
&.suggestion {
|
||||
color: var(--color-main-text);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { api, ShareWith, ShareType, ShareWithOption } from '../Common/Api';
|
||||
import './ShareWith.scss';
|
||||
import './ShareSelection.scss';
|
||||
|
||||
type Props = {
|
||||
selectShare: (selection: ShareWithOption) => void;
|
|
@ -35,39 +35,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.bbb-selection-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bbb-selection {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid var(--color-border-dark);
|
||||
max-height: 88px;
|
||||
overflow: auto;
|
||||
box-shadow: 0 5px 10px -5px var(--color-box-shadow);
|
||||
|
||||
li {
|
||||
color: var(--color-text-lighter);
|
||||
padding: 0 1em;
|
||||
line-height: 44px;
|
||||
|
||||
&.suggestion {
|
||||
color: var(--color-main-text);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bbb-form-shareWith {
|
||||
margin-top: -1.5em;
|
||||
}
|
||||
|
||||
.bbb-icon-unselected {
|
||||
opacity: 0.2 !important;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { api, ShareWith, ShareType, RoomShare, Room, Permission, ShareWithOption } from '../Common/Api';
|
||||
import React from 'react';
|
||||
import { api, ShareWith, ShareType, RoomShare, Room, Permission } from '../Common/Api';
|
||||
import './ShareWith.scss';
|
||||
import ShareSelection from '../Common/ShareSelection';
|
||||
|
||||
type Props = {
|
||||
room: Room;
|
||||
|
@ -10,12 +11,6 @@ type Props = {
|
|||
}
|
||||
|
||||
const ShareWith: React.FC<Props> = ({ room, permission, shares: allShares, setShares }) => {
|
||||
const [search, setSearch] = useState<string>('');
|
||||
const [hasFocus, setFocus] = useState<boolean>(false);
|
||||
const [showSearchResults, setShowSearchResults] = useState<boolean>(false);
|
||||
const [recommendations, setRecommendations] = useState<ShareWith>();
|
||||
const [searchResults, setSearchResults] = useState<ShareWith>();
|
||||
|
||||
const isOwner = room.userId === OC.currentUser;
|
||||
|
||||
const shares = (allShares && permission === Permission.Moderator) ?
|
||||
|
@ -24,32 +19,11 @@ const ShareWith: React.FC<Props> = ({ room, permission, shares: allShares, setSh
|
|||
const sharedUserIds = shares ? shares.filter(share => share.shareType === ShareType.User).map(share => share.shareWith) : [];
|
||||
const sharedGroupIds = shares ? shares.filter(share => share.shareType === ShareType.Group).map(share => share.shareWith) : [];
|
||||
|
||||
useEffect(() => {
|
||||
setSearchResults(undefined);
|
||||
const searchQuery = search;
|
||||
|
||||
api.searchShareWith(searchQuery).then(result => {
|
||||
if (searchQuery === search) {
|
||||
setSearchResults(result);
|
||||
}
|
||||
});
|
||||
}, [search]);
|
||||
|
||||
useEffect(() => {
|
||||
api.getRecommendedShareWith().then(result => setRecommendations(result));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => setShowSearchResults(hasFocus), 100);
|
||||
}, [hasFocus]);
|
||||
|
||||
async function addRoomShare(shareWith: string, shareType: number, displayName: string, permission: Permission) {
|
||||
const roomShare = await api.createRoomShare(room.id, shareType, shareWith, permission);
|
||||
|
||||
roomShare.shareWithDisplayName = displayName;
|
||||
|
||||
console.log('addRoomShare', allShares, roomShare);
|
||||
|
||||
const newShares = allShares ? [...allShares] : [];
|
||||
const index = newShares.findIndex(share => share.id === roomShare.id);
|
||||
|
||||
|
@ -59,10 +33,7 @@ const ShareWith: React.FC<Props> = ({ room, permission, shares: allShares, setSh
|
|||
newShares.push(roomShare);
|
||||
}
|
||||
|
||||
console.log('newroomshares', newShares);
|
||||
|
||||
setShares(newShares);
|
||||
setSearch('');
|
||||
}
|
||||
|
||||
async function deleteRoomShare(id: number) {
|
||||
|
@ -79,27 +50,12 @@ const ShareWith: React.FC<Props> = ({ room, permission, shares: allShares, setSh
|
|||
return addRoomShare(share.shareWith, share.shareType, share.shareWithDisplayName || share.shareWith, newPermission);
|
||||
}
|
||||
|
||||
function renderSearchResults(options: ShareWith|undefined) {
|
||||
const results = options ? [
|
||||
...options.users.filter(user => !sharedUserIds.includes(user.value.shareWith)),
|
||||
...options.groups.filter(group => !sharedGroupIds.includes(group.value.shareWith)),
|
||||
] : [];
|
||||
|
||||
const renderOption = (option: ShareWithOption) => {
|
||||
return (<li key={option.value.shareWith} className="suggestion" onClick={() => addRoomShare(option.value.shareWith, option.value.shareType, option.label, permission)}>
|
||||
{option.label}{option.value.shareType === ShareType.Group ? ` (${t('bbb', 'Group')})` : ''}
|
||||
</li>);
|
||||
};
|
||||
|
||||
return (
|
||||
<ul className="bbb-selection">
|
||||
{!options ?
|
||||
<li><span className="icon icon-loading-small icon-visible"></span> {t('bbb', 'Searching')}</li> :
|
||||
(
|
||||
(results.length === 0 && search) ? <li>{t('bbb', 'No matches')}</li> : results.map(renderOption)
|
||||
)}
|
||||
</ul>
|
||||
);
|
||||
function getAvatarUrl(userId: string) {
|
||||
return OC.generateUrl('/avatar/' + encodeURIComponent(userId) + '/' + 32, {
|
||||
user: userId,
|
||||
size: 32,
|
||||
requesttoken: OC.requestToken,
|
||||
});
|
||||
}
|
||||
|
||||
function renderShares(shares: RoomShare[]) {
|
||||
|
@ -116,11 +72,7 @@ const ShareWith: React.FC<Props> = ({ room, permission, shares: allShares, setSh
|
|||
return (
|
||||
<ul className="bbb-shareWith">
|
||||
{[ownShare, ...shares].map(share => {
|
||||
const avatarUrl = share.shareType === ShareType.User ? OC.generateUrl('/avatar/' + encodeURIComponent(share.shareWith) + '/' + 32, {
|
||||
user: share.shareWith,
|
||||
size: 32,
|
||||
requesttoken: OC.requestToken,
|
||||
}) : undefined;
|
||||
const avatarUrl = share.shareType === ShareType.User ? getAvatarUrl(share.shareWith) : undefined;
|
||||
const displayName = share.shareWithDisplayName || share.shareWith;
|
||||
|
||||
return (
|
||||
|
@ -136,7 +88,10 @@ const ShareWith: React.FC<Props> = ({ room, permission, shares: allShares, setSh
|
|||
</div>
|
||||
{(share.id > -1 && permission === Permission.Moderator && isOwner) && <div className="bbb-shareWith__item__action">
|
||||
<a className={`icon icon-shared icon-visible ${share.permission === Permission.Admin ? 'bbb-icon-selected' : 'bbb-icon-unselected'}`}
|
||||
onClick={ev => {ev.preventDefault(); toggleAdminShare(share);}}
|
||||
onClick={ev => {
|
||||
ev.preventDefault();
|
||||
toggleAdminShare(share);
|
||||
}}
|
||||
title={t('bbb', 'Share')} />
|
||||
</div>}
|
||||
{(share.id > -1 && isOwner) && <div className="bbb-shareWith__item__action">
|
||||
|
@ -157,17 +112,14 @@ const ShareWith: React.FC<Props> = ({ room, permission, shares: allShares, setSh
|
|||
<>
|
||||
{shares ? renderShares(shares) : loading}
|
||||
|
||||
<div className="bbb-selection-container">
|
||||
{isOwner ? <input
|
||||
type="text"
|
||||
value={search}
|
||||
onChange={ev => setSearch(ev.currentTarget.value)}
|
||||
onFocus={() => setFocus(true)}
|
||||
onBlur={() => setFocus(false)}
|
||||
placeholder={t('bbb', 'Name, group, ...')} /> :
|
||||
<em><span className="icon icon-details icon-visible"></span> {t('bbb', 'You are not allowed to change this option, because this room is shared with you.')}</em>}
|
||||
{showSearchResults && renderSearchResults((search && searchResults) ? searchResults : ((recommendations && !search) ? recommendations : undefined))}
|
||||
</div>
|
||||
{isOwner ?
|
||||
<ShareSelection
|
||||
selectShare={(shareOption) => addRoomShare(shareOption.value.shareWith, shareOption.value.shareType, shareOption.label, permission)}
|
||||
excluded={{userIds: sharedUserIds, groupIds: sharedGroupIds}}/> :
|
||||
<em>
|
||||
<span className="icon icon-details icon-visible"></span> {t('bbb', 'You are not allowed to change this option, because this room is shared with you.')}
|
||||
</em>
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
|
|||
import '../Manager/App.scss';
|
||||
import { api, Restriction, ShareType } from '../Common/Api';
|
||||
import RestrictionRow from './RestrictionRow';
|
||||
import ShareSelection from './ShareSelection';
|
||||
import ShareSelection from '../Common/ShareSelection';
|
||||
|
||||
type Props = {
|
||||
|
||||
|
@ -52,8 +52,7 @@ const App: React.FC<Props> = () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<div id="bbb-react-root"
|
||||
onClick={() => { /* @TODO hide edit inputs */ }}>
|
||||
<div id="bbb-react-root">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
.bbb-shareWith {
|
||||
margin: 1em 0;
|
||||
|
||||
&__item {
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-dark);
|
||||
}
|
||||
|
||||
.avatardiv {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
overflow: hidden;
|
||||
|
||||
.icon-group-white {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #a9a9a9;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
height: 44px;
|
||||
width: 44px;
|
||||
}
|
||||
|
||||
&__label {
|
||||
padding: 0 1em;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bbb-selection-container {
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.bbb-selection {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid var(--color-border-dark);
|
||||
max-height: 88px;
|
||||
overflow: auto;
|
||||
box-shadow: 0 5px 10px -5px var(--color-box-shadow);
|
||||
z-index: 100;
|
||||
|
||||
li {
|
||||
color: var(--color-text-lighter);
|
||||
padding: 0 1em;
|
||||
line-height: 44px;
|
||||
|
||||
&.suggestion {
|
||||
color: var(--color-main-text);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bbb-form-shareWith {
|
||||
margin-top: -1.5em;
|
||||
}
|
||||
|
||||
.bbb-icon-unselected {
|
||||
opacity: 0.2 !important;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue