diff options
Diffstat (limited to 'src/client/views')
| -rw-r--r-- | src/client/views/DocComponent.tsx | 10 | ||||
| -rw-r--r-- | src/client/views/DocumentDecorations.scss | 3 | ||||
| -rw-r--r-- | src/client/views/DocumentDecorations.tsx | 6 | ||||
| -rw-r--r-- | src/client/views/Main.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/MarqueeAnnotator.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/PropertiesView.scss | 4 | ||||
| -rw-r--r-- | src/client/views/PropertiesView.tsx | 93 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 9 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts | 12 |
9 files changed, 51 insertions, 92 deletions
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 0b92fd864..5a1dae8db 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -222,8 +222,12 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>() if (effectiveAcl === AclAugment) { added.map(doc => { - if ([AclAdmin, AclEdit].includes(GetEffectiveAcl(doc)) && Doc.ActiveDashboard) inheritParentAcls(Doc.ActiveDashboard, doc); doc.context = this.props.Document; + const contextDoc = Cast(doc.context, Doc, null) + if ([AclAdmin, AclEdit].includes(GetEffectiveAcl(doc))) { + if (contextDoc) inheritParentAcls(contextDoc, doc); + else if (Doc.ActiveDashboard) inheritParentAcls(Doc.ActiveDashboard, doc); + }; if (annotationKey ?? this._annotationKeySuffix()) Doc.GetProto(doc).annotationOn = this.props.Document; Doc.AddDocToList(targetDataDoc, annotationKey ?? this.annotationKey, doc); }); @@ -237,7 +241,9 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>() doc.context = this.props.Document; if (annotationKey ?? this._annotationKeySuffix()) Doc.GetProto(doc).annotationOn = this.props.Document; - Doc.ActiveDashboard && inheritParentAcls(Doc.ActiveDashboard, doc); + const contextDoc = Cast(doc.context, Doc, null) + if (contextDoc) inheritParentAcls(contextDoc, doc); + else if (Doc.ActiveDashboard) inheritParentAcls(Doc.ActiveDashboard, doc); }); const annoDocs = targetDataDoc[annotationKey ?? this.annotationKey] as List<Doc>; if (annoDocs instanceof List) annoDocs.push(...added); diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index ce5378e69..32bcc872a 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -237,8 +237,7 @@ $resizeHandler: 8px; color: rgb(71, 71, 71); border-color: rgb(71, 71, 71); } - .documentDecorations-shareEdit, - .documentDecorations-shareSelf-Edit{ + .documentDecorations-shareEdit{ width: calc(100% + 10px); background: rgb(235, 235, 145); color: rgb(75, 75, 5); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 3e0a1f7a4..b769056d8 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -32,6 +32,7 @@ import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { ImageBox } from './nodes/ImageBox'; import React = require('react'); import { SharingManager } from '../util/SharingManager'; +import { DocServer } from '../DocServer'; @observer export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> { @@ -754,9 +755,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P case ("Edit"): shareSymbolIcon = "⬢ "; break; - case ("Self-Edit"): - shareSymbolIcon = "⬢ "; - break; case ("Augment"): shareSymbolIcon = "⬟ "; break; @@ -794,7 +792,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P // 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); + return docView.rootDoc.stayInCollection || (effectiveAcl !== AclAdmin && 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"> diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 6b18caed0..7da9dc603 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -26,7 +26,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0 }; // bcz: not sure root.render(<FieldLoader />); window.location.search.includes('safe') && CollectionView.SetSafeMode(true); const info = await CurrentUserUtils.loadCurrentUser(); - if (info.email === 'guest') DocServer.Control.makeReadOnly(); + // if (info.email === 'guest') DocServer.Control.makeReadOnly(); await CurrentUserUtils.loadUserDocument(info.id); setTimeout(() => { document.getElementById('root')!.addEventListener( diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 30867a774..094c9cc61 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -1,6 +1,6 @@ import { action, observable, ObservableMap, runInAction } from 'mobx'; import { observer } from 'mobx-react'; -import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DataSym, Doc, Opt } from '../../fields/Doc'; +import { AclAdmin, AclAugment, AclEdit, DataSym, Doc, Opt } from '../../fields/Doc'; import { Id } from '../../fields/FieldSymbols'; import { List } from '../../fields/List'; import { NumCast } from '../../fields/Types'; @@ -202,7 +202,7 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> { highlight = (color: string, isLinkButton: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => { // creates annotation documents for current highlights const effectiveAcl = GetEffectiveAcl(this.props.rootDoc[DataSym]); - const annotationDoc = [AclAugment, AclSelfEdit, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color, isLinkButton, savedAnnotations); + const annotationDoc = [AclAugment, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color, isLinkButton, savedAnnotations); addAsAnnotation && !savedAnnotations && annotationDoc && this.props.addDocument(annotationDoc); return (annotationDoc as Doc) ?? undefined; }; diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index 50bf6ce74..71107a5f9 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -172,8 +172,7 @@ border-radius: 6px; border: 1px solid rgb(71, 71, 71); } - & .propertiesView-shareDropDownEdit, - .propertiesView-shareDropDownSelf-Edit{ + & .propertiesView-shareDropDownEdit{ padding: 5px; background: rgb(235, 235, 145); color: rgb(75, 75, 5); @@ -426,7 +425,6 @@ background: inherit; border: none; background: inherit; - // 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 a6a5347ad..984c2dc04 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -369,7 +369,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { 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"){ - docs[0]['acl-' +user] = e.currentTarget.value as SharingPermissions; + // docs[0]['acl-' +user] = e.currentTarget.value as SharingPermissions; + SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, docs); } else{ @@ -385,12 +386,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { if (permission === '-multiple-') dropdownValues.unshift(permission); 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 => permission != SharingPermissions.SelfEdit && (!Doc.noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any))) + .filter(permission => !Doc.noviceMode || ![SharingPermissions.View].includes(permission as any)) .map(permission => ( <option className="propertiesView-permisssions-select" key={permission} value={permission}> {' '}{permission}{' '} @@ -464,9 +464,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { case ("Edit"): dropDownText = "⬢ "; break; - case ("Self-Edit"): - dropDownText = "⬢ "; - break; case ("Augment"): dropDownText = "⬟ "; break; @@ -494,52 +491,35 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } /** + * Sorting algorithm to sort users. + */ + sortUsers = (u1: String, u2: String) => { + return u1 > u2 ? -1 : u1 === u2 ? 0 : 1; + }; + + /** * @returns the sharing and permissions panel. */ @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; } // all selected docs const docs = SelectionManager.Views().length < 2 ? [this.layoutDocAcls ? docToUse : docToUse?.[DataSym]] : SelectionManager.Views().map(docView => (this.layoutDocAcls ? docView.props.Document : docView.props.Document[DataSym])); - const target = docs[0]; - // tslint:disable-next-line: no-unnecessary-callback-wrapper - // 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 commonKeys: string[] = intersection(...docs.map(doc => doc?.[AclSym] && Object.keys(doc[AclSym]).filter(key => key !== 'acl-Me'))); + // const ownerSame = Doc.CurrentUserEmail !== target.author && docs.filter(doc => doc).every(doc => doc.author === docs[0].author); 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)}`]) @@ -548,46 +528,33 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { 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 + if (userOnDashboard && !usersAdded.includes(eachUser.user.email) && eachUser.user.email!='Public' && eachUser.user.email!=target.author){ + // tableEntries.unshift(this.sharingItem(eachUser.user.email, showAdmin, permission, false)); // adds each user usersAdded.push(eachUser.user.email); } }); - - // commonKeys.forEach(user => { - // const userEmail = user.slice(4) - // var userOnDashboard = true; - // if(Doc.ActiveDashboard){ - // if(Doc.ActiveDashboard[user]=='' || Doc.ActiveDashboard[user]==undefined){ - // userOnDashboard = false; - // } - // } - // 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)); + + usersAdded.sort(this.sortUsers) + usersAdded.map(userEmail => { + const permission = StrCast(target[`acl-${normalizeEmail(userEmail)}`]) + tableEntries.unshift(this.sharingItem(userEmail, showAdmin, permission, false)); // adds each user + }) + + // add current user + var userEmail = Doc.CurrentUserEmail + if (userEmail == 'guest') userEmail = 'Public'; + if (!usersAdded.includes(userEmail) && userEmail!='Public' && userEmail!=target.author){ + tableEntries.unshift(this.sharingItem(userEmail, showAdmin, StrCast(target[`acl-${normalizeEmail((userEmail))}`]), false)); // adds each user + usersAdded.push(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 + // shift owner to top + tableEntries.unshift(this.sharingItem(StrCast(target.author), showAdmin, 'Owner'), false); return ( <div > Sharing Mode <div>{ - this.publicACLDropDown(true, StrCast(target['acl-Public']), false)} + this.publicACLDropDown(showAdmin, StrCast(target['acl-Public']), false)} </div> <div> <br></br> Who has access to the Dashboard? </div> <div className="propertiesView-sharingTable">{ diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 0e4330fa5..c073c7468 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -11,7 +11,7 @@ import { Fragment, Mark, Node, Slice } from 'prosemirror-model'; import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from 'prosemirror-state'; import { EditorView } from 'prosemirror-view'; import { DateField } from '../../../../fields/DateField'; -import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, Doc, DocListCast, Field, ForceServerWrite, HeightSym, Opt, UpdatingFromServer, WidthSym } from '../../../../fields/Doc'; +import { AclAdmin, AclAugment, AclEdit, Doc, DocListCast, Field, ForceServerWrite, HeightSym, Opt, UpdatingFromServer, WidthSym } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; import { InkTool } from '../../../../fields/InkField'; import { PrefetchProxy } from '../../../../fields/Proxy'; @@ -295,12 +295,11 @@ 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(this.rootDoc); const removeSelection = (json: string | undefined) => (json?.indexOf('"storedMarks"') === -1 ? json?.replace(/"selection":.*/, '') : json?.replace(/"selection":"\"storedMarks\""/, '"storedMarks"')); - if ([AclEdit, AclAdmin, AclSelfEdit, AclAugment].includes(effectiveAcl)) { + if ([AclEdit, AclAdmin, 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('#')) { @@ -1690,7 +1689,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) && [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) ) { e.preventDefault(); } } @@ -1712,7 +1711,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps if (e.code == "Space"){ break; } - [AclEdit, AclAugment, AclSelfEdit, AclAdmin].includes(GetEffectiveAcl(this.rootDoc)) && + [AclEdit, AclAugment, 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(); diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index 68b0488a2..64cc7addc 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -4,7 +4,7 @@ import { Schema } from 'prosemirror-model'; import { splitListItem, wrapInList } from 'prosemirror-schema-list'; import { EditorState, NodeSelection, TextSelection, Transaction } from 'prosemirror-state'; import { liftTarget } from 'prosemirror-transform'; -import { AclAugment, AclSelfEdit, Doc } from '../../../../fields/Doc'; +import { AclAdmin, AclAugment, AclEdit} from '../../../../fields/Doc'; import { GetEffectiveAcl } from '../../../../fields/util'; import { Utils } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; @@ -48,14 +48,6 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey switch (GetEffectiveAcl(props.DataDoc)) { case AclAugment: return false; - case AclSelfEdit: - for (var i = state.selection.from; i < state.selection.to; i++) { - const marks = state.doc.resolve(i)?.marks?.(); - if (marks?.some((mark: any) => mark.type === schema.marks.user_mark && mark.attrs.userid !== Doc.CurrentUserEmail)) { - return false; - } - } - break; } return true; }; @@ -259,7 +251,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey //Command to create a blank space bind('Space', (state: EditorState, dispatch: (tx: Transaction) => void) => { - if (!canEdit(state)) return true; + if (GetEffectiveAcl(props.DataDoc)!=AclEdit && GetEffectiveAcl(props.DataDoc)!=AclAugment && GetEffectiveAcl(props.DataDoc)!=AclAdmin) return true; const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); dispatch(splitMetadata(marks, state.tr)); return false; |
