diff options
author | eperelm2 <emily_perelman@brown.edu> | 2023-07-18 11:40:12 -0400 |
---|---|---|
committer | eperelm2 <emily_perelman@brown.edu> | 2023-07-18 11:40:12 -0400 |
commit | 5100a643fb0d98b6dd738e7024f4fe15f56ba1a8 (patch) | |
tree | 92fa39d2d5cc8f584e3346c8fe0efaa5b184a9e5 /src/fields/Doc.ts | |
parent | c9779f31d9ce2363e61c3c9fa7e3446203622dde (diff) | |
parent | 16a1b7de3ec26187b3a426eb037a5e4f4b9fcc55 (diff) |
Merge branch 'master' into secondpropertiesmenu-emily
Diffstat (limited to 'src/fields/Doc.ts')
-rw-r--r-- | src/fields/Doc.ts | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index f13dab68c..5a8a6e4b6 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -20,8 +20,6 @@ import { AclEdit, AclPrivate, AclReadonly, - AclSelfEdit, - AclUnset, Animation, CachedUpdates, DirectLinks, @@ -38,11 +36,10 @@ import { Initializing, Self, SelfProxy, - Update, UpdatingFromServer, Width, } from './DocSymbols'; -import { Copy, HandleUpdate, Id, OnUpdate, Parent, ToScriptString, ToString } from './FieldSymbols'; +import { Copy, FieldChanged, HandleUpdate, Id, Parent, ToScriptString, ToString } from './FieldSymbols'; import { InkField, InkTool } from './InkField'; import { List, ListFieldName } from './List'; import { ObjectField } from './ObjectField'; @@ -53,7 +50,7 @@ import { listSpec } from './Schema'; import { ComputedField, ScriptField } from './ScriptField'; import { Cast, DocCast, FieldValue, NumCast, StrCast, ToConstructor } from './Types'; import { AudioField, CsvField, ImageField, PdfField, VideoField, WebField } from './URLField'; -import { deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, updateFunction } from './util'; +import { deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, containedFieldChangedHandler } from './util'; import JSZip = require('jszip'); export namespace Field { export function toKeyValueString(doc: Doc, key: string): string { @@ -126,21 +123,18 @@ export enum aclLevel { unshared = 0, viewable = 1, augmentable = 2, - selfEditable = 2.5, editable = 3, admin = 4, } // prettier-ignore -export const HierarchyMapping: Map<symbol, { level:aclLevel; name: SharingPermissions }> = new Map([ - [AclPrivate, { level: aclLevel.unshared, name: SharingPermissions.None }], - [AclReadonly, { level: aclLevel.viewable, name: SharingPermissions.View }], - [AclAugment, { level: aclLevel.augmentable, name: SharingPermissions.Augment}], - [AclSelfEdit, { level: aclLevel.selfEditable, name: SharingPermissions.SelfEdit }], - [AclEdit, { level: aclLevel.editable, name: SharingPermissions.Edit }], - [AclAdmin, { level: aclLevel.admin, name: SharingPermissions.Admin }], - [AclUnset, { level: aclLevel.unset, name: SharingPermissions.Unset }], +export const HierarchyMapping: Map<symbol, { level:aclLevel; name: SharingPermissions; image: string }> = new Map([ + [AclPrivate, { level: aclLevel.unshared, name: SharingPermissions.None, image: '▲' }], + [AclReadonly, { level: aclLevel.viewable, name: SharingPermissions.View, image: '♦' }], + [AclAugment, { level: aclLevel.augmentable, name: SharingPermissions.Augment, image: '⬟' }], + [AclEdit, { level: aclLevel.editable, name: SharingPermissions.Edit, image: '⬢' }], + [AclAdmin, { level: aclLevel.admin, name: SharingPermissions.Admin, image: '⬢' }], ]); -export const ReverseHierarchyMap: Map<string, { level: aclLevel; acl: symbol }> = new Map(Array.from(HierarchyMapping.entries()).map(value => [value[1].name, { level: value[1].level, acl: value[0] }])); +export const ReverseHierarchyMap: Map<string, { level: aclLevel; acl: symbol; image: string }> = new Map(Array.from(HierarchyMapping.entries()).map(value => [value[1].name, { level: value[1].level, acl: value[0], image: value[1].image }])); // caches the document access permissions for the current user. // this recursively updates all protos as well. @@ -340,9 +334,10 @@ export class Doc extends RefField { for (const key in value) { const field = value[key]; field !== undefined && (this[FieldKeys][key] = true); - if (!(field instanceof ObjectField)) continue; - field[Parent] = this[Self]; - field[OnUpdate] = updateFunction(this[Self], key, field, this[SelfProxy]); + if (field instanceof ObjectField) { + field[Parent] = this[Self]; + field[FieldChanged] = containedFieldChangedHandler(this[SelfProxy], key, field); + } } } @@ -351,7 +346,7 @@ export class Doc extends RefField { /// all of the raw acl's that have been set on this document. Use GetEffectiveAcl to determine the actual ACL of the doc for editing @observable public [DocAcl]: { [key: string]: symbol } = {}; @observable public [DocCss]: number = 0; // incrementer denoting a change to CSS layout - @observable public [DirectLinks]: Set<Doc> = new Set(); + @observable public [DirectLinks] = new ObservableSet<Doc>(); @observable public [Animation]: Opt<Doc>; @observable public [Highlight]: boolean = false; static __Anim(Doc: Doc) { @@ -363,12 +358,13 @@ export class Doc extends RefField { private [ForceServerWrite]: boolean = false; public [Initializing]: boolean = false; - private [Update] = (diff: any) => { - (!this[UpdatingFromServer] || this[ForceServerWrite]) && DocServer.UpdateField(this[Id], diff); - }; - private [Self] = this; private [SelfProxy]: any; + public [FieldChanged] = (diff: undefined | { op: '$addToSet' | '$remFromSet' | '$set'; items: Field[] | undefined; length: number | undefined; hint?: any }, serverOp: any) => { + if (!this[UpdatingFromServer] || this[ForceServerWrite]) { + DocServer.UpdateField(this[Id], serverOp); + } + }; public [DocFields] = () => this[Self][FieldTuples]; // Object.keys(this).reduce((fields, key) => { fields[key] = this[key]; return fields; }, {} as any); public [Width] = () => NumCast(this[SelfProxy]._width); public [Height] = () => NumCast(this[SelfProxy]._height); @@ -382,7 +378,8 @@ export class Doc extends RefField { return self.resolvedDataDoc && !self.isTemplateForField ? self : Doc.GetProto(Cast(Doc.Layout(self).resolvedDataDoc, Doc, null) || self); } @computed get __LAYOUT__(): Doc | undefined { - const templateLayoutDoc = Cast(Doc.LayoutField(this[SelfProxy]), Doc, null); + const self = this[SelfProxy]; + const templateLayoutDoc = Cast(Doc.LayoutField(self), Doc, null); if (templateLayoutDoc) { let renderFieldKey: any; const layoutField = templateLayoutDoc[StrCast(templateLayoutDoc.layout_fieldKey, 'layout')]; @@ -391,7 +388,7 @@ export class Doc extends RefField { } else { return Cast(layoutField, Doc, null); } - return Cast(this[SelfProxy][renderFieldKey + '-layout[' + templateLayoutDoc[Id] + ']'], Doc, null) || templateLayoutDoc; + return Cast(self[renderFieldKey + '-layout[' + templateLayoutDoc[Id] + ']'], Doc, null) || templateLayoutDoc; } return undefined; } @@ -480,6 +477,9 @@ export namespace Doc { // }); // } + export function SetContainer(doc: Doc, container: Doc) { + doc.embedContainer = container; + } export function RunCachedUpdate(doc: Doc, field: string) { const update = doc[CachedUpdates][field]; if (update) { @@ -691,7 +691,7 @@ export namespace Doc { Doc.SetLayout(embedding, Doc.MakeEmbedding(layout)); } embedding.createdFrom = doc; - embedding.proto_embeddingId = Doc.GetProto(doc).proto_embeddingId = NumCast(Doc.GetProto(doc).proto_embeddingId) + 1; + embedding.proto_embeddingId = Doc.GetProto(doc).proto_embeddingId = DocListCast(Doc.GetProto(doc).proto_embeddings).length - 1; embedding.title = ComputedField.MakeFunction(`renameEmbedding(this)`); embedding.author = Doc.CurrentUserEmail; @@ -746,7 +746,9 @@ export namespace Doc { } }; const docAtKey = doc[key]; - if (docAtKey instanceof Doc) { + if (key === 'author') { + assignKey(Doc.CurrentUserEmail); + } else if (docAtKey instanceof Doc) { if (pruneDocs.includes(docAtKey)) { // prune doc and do nothing } else if (!Doc.IsSystem(docAtKey) && (key.startsWith('layout') || ['embedContainer', 'annotationOn', 'proto'].includes(key) || ((key === 'link_anchor_1' || key === 'link_anchor_2') && doc.author === Doc.CurrentUserEmail))) { @@ -934,6 +936,7 @@ export namespace Doc { newLayoutDoc.rootDocument = targetDoc; const dataDoc = Doc.GetProto(targetDoc); newLayoutDoc.resolvedDataDoc = dataDoc; + newLayoutDoc['acl-Guest'] = SharingPermissions.Edit; if (dataDoc[templateField] === undefined && templateLayoutDoc[templateField] instanceof List && (templateLayoutDoc[templateField] as any).length) { dataDoc[templateField] = ComputedField.MakeFunction(`ObjectField.MakeCopy(templateLayoutDoc["${templateField}"] as List)`, { templateLayoutDoc: Doc.name }, { templateLayoutDoc }); } @@ -1019,7 +1022,6 @@ export namespace Doc { Doc.AddDocToList(Doc.GetProto(copy)[DocData], 'proto_embeddings', copy); } copy.embedContainer = undefined; - Doc.defaultAclPrivate && (copy['acl-Public'] = 'Not Shared'); if (retitle) { copy.title = incrementTitleCopy(StrCast(copy.title)); } @@ -1079,7 +1081,6 @@ export namespace Doc { const applied = ApplyTemplateTo(templateDoc, target, targetKey, templateDoc.title + '(...' + _applyCount++ + ')'); target.layout_fieldKey = targetKey; applied && (Doc.GetProto(applied).type = templateDoc.type); - Doc.defaultAclPrivate && (applied['acl-Public'] = 'Not Shared'); return applied; } return undefined; @@ -1090,7 +1091,7 @@ export namespace Doc { target[targetKey] = new PrefetchProxy(templateDoc); } else { titleTarget && (Doc.GetProto(target).title = titleTarget); - const setDoc = [AclAdmin, AclEdit].includes(GetEffectiveAcl(Doc.GetProto(target))) ? Doc.GetProto(target) : target; + const setDoc = [AclAdmin, AclEdit, AclAugment].includes(GetEffectiveAcl(Doc.GetProto(target))) ? Doc.GetProto(target) : target; setDoc[targetKey] = new PrefetchProxy(templateDoc); } } |