aboutsummaryrefslogtreecommitdiff
path: root/src/client/views
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views')
-rw-r--r--src/client/views/DocumentDecorations.tsx60
-rw-r--r--src/client/views/PropertiesView.scss7
-rw-r--r--src/client/views/PropertiesView.tsx124
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx18
4 files changed, 135 insertions, 74 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index b2b18b245..3e0a1f7a4 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -6,12 +6,12 @@ import { action, computed, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { FaUndo } from 'react-icons/fa';
import { DateField } from '../../fields/DateField';
-import { AclAdmin, AclEdit, DataSym, Doc, DocListCast, Field, HeightSym, WidthSym } from '../../fields/Doc';
+import { AclAdmin, AclAugment, AclEdit, DataSym, Doc, DocListCast, Field, HeightSym, WidthSym } from '../../fields/Doc';
import { Document } from '../../fields/documentSchemas';
import { InkField } from '../../fields/InkField';
import { ScriptField } from '../../fields/ScriptField';
import { Cast, NumCast, StrCast } from '../../fields/Types';
-import { GetEffectiveAcl, SharingPermissions } from '../../fields/util';
+import { GetEffectiveAcl, SharingPermissions, normalizeEmail } from '../../fields/util';
import { emptyFunction, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils';
import { Docs } from '../documents/Documents';
import { DocumentType } from '../documents/DocumentTypes';
@@ -157,27 +157,35 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
};
@action onContainerDown = (e: React.PointerEvent): void => {
- setupMoveUpEvents(
- this,
- e,
- e => this.onBackgroundMove(true, e),
- e => {},
- emptyFunction
- );
+ const first = SelectionManager.Views()[0];
+ const effectiveAcl = GetEffectiveAcl(first.rootDoc)
+ if (effectiveAcl==AclAdmin || effectiveAcl==AclEdit || effectiveAcl==AclAugment){
+ setupMoveUpEvents(
+ this,
+ e,
+ e => this.onBackgroundMove(true, e),
+ e => {},
+ emptyFunction
+ );
+ }
};
@action onTitleDown = (e: React.PointerEvent): void => {
- setupMoveUpEvents(
- this,
- e,
- e => this.onBackgroundMove(true, e),
- e => {},
- action(e => {
- !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString);
- this._editingTitle = true;
- this._keyinput.current && setTimeout(this._keyinput.current.focus);
- })
- );
+ const first = SelectionManager.Views()[0];
+ const effectiveAcl = GetEffectiveAcl(first.rootDoc)
+ if (effectiveAcl==AclAdmin || effectiveAcl==AclEdit || effectiveAcl==AclAugment){
+ setupMoveUpEvents(
+ this,
+ e,
+ e => this.onBackgroundMove(true, e),
+ e => {},
+ action(e => {
+ !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString);
+ this._editingTitle = true;
+ this._keyinput.current && setTimeout(this._keyinput.current.focus);
+ })
+ );
+ }
};
onBackgroundDown = (e: React.PointerEvent) => setupMoveUpEvents(this, e, e => this.onBackgroundMove(false, e), emptyFunction, emptyFunction);
@@ -485,6 +493,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
onPointerMove = (e: PointerEvent, down: number[], move: number[]): boolean => {
const first = SelectionManager.Views()[0];
+ const effectiveAcl = GetEffectiveAcl(first.rootDoc)
+ if (!(effectiveAcl==AclAdmin || effectiveAcl==AclEdit || effectiveAcl==AclAugment)) return false;
if (!first) return false;
let thisPt = { x: e.clientX - this._offX, y: e.clientY - this._offY };
var fixedAspect = Doc.NativeAspect(first.layoutDoc);
@@ -737,7 +747,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
}
// sharing
- const docShareMode = seldocview.rootDoc["acl-Public"];
+ const docShareMode = Doc.GetProto(seldocview.rootDoc)["acl-Public"];
const shareMode = StrCast(docShareMode);
var shareSymbolIcon = null;
switch(shareMode){
@@ -781,10 +791,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
seldocview.props.hideDeleteButton ||
seldocview.rootDoc.hideDeleteButton ||
SelectionManager.Views().some(docView => {
- const collectionAcl = docView.props.ContainingCollectionView ? GetEffectiveAcl(docView.props.ContainingCollectionDoc?.[DataSym]) : AclEdit;
- return docView.rootDoc.stayInCollection || (collectionAcl !== AclAdmin && collectionAcl !== AclEdit && GetEffectiveAcl(docView.rootDoc) !== AclAdmin);
+ // const collectionAcl = docView.props.ContainingCollectionView ? GetEffectiveAcl(docView.props.ContainingCollectionDoc?.[DataSym]) : AclEdit;
+ // return docView.rootDoc.stayInCollection || (collectionAcl !== AclAdmin && collectionAcl !== AclEdit && GetEffectiveAcl(docView.rootDoc) !== AclAdmin);
+ const effectiveAcl = GetEffectiveAcl(Doc.GetProto(seldocview.rootDoc))
+ return docView.rootDoc.stayInCollection || (effectiveAcl !== AclAdmin && effectiveAcl !== AclEdit && GetEffectiveAcl(docView.rootDoc) !== AclAdmin);
});
-
const topBtn = (key: string, icon: string, pointerDown: undefined | ((e: React.PointerEvent) => void), click: undefined | ((e: any) => void), title: string) => (
<Tooltip key={key} title={<div className="dash-tooltip">{title}</div>} placement="top">
<div
@@ -852,7 +863,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
<div className={'documentDecorations-share'}>
<div className={`documentDecorations-share${shareMode}`}>
<span>{shareSymbolIcon + " " + shareMode}</span>
- {/* <span>{shareMode}</span> */}
</div>
</div> ) : (<div/>
);
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index 3edc7fea8..50bf6ce74 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -384,17 +384,14 @@
padding: 5px; // remove when adding buttons
border-radius: 6px; // remove when adding buttons
margin-right: 10px; // remove when adding buttons
- // width: 100%;
- // display: inline-table;
background-color: #ececec;
max-height: 130px;
width: 92%;
.propertiesView-sharingTable-item {
display: flex;
- // padding: 5px;
padding: 3px;
- align-items: center;
+ align-items: right;
border-bottom: 0.5px solid grey;
&:hover .propertiesView-sharingTable-item-name {
@@ -429,7 +426,7 @@
background: inherit;
border: none;
background: inherit;
- width: 87px;
+ // width: 100%;
text-align: justify; // for Edge
text-align-last: end;
&:hover {
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index dfc43e6c8..a6a5347ad 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -13,7 +13,7 @@ import { InkField } from '../../fields/InkField';
import { List } from '../../fields/List';
import { ComputedField } from '../../fields/ScriptField';
import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
-import { denormalizeEmail, GetEffectiveAcl, SharingPermissions } from '../../fields/util';
+import { denormalizeEmail, GetEffectiveAcl, normalizeEmail, SharingPermissions } from '../../fields/util';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
import { DocumentType } from '../documents/DocumentTypes';
import { DocumentManager } from '../util/DocumentManager';
@@ -34,6 +34,7 @@ import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector
import { PropertiesDocContextSelector } from './PropertiesDocContextSelector';
import './PropertiesView.scss';
import { DefaultStyleProvider } from './StyleProvider';
+import { SourceMapDevToolPlugin } from 'webpack';
const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -366,11 +367,12 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
*/
@undoBatch
changePermissions = (e: any, user: string) => {
+ const docs = (SelectionManager.Views().length < 2 ? [this.selectedDoc] : SelectionManager.Views().map(dv => dv.props.Document)).filter(doc => doc).map(doc => (this.layoutDocAcls ? doc : DocCast(doc)[DataSym]));
if (user=="Public"){
- this.selectedDoc!['acl-' +user] = e.currentTarget.value as SharingPermissions;
+ docs[0]['acl-' +user] = e.currentTarget.value as SharingPermissions;
}
else{
- const docs = (SelectionManager.Views().length < 2 ? [this.selectedDoc] : SelectionManager.Views().map(dv => dv.props.Document)).filter(doc => doc).map(doc => (this.layoutDocAcls ? doc : DocCast(doc)[DataSym]));
+
SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, docs);
}
};
@@ -381,15 +383,17 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
getPermissionsSelect(user: string, permission: string) {
const dropdownValues: string[] = Object.values(SharingPermissions);
if (permission === '-multiple-') dropdownValues.unshift(permission);
- if (user !== 'Override') dropdownValues.splice(dropdownValues.indexOf(SharingPermissions.Unset), 1);
+ if (user !== 'Override') {
+ dropdownValues.splice(dropdownValues.indexOf(SharingPermissions.Unset), 1);
+ // dropdownValues.splice(dropdownValues.indexOf(SharingPermissions.Unset), 1);
+ }
return (
<select className="propertiesView-permissions-select" value={permission} onChange={e => this.changePermissions(e, user)}>
{dropdownValues
- .filter(permission => !Doc.noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any))
+ .filter(permission => permission != SharingPermissions.SelfEdit && (!Doc.noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any)))
.map(permission => (
<option className="propertiesView-permisssions-select" key={permission} value={permission}>
- {' '}
- {permission}{' '}
+ {' '}{permission}{' '}
</option>
))}
</select>
@@ -432,6 +436,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
* @returns a row of the permissions panel
*/
sharingItem(name: string, admin: boolean, permission: string, showExpansionIcon?: boolean) {
+ if (name==Doc.CurrentUserEmail){
+ name = 'Me';
+ }
return (
<div
className="propertiesView-sharingTable-item"
@@ -445,7 +452,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
{/* {name !== "Me" ? this.notifyIcon : null} */}
<div className="propertiesView-sharingTable-item-permission">
{admin && permission !== 'Owner' ? this.getPermissionsSelect(name, permission) : permission}
- {permission === 'Owner' || showExpansionIcon ? this.expansionIcon : null}
+ {(permission === 'Owner' && name=='Me')|| showExpansionIcon ? this.expansionIcon : null}
</div>
</div>
);
@@ -470,6 +477,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
dropDownText = "▲ ";
break;
}
+
return (
<div>
<div className={'propertiesView-shareDropDown'}>
@@ -490,7 +498,24 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
*/
@computed get sharingTable() {
// const docToUse = this.selectedDocumentView?.rootDoc;
+
+ // const dashboard = Doc.ActiveDashboard
+ // var docToUse = dashboard
+ // const tabs = DocListCast(dashboard?.data)
+ // tabs.forEach(tab => {
+ // if (tab.title == this.selectedDoc?.title){
+ // docToUse = tab
+ // }
+ // var newdocsList = DocListCast(tab.data)
+ // newdocsList.forEach(newDoc => {
+ // if (newDoc.title == this.selectedDoc?.title){
+ // docToUse = newDoc
+ // }
+ // })
+ // })
+
const docToUse = this.selectedDoc;
+
if (!docToUse){
return null;
}
@@ -501,44 +526,69 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const target = docs[0];
// tslint:disable-next-line: no-unnecessary-callback-wrapper
- const effectiveAcls = docs.map(doc => GetEffectiveAcl(doc));
- const showAdmin = effectiveAcls.every(acl => acl === AclAdmin);
+ // const effectiveAcls = docs.map(doc => GetEffectiveAcl(doc));
+ // const effectiveAcls = GetEffectiveAcl(docToUse)
+ const effectiveAcls = GetEffectiveAcl(target)
+
+ // const showAdmin = effectiveAcls.every(acl => acl === AclAdmin);
+ const showAdmin= effectiveAcls==AclAdmin || docToUse!['acl-'+normalizeEmail(Doc.CurrentUserEmail)]=='Owner';
// users in common between all docs
const commonKeys: string[] = intersection(...docs.map(doc => doc?.[AclSym] && Object.keys(doc[AclSym]).filter(key => key !== 'acl-Me')));
const tableEntries = [];
+ const usersAdded: string[] = []; // all shared users being added - organized by denormalized email
+ const ownerSame = Doc.CurrentUserEmail !== target.author && docs.filter(doc => doc).every(doc => doc.author === docs[0].author);
+
+ usersAdded.push(target.author);
+ SharingManager.Instance.users.forEach(eachUser => {
+ var userOnDashboard = true;
+ var permission = StrCast(target[`acl-${normalizeEmail(eachUser.user.email)}`])
+ if(Doc.ActiveDashboard){
+ if(Doc.ActiveDashboard['acl-'+normalizeEmail(eachUser.user.email)]=='' || Doc.ActiveDashboard['acl-'+normalizeEmail(eachUser.user.email)]==undefined){
+ userOnDashboard = false;
+ }
+ }
+ if (userOnDashboard && !usersAdded.includes(eachUser.user.email) && eachUser.user.email!='Public'){
+ tableEntries.unshift(this.sharingItem(eachUser.user.email, showAdmin, permission, false)); // adds each user
+ usersAdded.push(eachUser.user.email);
+ }
+ });
- // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
- // if (commonKeys.length) {
- // for (const key of commonKeys) {
- // const name = denormalizeEmail(key.substring(4));
- // const uniform = docs.every(doc => doc?.[AclSym]?.[key] === docs[0]?.[AclSym]?.[key]);
- // if (name !== Doc.CurrentUserEmail && name !== target.author && name !== 'Public' && name !== 'Override' /* && sidebarUsersDisplayed![name] !== false*/) {
- // tableEntries.push(this.sharingItem(name, showAdmin, uniform ? HierarchyMapping.get(target[AclSym][key])!.name : '-multiple-'));
+ // commonKeys.forEach(user => {
+ // const userEmail = user.slice(4)
+ // var userOnDashboard = true;
+ // if(Doc.ActiveDashboard){
+ // if(Doc.ActiveDashboard[user]=='' || Doc.ActiveDashboard[user]==undefined){
+ // userOnDashboard = false;
// }
// }
- // }
- const ownerSame = Doc.CurrentUserEmail !== target.author && docs.filter(doc => doc).every(doc => doc.author === docs[0].author);
- // shifts the current user, owner, public to the top of the doc.
- // tableEntries.unshift(this.sharingItem("Override", showAdmin, docs.filter(doc => doc).every(doc => doc["acl-Override"] === docs[0]["acl-Override"]) ? (AclMap.get(target[AclSym]?.["acl-Override"]) || "None") : "-multiple-"));
- if (ownerSame) tableEntries.unshift(this.sharingItem(StrCast(target.author), showAdmin, 'Owner'));
- // tableEntries.unshift(this.sharingItem(target.author, showAdmin, docs.filter(doc => doc).every(doc => doc['acl-Public'] === target['acl-Public']) ? target['acl-Public'] || SharingPermissions.None : '-multiple-'));
- // tableEntries.unshift(
- // this.sharingItem(
- // 'Me',
- // showAdmin,
- // docs.filter(doc => doc).every(doc => doc.author === Doc.CurrentUserEmail) ? 'Owner' : effectiveAcls.every(acl => acl === effectiveAcls[0]) ? HierarchyMapping.get(effectiveAcls[0])!.name : '-multiple-',
- // !ownerSame
- // )
- // );
-
- SharingManager.Instance.users.forEach(eachUser => tableEntries.unshift(this.sharingItem(eachUser.user.email, false, "test", false)));
-
- docs.map(doc => tableEntries.unshift(this.sharingItem(doc.author, showAdmin, 'Owner', true)));
+ // if (userOnDashboard && !usersAdded.includes(denormalizeEmail(userEmail)) && userEmail!='Public'){
+ // tableEntries.unshift(this.sharingItem(denormalizeEmail(userEmail), showAdmin, StrCast(docToUse![`acl-${normalizeEmail((userEmail))}`]), false)); // adds each user
+ // usersAdded.push(denormalizeEmail(userEmail));
+ // }
+ // })
+
+ // current user
+ const userEmail = Doc.CurrentUserEmail
+ var userOnDashboard = true;
+ if(Doc.ActiveDashboard){
+ if(Doc.ActiveDashboard['acl-'+normalizeEmail(userEmail)]=='' || Doc.ActiveDashboard['acl-'+normalizeEmail(userEmail)]==undefined){
+ userOnDashboard = false;
+ }
+ }
+ if (userOnDashboard && !usersAdded.includes(denormalizeEmail(userEmail)) && userEmail!='Public'){
+ tableEntries.unshift(this.sharingItem(denormalizeEmail(userEmail), showAdmin, StrCast(target[`acl-${normalizeEmail((userEmail))}`]), false)); // adds each user
+ usersAdded.push(denormalizeEmail(userEmail));
+ }
+
+ // if (ownerSame ) tableEntries.unshift(this.sharingItem(StrCast(target.author), showAdmin, 'Owner'), false); // shift owner to top
+ tableEntries.unshift(this.sharingItem(StrCast(target.author), showAdmin, 'Owner'), false); // shift owner to top
return (
- <div> Sharing Mode
- <div>{this.publicACLDropDown(true, StrCast(docToUse['acl-Public']), false)}</div>
+ <div > Sharing Mode
+ <div>{
+ this.publicACLDropDown(true, StrCast(target['acl-Public']), false)}
+ </div>
<div> <br></br> Who has access to the Dashboard? </div>
<div className="propertiesView-sharingTable">{
<div> {tableEntries}</div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index a2c1195cb..0e4330fa5 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -19,7 +19,7 @@ import { RichTextField } from '../../../../fields/RichTextField';
import { RichTextUtils } from '../../../../fields/RichTextUtils';
import { ComputedField } from '../../../../fields/ScriptField';
import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util';
+import { GetEffectiveAcl, normalizeEmail, TraceMobx } from '../../../../fields/util';
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils';
import { GoogleApiClientUtils, Pulls, Pushes } from '../../../apis/google_docs/GoogleApiClientUtils';
import { DocServer } from '../../../DocServer';
@@ -295,11 +295,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
const curProto = Cast(Cast(dataDoc.proto, Doc, null)?.[this.fieldKey], RichTextField, null); // the default text inherited from a prototype
const curLayout = this.rootDoc !== this.layoutDoc ? Cast(this.layoutDoc[this.fieldKey], RichTextField, null) : undefined; // the default text stored in a layout template
const json = JSON.stringify(state.toJSON());
- const effectiveAcl = GetEffectiveAcl(dataDoc);
-
+ // const effectiveAcl = GetEffectiveAcl(dataDoc);
+ const effectiveAcl = GetEffectiveAcl(this.rootDoc);
+
const removeSelection = (json: string | undefined) => (json?.indexOf('"storedMarks"') === -1 ? json?.replace(/"selection":.*/, '') : json?.replace(/"selection":"\"storedMarks\""/, '"storedMarks"'));
-
- if ([AclEdit, AclAdmin, AclSelfEdit].includes(effectiveAcl)) {
+
+ if ([AclEdit, AclAdmin, AclSelfEdit, AclAugment].includes(effectiveAcl)) {
const accumTags = [] as string[];
state.tr.doc.nodesBetween(0, state.doc.content.size, (node: any, pos: number, parent: any) => {
if (node.type === schema.nodes.dashField && node.attrs.fieldKey.startsWith('#')) {
@@ -1689,7 +1690,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
e.stopPropagation();
for (var i = state.selection.from; i <= state.selection.to; i++) {
const node = state.doc.resolve(i);
- if (state.doc.content.size - 1 > i && node?.marks?.().some(mark => mark.type === schema.marks.user_mark && mark.attrs.userid !== Doc.CurrentUserEmail) && [AclAugment, AclSelfEdit].includes(GetEffectiveAcl(this.rootDoc))) {
+ if (state.doc.content.size - 1 > i && node?.marks?.().some(mark => mark.type === schema.marks.user_mark && mark.attrs.userid !== Doc.CurrentUserEmail) && [AclSelfEdit].includes(GetEffectiveAcl(this.rootDoc))) {
e.preventDefault();
}
}
@@ -1708,7 +1709,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
default:
if (this._lastTimedMark?.attrs.userid === Doc.CurrentUserEmail) break;
case ' ':
- [AclEdit, AclAdmin, AclSelfEdit].includes(GetEffectiveAcl(this.dataDoc)) &&
+ if (e.code == "Space"){
+ break;
+ }
+ [AclEdit, AclAugment, AclSelfEdit, AclAdmin].includes(GetEffectiveAcl(this.rootDoc)) &&
this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({})).addStoredMark(schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })));
}
this.startUndoTypingBatch();