diff options
| author | bobzel <zzzman@gmail.com> | 2024-04-17 12:27:21 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2024-04-17 12:27:21 -0400 |
| commit | 2a313f28fcb8675223708b0657de7517a3281095 (patch) | |
| tree | ed6db226cc7d323aee378eddee43dc5f3bdb1ef9 /src/client/views/collections/CollectionSubView.tsx | |
| parent | 62937027183dc8acf14e489fbb4590aff6fce2cd (diff) | |
restoring eslint - updates not complete yet
Diffstat (limited to 'src/client/views/collections/CollectionSubView.tsx')
| -rw-r--r-- | src/client/views/collections/CollectionSubView.tsx | 173 |
1 files changed, 104 insertions, 69 deletions
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 32198e3a2..cd401058f 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -1,10 +1,10 @@ import { action, computed, makeObservable, observable } from 'mobx'; import * as React from 'react'; import * as rp from 'request-promise'; -import { Utils, returnFalse } from '../../../Utils'; +import { ClientUtils, returnFalse } from '../../../ClientUtils'; import CursorField from '../../../fields/CursorField'; -import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc'; -import { AclPrivate, DocData } from '../../../fields/DocSymbols'; +import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../fields/Doc'; +import { AclPrivate } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { listSpec } from '../../../fields/Schema'; @@ -15,16 +15,47 @@ import { GestureUtils } from '../../../pen-gestures/GestureUtils'; import { DocServer } from '../../DocServer'; import { Networking } from '../../Network'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; -import { ViewBoxBaseComponent } from '../DocComponent'; import { DocUtils, Docs, DocumentOptions } from '../../documents/Documents'; -import { DragManager, dropActionType } from '../../util/DragManager'; +import { DragManager } from '../../util/DragManager'; +import { dropActionType } from '../../util/DropActionTypes'; import { ImageUtils } from '../../util/Import & Export/ImageUtils'; import { SelectionManager } from '../../util/SelectionManager'; import { SnappingManager } from '../../util/SnappingManager'; import { UndoManager, undoBatch } from '../../util/UndoManager'; +import { ViewBoxBaseComponent } from '../DocComponent'; +import { FieldViewProps } from '../nodes/FieldView'; import { LoadingBox } from '../nodes/LoadingBox'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; -import { CollectionView, CollectionViewProps } from './CollectionView'; + +export interface CollectionViewProps extends React.PropsWithChildren<FieldViewProps> { + isAnnotationOverlay?: boolean; // is the collection an annotation overlay (eg an overlay on an image/video/etc) + isAnnotationOverlayScrollable?: boolean; // whether the annotation overlay can be vertically scrolled (just for tree views, currently) + layoutEngine?: () => string; + setPreviewCursor?: (func: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => void; + ignoreUnrendered?: boolean; + + // property overrides for child documents + childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox) + childDocumentsActive?: () => boolean | undefined; // whether child documents can be dragged if collection can be dragged (eg., in a when a Pile document is in startburst mode) + childContentsActive?: () => boolean | undefined; + childLayoutFitWidth?: (child: Doc) => boolean; + childlayout_showTitle?: () => string; + childOpacity?: () => number; + childContextMenuItems?: () => { script: ScriptField; label: string }[]; + childLayoutTemplate?: () => Doc | undefined; // specify a layout Doc template to use for children of the collection + childHideDecorationTitle?: boolean; + childHideResizeHandles?: boolean; + childDragAction?: dropActionType; + childXPadding?: number; + childYPadding?: number; + childLayoutString?: string; + childIgnoreNativeSize?: boolean; + childClickScript?: ScriptField; + childDoubleClickScript?: ScriptField; + AddToMap?: (treeViewDoc: Doc, index: number[]) => void; + RemFromMap?: (treeViewDoc: Doc, index: number[]) => void; + hierarchyIndex?: number[]; // hierarchical index of a document up to the rendering root (primarily used for tree views) +} export interface SubCollectionViewProps extends CollectionViewProps { isAnyChildContentActive: () => boolean; @@ -53,7 +84,7 @@ export function CollectionSubView<X>(moreProps?: X) { } }; protected CreateDropTarget(ele: HTMLDivElement) { - //used in schema view + // used in schema view this.createDashEventsTarget(ele); } @@ -83,10 +114,11 @@ export function CollectionSubView<X>(moreProps?: X) { const { Document, TemplateDataDocument } = this._props; const validPairs = this.childDocs .map(doc => Doc.GetLayoutDataDocPair(Document, !this._props.isAnnotationOverlay ? TemplateDataDocument : undefined, doc)) - .filter(pair => { - // filter out any documents that have a proto that we don't have permissions to - return !pair.layout?.hidden && pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate)); - }); + .filter( + pair => + // filter out any documents that have a proto that we don't have permissions to + !pair.layout?.hidden && pair.layout && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate)) + ); return validPairs.map(({ data, layout }) => ({ data: data as Doc, layout: layout! })); // this mapping is a bit of a hack to coerce types } @computed get childDocList() { @@ -95,9 +127,9 @@ export function CollectionSubView<X>(moreProps?: X) { collectionFilters = () => this._focusFilters ?? StrListCast(this.Document._childFilters); collectionRangeDocFilters = () => this._focusRangeFilters ?? Cast(this.Document._childFiltersByRanges, listSpec('string'), []); // child filters apply to the descendants of the documents in this collection - childDocFilters = () => [...(this._props.childFilters?.().filter(f => Utils.IsRecursiveFilter(f)) || []), ...this.collectionFilters()]; + childDocFilters = () => [...(this._props.childFilters?.().filter(f => ClientUtils.IsRecursiveFilter(f)) || []), ...this.collectionFilters()]; // unrecursive filters apply to the documents in the collection, but no their children. See Utils.noRecursionHack - unrecursiveDocFilters = () => [...(this._props.childFilters?.().filter(f => !Utils.IsRecursiveFilter(f)) || [])]; + unrecursiveDocFilters = () => [...(this._props.childFilters?.().filter(f => !ClientUtils.IsRecursiveFilter(f)) || [])]; childDocRangeFilters = () => [...(this._props.childFiltersByRanges?.() || []), ...this.collectionRangeDocFilters()]; searchFilterDocs = () => this._props.searchFilterDocs?.() ?? DocListCast(this.Document._searchFilterDocs); @computed.struct get childDocs() { @@ -129,13 +161,13 @@ export function CollectionSubView<X>(moreProps?: X) { const docsforFilter: Doc[] = []; childDocs.forEach(d => { // dragging facets - const dragged = this._props.childFilters?.().some(f => f.includes(Utils.noDragDocsFilter)); - if (dragged && SnappingManager.CanEmbed && DragManager.docsBeingDragged.includes(d)) return false; + const dragged = this._props.childFilters?.().some(f => f.includes(ClientUtils.noDragDocsFilter)); + if (dragged && SnappingManager.CanEmbed && DragManager.docsBeingDragged.includes(d)) return; let notFiltered = d.z || Doc.IsSystem(d) || DocUtils.FilterDocs([d], this.unrecursiveDocFilters(), childFiltersByRanges, this.Document).length > 0; if (notFiltered) { notFiltered = (!searchDocs.length || searchDocs.includes(d)) && DocUtils.FilterDocs([d], childDocFilters, childFiltersByRanges, this.Document).length > 0; const fieldKey = Doc.LayoutFieldKey(d); - const annos = !Field.toString(Doc.LayoutField(d) as Field).includes(CollectionView.name); + const annos = !Field.toString(Doc.LayoutField(d) as FieldType).includes(CollectionView.name); const data = d[annos ? fieldKey + '_annotations' : fieldKey]; const side = annos && d[fieldKey + '_sidebar']; if (data !== undefined || side !== undefined) { @@ -147,7 +179,7 @@ export function CollectionSubView<X>(moreProps?: X) { newarray = []; subDocs.forEach(t => { const fieldKey = Doc.LayoutFieldKey(t); - const annos = !Field.toString(Doc.LayoutField(t) as Field).includes(CollectionView.name); + const annos = !Field.toString(Doc.LayoutField(t) as FieldType).includes(CollectionView.name); notFiltered = notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!childDocFilters.length && !childFiltersByRanges.length) || DocUtils.FilterDocs([t], childDocFilters, childFiltersByRanges, d).length)); DocListCast(t[annos ? fieldKey + '_annotations' : fieldKey]).forEach(newdoc => newarray.push(newdoc)); @@ -168,7 +200,7 @@ export function CollectionSubView<X>(moreProps?: X) { let ind; const doc = this.Document; const id = Doc.UserDoc()[Id]; - const email = Doc.CurrentUserEmail; + const email = ClientUtils.CurrentUserEmail; const pos = { x: position[0], y: position[1] }; if (id && email) { const proto = Doc.GetProto(doc); @@ -184,6 +216,7 @@ export function CollectionSubView<X>(moreProps?: X) { if (!cursors) { proto.cursors = cursors = new List<CursorField>(); } + // eslint-disable-next-line no-cond-assign if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.data.metadata.id === id)) > -1) { cursors[ind].setPosition(pos); } else { @@ -215,9 +248,9 @@ export function CollectionSubView<X>(moreProps?: X) { moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string) => this._props.moveDocument?.(doc, targetCollection, addDocument) || false; protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { - const docDragData = de.complete.docDragData; + const { docDragData } = de.complete; if (docDragData) { - let added = undefined; + let added; const dropAction = docDragData.dropAction || docDragData.userDropAction; const targetDocments = DocListCast(this.dataDoc[this._props.fieldKey]); const someMoved = !dropAction && docDragData.draggedDocuments.some(drag => targetDocments.includes(drag)); @@ -245,8 +278,9 @@ export function CollectionSubView<X>(moreProps?: X) { } added === false && !this._props.isAnnotationOverlay && e.preventDefault(); added === true && e.stopPropagation(); - return added ? true : false; - } else if (de.complete.annoDragData) { + return !!added; + } + if (de.complete.annoDragData) { const dropCreator = de.complete.annoDragData.dropDocCreator; de.complete.annoDragData.dropDocCreator = () => { const dropped = dropCreator(this._props.isAnnotationOverlay ? this.Document : undefined); @@ -316,7 +350,7 @@ export function CollectionSubView<X>(moreProps?: X) { const result = (await Networking.PostToServer('/uploadRemoteImage', { sources: [imgSrc] })).lastElement(); const newImgSrc = result.accessPaths.agnostic.client.indexOf('dashblobstore') === -1 // - ? Utils.prepend(result.accessPaths.agnostic.client) + ? ClientUtils.prepend(result.accessPaths.agnostic.client) : result.accessPaths.agnostic.client; addDocument(ImageUtils.AssignImgInfo(Docs.Create.ImageDocument(newImgSrc, imgOpts), result)); @@ -325,39 +359,39 @@ export function CollectionSubView<X>(moreProps?: X) { addDocument(ImageUtils.AssignImgInfo(doc, await ImageUtils.ExtractImgInfo(doc))); } return; + } + const path = window.location.origin + '/doc/'; + if (text.startsWith(path)) { + const docId = text.replace(Doc.globalServerPath(), '').split('?')[0]; + DocServer.GetRefField(docId).then(f => { + const fDoc = f; + if (fDoc instanceof Doc) { + if (options.x || options.y) { + fDoc.x = options.x as number; + fDoc.y = options.y as number; + } // should be in CollectionFreeFormView + addDocument(fDoc); + } + }); } else { - const path = window.location.origin + '/doc/'; - if (text.startsWith(path)) { - const docId = text.replace(Doc.globalServerPath(), '').split('?')[0]; - DocServer.GetRefField(docId).then(f => { - if (f instanceof Doc) { - if (options.x || options.y) { - f.x = options.x as number; - f.y = options.y as number; - } // should be in CollectionFreeFormView - f instanceof Doc && addDocument(f); - } - }); - } else { - const srcWeb = SelectionManager.Views.lastElement(); - const srcUrl = (srcWeb?.Document.data as WebField)?.url?.href?.match(/https?:\/\/[^/]*/)?.[0]; - const reg = new RegExp(Utils.prepend(''), 'g'); - const modHtml = srcUrl ? html.replace(reg, srcUrl) : html; - const backgroundColor = tags.map(tag => tag.match(/.*(background-color: ?[^;]*)/)?.[1]?.replace(/background-color: ?(.*)/, '$1')).filter(t => t)?.[0]; - const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: srcUrl ? 'from:' + srcUrl : '-web clip-', _width: 300, _height: 300, backgroundColor }); - Doc.GetProto(htmlDoc)['data-text'] = Doc.GetProto(htmlDoc).text = text; - addDocument(htmlDoc); - if (srcWeb) { - const iframe = SelectionManager.Views[0].ContentDiv?.getElementsByTagName('iframe')?.[0]; - const focusNode = iframe?.contentDocument?.getSelection()?.focusNode as any; - if (focusNode) { - const anchor = srcWeb?.ComponentView?.getAnchor?.(true); - anchor && DocUtils.MakeLink(htmlDoc, anchor, {}); - } + const srcWeb = SelectionManager.Views.lastElement(); + const srcUrl = (srcWeb?.Document.data as WebField)?.url?.href?.match(/https?:\/\/[^/]*/)?.[0]; + const reg = new RegExp(ClientUtils.prepend(''), 'g'); + const modHtml = srcUrl ? html.replace(reg, srcUrl) : html; + const backgroundColor = tags.map(tag => tag.match(/.*(background-color: ?[^;]*)/)?.[1]?.replace(/background-color: ?(.*)/, '$1')).filter(t => t)?.[0]; + const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: srcUrl ? 'from:' + srcUrl : '-web clip-', _width: 300, _height: 300, backgroundColor }); + Doc.GetProto(htmlDoc)['data-text'] = Doc.GetProto(htmlDoc).text = text; + addDocument(htmlDoc); + if (srcWeb) { + const iframe = SelectionManager.Views[0].ContentDiv?.getElementsByTagName('iframe')?.[0]; + const focusNode = iframe?.contentDocument?.getSelection()?.focusNode as any; + if (focusNode) { + const anchor = srcWeb?.ComponentView?.getAnchor?.(true); + anchor && DocUtils.MakeLink(htmlDoc, anchor, {}); } } - return; } + return; } } @@ -414,10 +448,15 @@ export function CollectionSubView<X>(moreProps?: X) { for (let i = 0; i < length; i++) { const item = e.dataTransfer.items[i]; if (item.kind === 'string' && item.type.includes('uri')) { - const stringContents = await new Promise<string>(resolve => item.getAsString(resolve)); - const type = (await rp.head(Utils.CorsProxy(stringContents)))['content-type']; + // eslint-disable-next-line no-await-in-loop + const stringContents = await new Promise<string>(resolve => { + item.getAsString(resolve); + }); + // eslint-disable-next-line no-await-in-loop + const type = (await rp.head(ClientUtils.CorsProxy(stringContents)))['content-type']; if (type) { - const doc = await DocUtils.DocumentFromType(type, Utils.CorsProxy(stringContents), options); + // eslint-disable-next-line no-await-in-loop + const doc = await DocUtils.DocumentFromType(type, ClientUtils.CorsProxy(stringContents), options); doc && generatedDocuments.push(doc); } } @@ -426,7 +465,7 @@ export function CollectionSubView<X>(moreProps?: X) { file?.type && files.push(file); file?.type === 'application/json' && - Utils.readUploadedFileAsText(file).then(result => { + ClientUtils.readUploadedFileAsText(file).then(result => { const json = JSON.parse(result as string); addDocument( Docs.Create.TreeDocument( @@ -450,7 +489,7 @@ export function CollectionSubView<X>(moreProps?: X) { // create placeholder docs // inside placeholder docs have some func that - let pileUpDoc = undefined; + let pileUpDoc; if (typeof files === 'string') { const loading = Docs.Create.LoadingDocument(files, options); generatedDocuments.push(loading); @@ -478,20 +517,16 @@ export function CollectionSubView<X>(moreProps?: X) { }) : []; if (completed) completed(set); - else { - if (isFreeformView && generatedDocuments.length > 1) { - pileUpDoc = DocUtils.pileup(generatedDocuments, options.x as number, options.y as number)!; - addDocument(pileUpDoc); - } else { - generatedDocuments.forEach(addDocument); - } - } - } else { - if (text && !text.includes('https://')) { - addDocument(Docs.Create.TextDocument(text, { ...options, title: text.substring(0, 20), _width: 400, _height: 315 })); + else if (isFreeformView && generatedDocuments.length > 1) { + pileUpDoc = DocUtils.pileup(generatedDocuments, options.x as number, options.y as number)!; + addDocument(pileUpDoc); } else { - alert('Document upload failed - possibly an unsupported file type.'); + generatedDocuments.forEach(addDocument); } + } else if (text && !text.includes('https://')) { + addDocument(Docs.Create.TextDocument(text, { ...options, title: text.substring(0, 20), _width: 400, _height: 315 })); + } else { + alert('Document upload failed - possibly an unsupported file type.'); } }; } |
