aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/CurrentUserUtils.ts2
-rw-r--r--src/client/views/DocComponent.tsx20
-rw-r--r--src/client/views/DocumentDecorations.tsx9
-rw-r--r--src/client/views/MainView.tsx7
-rw-r--r--src/client/views/MarqueeAnnotator.tsx6
-rw-r--r--src/client/views/StyleProvider.tsx56
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.tsx7
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx15
-rw-r--r--src/client/views/collections/CollectionSubView.tsx4
-rw-r--r--src/client/views/collections/TabDocView.tsx4
-rw-r--r--src/client/views/collections/TreeView.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx17
-rw-r--r--src/client/views/collections/collectionLinear/CollectionLinearView.tsx2
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx2
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx2
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.scss3
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx2
-rw-r--r--src/client/views/collections/collectionSchema/SchemaRowBox.tsx18
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx14
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx7
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx12
-rw-r--r--src/client/views/nodes/DocumentView.tsx29
-rw-r--r--src/client/views/nodes/LabelBox.scss5
-rw-r--r--src/client/views/nodes/LabelBox.tsx4
-rw-r--r--src/client/views/nodes/LinkAnchorBox.tsx11
-rw-r--r--src/client/views/nodes/LinkBox.tsx6
-rw-r--r--src/client/views/nodes/PDFBox.tsx1
-rw-r--r--src/client/views/nodes/formattedText/DashDocView.tsx7
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx2
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx2
-rw-r--r--src/client/views/pdf/PDFViewer.tsx13
-rw-r--r--src/client/views/topbar/TopBar.tsx3
-rw-r--r--src/fields/Doc.ts5
33 files changed, 143 insertions, 158 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 7d9cb36c5..0b15e3add 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -192,7 +192,7 @@ export class CurrentUserUtils {
{onClick:"deiconifyView(documentView)", onDoubleClick: "deiconifyViewToLightbox(documentView)", });
};
const labelBox = (opts: DocumentOptions, data?:string) => Docs.Create.LabelDocument({
- textTransform: "unset", letterSpacing: "unset", _singleLine: false, _label_minFontSize: 14, _label_maxFontSize: 24, layout_borderRounding: "5px", _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, ...opts
+ textTransform: "unset", letterSpacing: "unset", _singleLine: false, _label_minFontSize: 14, _label_maxFontSize: 14, layout_borderRounding: "5px", _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, ...opts
});
const imageBox = (opts: DocumentOptions, url?:string) => Docs.Create.ImageDocument(url ?? "http://www.cs.brown.edu/~bcz/noImage.png", { "icon_nativeWidth": 360 / 4, "icon_nativeHeight": 270 / 4, iconTemplate:DocumentType.IMG, _width: 360 / 4, _height: 270 / 4, _layout_showTitle: "title", ...opts });
const fontBox = (opts:DocumentOptions, data?:string) => Docs.Create.FontIconDocument({ _nativeHeight: 30, _nativeWidth: 30, _width: 30, _height: 30, ...opts });
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 4400b3576..6aba4a042 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -1,6 +1,6 @@
import { action, computed, makeObservable, observable } from 'mobx';
import * as React from 'react';
-import { emptyPath, returnFalse } from '../../Utils';
+import { returnFalse } from '../../Utils';
import { DateField } from '../../fields/DateField';
import { Doc, DocListCast, Opt } from '../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, DocData } from '../../fields/DocSymbols';
@@ -41,7 +41,7 @@ export function DocComponent<P extends DocComponentProps>() {
}
// This is the data part of a document -- ie, the data that is constant across all views of the document
@computed get dataDoc() {
- return this._props.Document[DocData] as Doc;
+ return this._props.Document[DocData];
}
}
return Component;
@@ -55,16 +55,12 @@ export interface ViewBoxBaseProps {
Document: Doc;
TemplateDataDocument?: Doc;
DocumentView?: () => DocumentView;
- containerViewPath?: () => DocumentView[];
fieldKey: string;
isSelected: () => boolean;
isContentActive: () => boolean | undefined;
ScreenToLocalTransform: () => Transform;
renderDepth: number;
}
-function returnEmptyDocViewList() {
- return [] as DocumentView[];
-}
export function ViewBoxBaseComponent<P extends ViewBoxBaseProps>() {
class Component extends ObservableReactComponent<React.PropsWithChildren<P>> {
ScreenToLocalBoxXf = () => this._props.ScreenToLocalTransform();
@@ -72,12 +68,6 @@ export function ViewBoxBaseComponent<P extends ViewBoxBaseProps>() {
get DocumentView() {
return this._props.DocumentView;
}
- get docViewPath() {
- return this.DocumentView?.().docViewPath ?? returnEmptyDocViewList;
- }
- get containerViewPath() {
- return this._props.containerViewPath;
- }
//TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then
get Document() {
return this._props.Document;
@@ -132,12 +122,6 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>()
get DocumentView() {
return this._props.DocumentView;
}
- get docViewPath() {
- return this.DocumentView?.().docViewPath ?? returnEmptyDocViewList;
- }
- get containerViewPath() {
- return this.DocumentView?.().containerViewPath ?? returnEmptyDocViewList;
- }
//TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then
@computed get Document() {
return this._props.Document;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index c96253405..8db972ef0 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -344,10 +344,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
e,
returnFalse, // don't care about move or up event,
emptyFunction, // just care about whether we get a click event
- e => UndoManager.RunInBatch(
- () => SelectionManager.Docs.forEach(doc =>
- doc._pointerEvents = (doc._lockedPosition = !doc._lockedPosition)? 'none' : undefined ),
- 'toggleBackground' ) // prettier-ignore
+ e => UndoManager.RunInBatch(() => SelectionManager.Docs.forEach(doc => Doc.toggleLockedPosition(doc)), 'toggleBackground')
);
e.stopPropagation();
};
@@ -530,7 +527,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
doc.xPadding = NumCast(doc.xPadding) * scale.x;
doc.yPadding = NumCast(doc.yPadding) * scale.y;
} else {
- const refCent = docView.screenToContentsTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move)
+ const refCent = docView.screenToViewTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move)
const [nwidth, nheight] = [docView.nativeWidth, docView.nativeHeight];
const [initWidth, initHeight] = [NumCast(doc._width, 1), NumCast(doc._height)];
@@ -689,7 +686,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
);
const bounds = this.ClippedBounds;
- const useLock = bounds.r - bounds.x > 135 && seldocview.CollectionFreeFormDocumentView;
+ const useLock = bounds.r - bounds.x > 135;
const useRotation = !hideResizers && seldocview.Document.type !== DocumentType.EQUATION && seldocview.CollectionFreeFormDocumentView; // when do we want an object to not rotate?
const rotation = SelectionManager.Views.length == 1 ? seldocview.screenToContentsTransform().inverse().RotateDeg : 0;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index cd6aeea41..d700ea020 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -56,13 +56,11 @@ import { CollectionLinearView } from './collections/collectionLinear';
import { LinkMenu } from './linking/LinkMenu';
import { AudioBox } from './nodes/AudioBox';
import { DocButtonState } from './nodes/DocumentLinksButton';
-import { DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from './nodes/DocumentView';
+import { DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod, returnEmptyDocViewList } from './nodes/DocumentView';
import { ImageBox } from './nodes/ImageBox';
import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
import { LinkDocPreview, LinkInfo } from './nodes/LinkDocPreview';
import { MapAnchorMenu } from './nodes/MapBox/MapAnchorMenu';
-import { MapBox } from './nodes/MapBox/MapBox';
-import { RadialMenu } from './nodes/RadialMenu';
import { TaskCompletionBox } from './nodes/TaskCompletedBox';
import { DashFieldViewMenu } from './nodes/formattedText/DashFieldView';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
@@ -898,6 +896,7 @@ export class MainView extends ObservableReactComponent<{}> {
<div className="mainView-docButtons" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }} ref={this._docBtnRef}>
<CollectionLinearView
Document={Doc.MyDockedBtns}
+ docViewPath={returnEmptyDocViewList}
fieldKey="data"
dropAction="embed"
styleProvider={DefaultStyleProvider}
@@ -906,7 +905,6 @@ export class MainView extends ObservableReactComponent<{}> {
isAnyChildContentActive={returnFalse}
isContentActive={emptyFunction}
isSelected={returnFalse}
- containerViewPath={returnEmptyDoclist}
moveDocument={this.moveButtonDoc}
addDocument={this.addButtonDoc}
addDocTab={DocumentViewInternal.addDocTabFunc}
@@ -1021,7 +1019,6 @@ export class MainView extends ObservableReactComponent<{}> {
<PreviewCursor />
<TaskCompletionBox />
<ContextMenu />
- <RadialMenu />
<AnchorMenu />
<MapAnchorMenu />
<DirectionsAnchorMenu />
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index cfdc648b4..d0516336c 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -66,7 +66,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
const savedAnnoMap = savedAnnotations?.values() && Array.from(savedAnnotations?.values()).length ? savedAnnotations : this.props.savedAnnotations();
if (savedAnnoMap.size === 0) return undefined;
const savedAnnos = Array.from(savedAnnoMap.values())[0];
- const doc = this.props.docView().Document;
+ const doc = this.props.Document;
const scale = (this.props.annotationLayerScaling?.() || 1) * NumCast(doc._freeform_scale, 1);
if (savedAnnos.length && (savedAnnos[0] as any).marqueeing) {
const anno = savedAnnos[0];
@@ -227,7 +227,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
dragComplete: e => {
if (!e.aborted && e.linkDocument) {
Doc.GetProto(e.linkDocument).link_relationship = 'cropped image';
- Doc.GetProto(e.linkDocument).title = 'crop: ' + this.props.docView().Document.title;
+ Doc.GetProto(e.linkDocument).title = 'crop: ' + this.props.Document.title;
Doc.GetProto(e.linkDocument).link_displayLine = false;
}
},
@@ -256,7 +256,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
// configure and show the annotation/link menu if a the drag region is big enough
// copy the temporary marquee to allow for multiple selections (not currently available though).
const copy = document.createElement('div');
- const scale = (this.props.scaling?.() || 1) * NumCast(this.props.docView().Document._freeform_scale, 1);
+ const scale = (this.props.scaling?.() || 1) * NumCast(this.props.Document._freeform_scale, 1);
['border', 'opacity', 'top', 'left', 'width', 'height'].forEach(prop => (copy.style[prop as any] = marqueeStyle[prop as any]));
copy.className = 'marqueeAnnotator-annotationBox';
copy.style.top = parseInt(marqueeStyle.top.toString().replace('px', '')) / scale + this.props.scrollTop + 'px';
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 491a72c08..1cb5ff249 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -20,7 +20,6 @@ import { SnappingManager } from '../util/SnappingManager';
import { undoBatch, UndoManager } from '../util/UndoManager';
import { TreeSort } from './collections/TreeSort';
import { Colors } from './global/globalEnums';
-import { DocumentViewProps } from './nodes/DocumentView';
import { FieldViewProps } from './nodes/FieldView';
import { KeyValueBox } from './nodes/KeyValueBox';
import { PropertiesView } from './PropertiesView';
@@ -51,21 +50,7 @@ export enum StyleProp {
}
function toggleLockedPosition(doc: Doc) {
- UndoManager.RunInBatch(
- () =>
- runInAction(() => {
- doc._lockedPosition = !doc._lockedPosition;
- doc._pointerEvents = doc._lockedPosition ? 'none' : undefined;
- }),
- 'toggleBackground'
- );
-}
-
-export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentViewProps {
- return toBeDetermined?.isContentActive ? toBeDetermined : undefined;
-}
-export function testFieldProps(toBeDetermined: any): toBeDetermined is FieldViewProps {
- return toBeDetermined?.isContentActive ? toBeDetermined : undefined;
+ UndoManager.RunInBatch(() => Doc.toggleLockedPosition(doc), 'toggleBackground');
}
export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
@@ -82,19 +67,17 @@ export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
//
export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any {
const remoteDocHeader = 'author;author_date;noMargin';
- const docProps = testDocProps(props) ? props : undefined;
- const fieldProps = testFieldProps(props) ? props : undefined;
const isCaption = property.includes(':caption');
const isAnchor = property.includes(':anchor');
const isNonTransparent = property.includes(':nonTransparent');
const isNonTransparentLevel = isNonTransparent ? Number(property.replace(/.*:nonTransparent([0-9]+).*/, '$1')) : 0; // property.includes(':nonTransparent');
const isContent = property.includes(':content');
const isAnnotated = property.includes(':annotated');
- const isInk = () => doc?._layout_isSvg && !docProps?.LayoutTemplateString;
+ const isInk = () => doc?._layout_isSvg && !props?.LayoutTemplateString;
const isOpen = property.includes(':open');
const isEmpty = property.includes(':empty');
const boxBackground = property.includes(':box');
- const fieldKey = fieldProps?.fieldKey ? fieldProps.fieldKey + '_' : isCaption ? 'caption_' : '';
+ const fieldKey = props?.fieldKey ? props.fieldKey + '_' : isCaption ? 'caption_' : '';
const lockedPosition = () => doc && BoolCast(doc._lockedPosition);
const titleHeight = () => props?.styleProvider?.(doc, props, StyleProp.TitleHeight);
const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1));
@@ -137,20 +120,19 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>,
return undefined;
case StyleProp.DocContents:return undefined;
case StyleProp.WidgetColor:return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
- case StyleProp.Opacity: return docProps?.LayoutTemplateString?.includes(KeyValueBox.name) ? 1 : doc?.text_inlineAnnotations ? 0 : Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
+ case StyleProp.Opacity: return props?.LayoutTemplateString?.includes(KeyValueBox.name) ? 1 : doc?.text_inlineAnnotations ? 0 : Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
case StyleProp.FontSize: return StrCast(doc?.[fieldKey + 'fontSize'], StrCast(doc?._text_fontSize, StrCast(Doc.UserDoc().fontSize)));
case StyleProp.FontFamily: return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(doc?._text_fontFamily, StrCast(Doc.UserDoc().fontFamily)));
case StyleProp.FontWeight: return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(doc?._text_fontWeight, StrCast(Doc.UserDoc().fontWeight)));
case StyleProp.FillColor: return StrCast(doc?._fillColor, StrCast(doc?.fillColor, 'transparent'));
case StyleProp.ShowCaption:return doc?._type_collection === CollectionViewType.Carousel ? undefined: StrCast(doc?._layout_showCaption);
- case StyleProp.TitleHeight:
- return (props?.DocumentView?.().screenToViewTransform().Scale ?? 1) * NumCast(Doc.UserDoc().headerHeight,30)
+ case StyleProp.TitleHeight:return (props?.ScreenToLocalTransform().Scale ?? 1) * NumCast(Doc.UserDoc().headerHeight,30);
case StyleProp.ShowTitle:
return (
(doc &&
- !docProps?.LayoutTemplateString &&
+ !props?.LayoutTemplateString &&
!doc.presentation_targetDoc &&
- !docProps?.LayoutTemplateString?.includes(KeyValueBox.name) &&
+ !props?.LayoutTemplateString?.includes(KeyValueBox.name) &&
props?.layout_showTitle?.() !== '' &&
StrCast(
doc._layout_showTitle,
@@ -169,7 +151,6 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>,
if (doc?.type === DocumentType.FONTICON) return SettingsManager.userColor;
const docColor: Opt<string> = StrCast(doc?.[fieldKey + 'color'], StrCast(doc?._color));
if (docColor) return docColor;
- const parView = props?.DocumentView?.();
const backColor = backgroundCol();
return backColor ? lightOrDark(backColor) : undefined;
case StyleProp.BorderRounding:
@@ -247,7 +228,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>,
doc?.layout_boxShadow,
doc?._type_collection === CollectionViewType.Pile
? '4px 4px 10px 2px'
- : lockedPosition() || doc?.isGroup || docProps?.LayoutTemplateString
+ : lockedPosition() || doc?.isGroup || props?.LayoutTemplateString
? undefined // groups have no drop shadow -- they're supposed to be "invisible". LayoutString's imply collection is being rendered as something else (e.g., title of a Slide)
: `${Colors.DARK_GRAY} ${StrCast(doc.layout_boxShadow, '0.2vw 0.2vw 0.8vw')}`
);
@@ -257,10 +238,10 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>,
default:
return doc.z
? `#9c9396 ${StrCast(doc?.layout_boxShadow, '10px 10px 0.9vw')}` // if it's a floating doc, give it a big shadow
- : props?.DocumentView?.().containerViewPath?.().lastElement()?.Document._freeform_useClusters
- ? `${backgroundCol()} ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (docProps?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
+ : props?.containerViewPath?.().lastElement()?.Document._freeform_useClusters
+ ? `${backgroundCol()} ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (props?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
: NumCast(doc.group, -1) !== -1
- ? `gray ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (docProps?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
+ ? `gray ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (props?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
: lockedPosition()
? undefined // if it's a background & has a cluster color, make the shadow spread really big
: StrCast(doc.layout_fieldKey).includes('_inline') // if doc is an inline document in a text box
@@ -271,8 +252,8 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>,
}
}
case StyleProp.PointerEvents:
- if (StrCast(doc?.pointerEvents) && !docProps?.LayoutTemplateString?.includes(KeyValueBox.name)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
- if (docProps?.DocumentView?.()._props.LayoutTemplateString?.includes(KeyValueBox.name)) return 'all';
+ if (StrCast(doc?.pointerEvents) && !props?.LayoutTemplateString?.includes(KeyValueBox.name)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
+ if (props?.LayoutTemplateString?.includes(KeyValueBox.name)) return 'all';
if (SnappingManager.ExploreMode || doc?.layout_unrendered) return isInk() ? 'visiblePainted' : 'all';
if (props?.pointerEvents?.() === 'none') return 'none';
if (opacity() === 0) return 'none';
@@ -281,22 +262,17 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>,
if (props?.isDocumentActive?.() && !props.treeViewDoc) return isInk() ? 'visiblePainted' : 'all';
return undefined; // fixes problem with tree view elements getting pointer events when the tree view is not active
case StyleProp.Decorations:
- const lock = () => {
- if (props?.DocumentView?.().containerViewPath?.().lastElement()?.Document?._type_collection === CollectionViewType.Freeform) {
- return doc?.pointerEvents !== 'none' ? null : (
+ const lock = () => doc?.pointerEvents !== 'none' ? null : (
<div className="styleProvider-lock" onClick={() => toggleLockedPosition(doc)}>
<FontAwesomeIcon icon='lock' size="lg" />
</div>
);
- }
- };
const filter = () => {
- const docView = props?.DocumentView?.();
const dashView = untracked(() => DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard));
const showFilterIcon =
StrListCast(doc?._childFilters).length || StrListCast(doc?._childFiltersByRanges).length
? 'green' // #18c718bd' //'hasFilter'
- : docProps?.childFilters?.().filter(f => Utils.IsRecursiveFilter(f) && f !== Utils.noDragDocsFilter).length || docProps?.childFiltersByRanges().length
+ : props?.childFilters?.().filter(f => Utils.IsRecursiveFilter(f) && f !== Utils.noDragDocsFilter).length || props?.childFiltersByRanges().length
? 'orange' //'inheritsFilter'
: undefined;
return !showFilterIcon ? null : (
@@ -327,7 +303,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>,
"this view inherits filters from one of its parents"}
color={SettingsManager.userColor}
background={showFilterIcon}
- items={[ ...(dashView ? [dashView]: []), ...(docView?.containerViewPath?.()??[]), ...(docView ? [docView]:[])]
+ items={[ ...(dashView ? [dashView]: []), ...(props?.docViewPath?.()??[])]
.filter(dv => StrListCast(dv?.Document.childFilters).length || StrListCast(dv?.Document.childRangeFilters).length)
.map(dv => ({
text: StrCast(dv?.Document.title),
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 92c8e1256..363db8850 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -238,7 +238,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
PanelWidth={width}
PanelHeight={height}
styleProvider={this.styleProvider}
- containerViewPath={this.docViewPath}
+ containerViewPath={this.childContainerViewPath}
layout_fitWidth={this._props.childLayoutFitWidth}
isContentActive={emptyFunction}
onKey={this.onKeyDown}
@@ -407,10 +407,9 @@ export class CollectionNoteTakingView extends CollectionSubView() {
@undoBatch
onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
- const docView = fieldProps.DocumentView?.();
- if (docView && (e.ctrlKey || docView.Document._createDocOnCR) && ['Enter'].includes(e.key)) {
+ if ((e.ctrlKey || fieldProps.Document._createDocOnCR) && ['Enter'].includes(e.key)) {
e.stopPropagation?.();
- const newDoc = Doc.MakeCopy(docView.Document, true);
+ const newDoc = Doc.MakeCopy(fieldProps.Document, true);
Doc.GetProto(newDoc).text = undefined;
FormattedTextBox.SetSelectOnLoad(newDoc);
return this.addDocument?.(newDoc);
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 0a0218124..9384b7088 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -278,16 +278,15 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
};
@undoBatch
onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
- const docView = fieldProps.DocumentView?.();
- if (docView && ['Enter'].includes(e.key) && e.ctrlKey) {
+ if (['Enter'].includes(e.key) && e.ctrlKey) {
e.stopPropagation?.();
const below = !e.altKey && e.key !== 'Tab';
- const layout_fieldKey = StrCast(docView.LayoutFieldKey);
- const newDoc = Doc.MakeCopy(docView.Document, true);
- const dataField = docView.Document[Doc.LayoutFieldKey(newDoc)];
+ const layout_fieldKey = StrCast(fieldProps.fieldKey);
+ const newDoc = Doc.MakeCopy(fieldProps.Document, true);
+ const dataField = fieldProps.Document[Doc.LayoutFieldKey(newDoc)];
newDoc[DocData][Doc.LayoutFieldKey(newDoc)] = dataField === undefined || Cast(dataField, listSpec(Doc), null)?.length !== undefined ? new List<Doc>([]) : undefined;
- if (layout_fieldKey !== 'layout' && docView.Document[layout_fieldKey] instanceof Doc) {
- newDoc[layout_fieldKey] = docView.Document[layout_fieldKey];
+ if (layout_fieldKey !== 'layout' && fieldProps.Document[layout_fieldKey] instanceof Doc) {
+ newDoc[layout_fieldKey] = fieldProps.Document[layout_fieldKey];
}
Doc.GetProto(newDoc).text = undefined;
FormattedTextBox.SetSelectOnLoad(newDoc);
@@ -327,7 +326,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
PanelHeight={panelHeight}
pointerEvents={this.DocumentView?.()._props.onClick?.() ? returnNone : undefined} // if the stack has an onClick, then we don't want the contents to be interactive (see CollectionPileView)
styleProvider={this.styleProvider}
- containerViewPath={this.docViewPath}
+ containerViewPath={this.childContainerViewPath}
layout_fitWidth={this.childFitWidth}
isContentActive={doc.onClick ? this.isChildButtonContentActive : this.isChildContentActive}
onKey={this.onKeyDown}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 2e0a75281..d7c42a975 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -25,6 +25,7 @@ import { ViewBoxBaseComponent, ViewBoxBaseProps } from '../DocComponent';
import { LoadingBox } from '../nodes/LoadingBox';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { CollectionView, CollectionViewProps } from './CollectionView';
+import { returnEmptyDocViewList } from '../nodes/DocumentView';
export interface SubCollectionViewProps extends CollectionViewProps {
isAnyChildContentActive: () => boolean;
@@ -69,6 +70,9 @@ export function CollectionSubView<X>(moreProps?: X) {
: Doc.GetProto(this._props.Document); // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template
}
+ get childContainerViewPath() {
+ return this.DocumentView?.().docViewPath ?? returnEmptyDocViewList;
+ }
// this returns whether either the collection is selected, or the template that it is part of is selected
rootSelected = () => this._props.isSelected() || BoolCast(this._props.TemplateDataDocument && this._props.rootSelected?.());
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 2441c67e6..f00e42360 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -29,7 +29,7 @@ import { LightboxView } from '../LightboxView';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { DefaultStyleProvider, StyleProp } from '../StyleProvider';
import { Colors } from '../global/globalEnums';
-import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere, OpenWhereMod } from '../nodes/DocumentView';
+import { DocFocusOptions, DocumentView, OpenWhere, OpenWhereMod, returnEmptyDocViewList } from '../nodes/DocumentView';
import { KeyValueBox } from '../nodes/KeyValueBox';
import { DashFieldView } from '../nodes/formattedText/DashFieldView';
import { PinProps, PresBox, PresMovement } from '../nodes/trails';
@@ -595,7 +595,7 @@ export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps
<div className="miniMap" style={{ width: miniSize, height: miniSize, background: this._props.background() }}>
<CollectionFreeFormView
Document={this._props.document}
- containerViewPath={returnEmptyDoclist}
+ docViewPath={returnEmptyDocViewList}
childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
noOverlay={true} // don't render overlay Docs since they won't scale
isContentActive={emptyFunction}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 41720d0dd..9f40edee1 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -977,7 +977,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
hideResizeHandles={this.treeView.outlineMode}
styleProvider={this.titleStyleProvider}
onClickScriptDisable="never" // tree docViews have a script to show fields, etc.
- containerViewPath={this.treeView.docViewPath}
+ containerViewPath={this.treeView.childContainerViewPath}
treeViewDoc={this.treeView.Document}
addDocument={undefined}
addDocTab={this._props.addDocTab}
@@ -1084,7 +1084,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
ScreenToLocalTransform={this.docTransform}
renderDepth={this._props.renderDepth + 1}
treeViewDoc={this.treeView?.Document}
- containerViewPath={this.treeView.docViewPath}
+ containerViewPath={this.treeView.childContainerViewPath}
childFilters={returnEmptyFilter}
childFiltersByRanges={returnEmptyFilter}
searchFilterDocs={returnEmptyDoclist}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 3eaf1876c..c4358747b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1170,18 +1170,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@undoBatch
onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
- const docView = fieldProps.DocumentView?.();
- if (docView && (e.metaKey || e.ctrlKey || e.altKey || docView.Document._createDocOnCR) && ['Tab', 'Enter'].includes(e.key)) {
+ if ((e.metaKey || e.ctrlKey || e.altKey || fieldProps.Document._createDocOnCR) && ['Tab', 'Enter'].includes(e.key)) {
e.stopPropagation?.();
const below = !e.altKey && e.key !== 'Tab';
- const layout_fieldKey = StrCast(docView.LayoutFieldKey);
- const newDoc = Doc.MakeCopy(docView.Document, true);
- const dataField = docView.Document[Doc.LayoutFieldKey(newDoc)];
+ const layout_fieldKey = StrCast(fieldProps.fieldKey);
+ const newDoc = Doc.MakeCopy(fieldProps.Document, true);
+ const dataField = fieldProps.Document[Doc.LayoutFieldKey(newDoc)];
newDoc[DocData][Doc.LayoutFieldKey(newDoc)] = dataField === undefined || Cast(dataField, listSpec(Doc), null)?.length !== undefined ? new List<Doc>([]) : undefined;
- if (below) newDoc.y = NumCast(docView.Document.y) + NumCast(docView.Document._height) + 10;
- else newDoc.x = NumCast(docView.Document.x) + NumCast(docView.Document._width) + 10;
- if (layout_fieldKey !== 'layout' && docView.Document[layout_fieldKey] instanceof Doc) {
- newDoc[layout_fieldKey] = docView.Document[layout_fieldKey];
+ if (below) newDoc.y = NumCast(fieldProps.Document.y) + NumCast(fieldProps.Document._height) + 10;
+ else newDoc.x = NumCast(fieldProps.Document.x) + NumCast(fieldProps.Document._width) + 10;
+ if (layout_fieldKey !== 'layout' && fieldProps.Document[layout_fieldKey] instanceof Doc) {
+ newDoc[layout_fieldKey] = fieldProps.Document[layout_fieldKey];
}
Doc.GetProto(newDoc).text = undefined;
FormattedTextBox.SetSelectOnLoad(newDoc);
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index 4f4c674ea..72bdb9b6b 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -189,7 +189,7 @@ export class CollectionLinearView extends CollectionSubView() {
dontRegisterView={BoolCast(this.Document.childDontRegisterViews)}
focus={emptyFunction}
styleProvider={this._props.styleProvider}
- containerViewPath={this.docViewPath}
+ containerViewPath={this.childContainerViewPath}
whenChildContentsActiveChanged={emptyFunction}
bringToFront={emptyFunction}
childFilters={this._props.childFilters}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 1fd514ccb..40b4151fe 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -259,7 +259,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
Document={childLayout}
TemplateDataDocument={childLayout.resolvedDataDoc as Doc}
styleProvider={this._props.styleProvider}
- containerViewPath={this.docViewPath}
+ containerViewPath={this.childContainerViewPath}
LayoutTemplate={this._props.childLayoutTemplate}
LayoutTemplateString={this._props.childLayoutString}
renderDepth={this._props.renderDepth + 1}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 98e39cd36..04a4042f1 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -254,7 +254,7 @@ export class CollectionMultirowView extends CollectionSubView() {
Document={layout}
TemplateDataDocument={layout.resolvedDataDoc as Doc}
styleProvider={this._props.styleProvider}
- containerViewPath={this.docViewPath}
+ containerViewPath={this.childContainerViewPath}
LayoutTemplate={this._props.childLayoutTemplate}
LayoutTemplateString={this._props.childLayoutString}
renderDepth={this._props.renderDepth + 1}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
index 02131ae22..29d121974 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
@@ -210,8 +210,9 @@
border: 1px solid $medium-gray;
overflow-x: hidden;
overflow-y: auto;
- padding: 5px;
display: inline-flex;
+ padding: 0;
+ align-items: center;
}
.schema-row {
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index e22a666c5..227274a53 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -971,7 +971,7 @@ class CollectionSchemaViewDoc extends ObservableReactComponent<CollectionSchemaV
<DocumentView
key={this._props.doc[Id]}
{...this._props.schema._props}
- containerViewPath={this._props.schema.docViewPath}
+ containerViewPath={this._props.schema.childContainerViewPath}
LayoutTemplate={this._props.schema._props.childLayoutTemplate}
LayoutTemplateString={SchemaRowBox.LayoutString(this._props.schema._props.fieldKey, this._props.index)}
Document={this._props.doc}
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index 8e1fba699..3f94e7fc1 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -3,7 +3,7 @@ import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import * as React from 'react';
-import { CgClose } from 'react-icons/cg';
+import { CgClose, CgLock, CgLockUnlock } from 'react-icons/cg';
import { FaExternalLinkAlt } from 'react-icons/fa';
import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../../Utils';
import { Doc } from '../../../../fields/Doc';
@@ -121,6 +121,22 @@ export class SchemaRowBox extends ViewBoxBaseComponent<FieldViewProps & SchemaRo
pointerEvents: !this._props.isContentActive() ? 'none' : undefined,
}}>
<IconButton
+ tooltip="whether document interations are enabled"
+ icon={this.Document._lockedPosition ? <CgLockUnlock size="12px" /> : <CgLock size="12px" />}
+ size={Size.XSMALL}
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ undoable(e => {
+ e.stopPropagation();
+ Doc.toggleLockedPosition(this.Document);
+ }, 'Delete Row')
+ )
+ }></IconButton>
+ <IconButton
tooltip="close"
icon={<CgClose size={'16px'} />}
size={Size.XSMALL}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 83cabf355..73709c17e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -12,6 +12,7 @@ import { DocumentManager } from '../../util/DocumentManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
import { DocComponent } from '../DocComponent';
+import { ObservableReactComponent } from '../ObservableReactComponent';
import { StyleProp } from '../StyleProvider';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import './CollectionFreeFormDocumentView.scss';
@@ -37,7 +38,7 @@ export interface CollectionFreeFormDocumentViewWrapperProps extends DocumentView
CollectionFreeFormView: CollectionFreeFormView;
}
@observer
-export class CollectionFreeFormDocumentViewWrapper extends DocComponent<CollectionFreeFormDocumentViewWrapperProps & { fieldKey: string }>() implements CollectionFreeFormDocumentViewProps {
+export class CollectionFreeFormDocumentViewWrapper extends ObservableReactComponent<CollectionFreeFormDocumentViewWrapperProps> implements CollectionFreeFormDocumentViewProps {
constructor(props: any) {
super(props);
makeObservable(this);
@@ -59,6 +60,9 @@ export class CollectionFreeFormDocumentViewWrapper extends DocComponent<Collecti
CollectionFreeFormView = this.props.CollectionFreeFormView; // needed for type checking
RenderCutoffProvider = this.props.RenderCutoffProvider; // needed for type checking
+ get Document() {
+ return this._props.Document;
+ }
@computed get WrapperKeys() {
return Object.keys(this).filter(key => key.startsWith('w_')).map(key => key.replace('w_', ''))
.map(key => ({upper:key, lower:key[0].toLowerCase() + key.substring(1)})); // prettier-ignore
@@ -227,7 +231,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
});
}
- @action public float = () => {
+ float = () => {
const topDoc = this.Document;
const containerDocView = this._props.containerViewPath?.().lastElement();
const screenXf = containerDocView?.screenToContentsTransform();
@@ -253,8 +257,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
nudge = (x: number, y: number) => {
const [locX, locY] = this._props.ScreenToLocalTransform().transformDirection(x, y);
- this._props.Document.x = this._props.w_X() + locX;
- this._props.Document.y = this._props.w_Y() + locY;
+ this.Document.x = this._props.w_X() + locX;
+ this.Document.y = this._props.w_Y() + locY;
};
screenToLocalTransform = () =>
this._props
@@ -288,7 +292,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
zIndex: this._props.w_ZIndex?.(),
display: this._props.w_Width?.() ? undefined : 'none',
}}>
- {this._props.RenderCutoffProvider(this._props.Document) ? (
+ {this._props.RenderCutoffProvider(this.Document) ? (
<div style={{ position: 'absolute', width: this._props.PanelWidth(), height: this._props.PanelHeight(), background: 'lightGreen' }} />
) : (
<DocumentView {...passOnProps} CollectionFreeFormDocumentView={this.returnThis} styleProvider={this.styleProvider} ScreenToLocalTransform={this.screenToLocalTransform} isGroupActive={this.isGroupActive} />
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index e707bb836..500eb52ac 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -11,7 +11,7 @@ import { undoBatch } from '../../util/UndoManager';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
import { StyleProp } from '../StyleProvider';
import './ComparisonBox.scss';
-import { DocumentView } from './DocumentView';
+import { DocumentView, returnEmptyDocViewList } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { PinProps, PresBox } from './trails';
@@ -152,6 +152,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
if (property === StyleProp.PointerEvents) return 'none';
return this._props.styleProvider?.(doc, props, property);
};
+ @computed get childContainerViewPath() {
+ return this.DocumentView?.().docViewPath ?? returnEmptyDocViewList;
+ }
moveDoc1 = (doc: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true);
moveDoc2 = (doc: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true);
remDoc1 = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true);
@@ -178,7 +181,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
{...this._props}
Document={targetDoc}
TemplateDataDocument={undefined}
- containerViewPath={this.docViewPath}
+ containerViewPath={this.childContainerViewPath}
moveDocument={which.endsWith('1') ? this.moveDoc1 : this.moveDoc2}
removeDocument={which.endsWith('1') ? this.remDoc1 : this.remDoc2}
NativeWidth={returnZero}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 0d76959af..55859b92b 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -117,8 +117,6 @@ export class HTMLtag extends React.Component<HTMLtagProps> {
@observer
export class DocumentContentsView extends ObservableReactComponent<
FieldViewProps & {
- layout_fieldKey: string;
- LayoutTemplateString?: string;
onClick?: () => ScriptField;
LayoutTemplate?: () => Opt<Doc>;
}
@@ -132,8 +130,8 @@ export class DocumentContentsView extends ObservableReactComponent<
TraceMobx();
if (this._props.LayoutTemplateString) return this._props.LayoutTemplateString;
if (!this.layoutDoc) return '<p>awaiting layout</p>';
- if (this._props.layout_fieldKey === 'layout_keyValue') return StrCast(this._props.Document.layout_keyValue, KeyValueBox.LayoutString());
- const layout = Cast(this.layoutDoc[this.layoutDoc === this._props.Document && this._props.layout_fieldKey ? this._props.layout_fieldKey : StrCast(this.layoutDoc.layout_fieldKey, 'layout')], 'string');
+ if (this._props.fieldKey === 'layout_keyValue') return StrCast(this._props.Document.layout_keyValue, KeyValueBox.LayoutString());
+ const layout = Cast(this.layoutDoc[this.layoutDoc === this._props.Document && this._props.fieldKey ? this._props.fieldKey : StrCast(this.layoutDoc.layout_fieldKey, 'layout')], 'string');
if (layout === undefined) return this._props.Document.data ? "<FieldView {...props} fieldKey='data' />" : KeyValueBox.LayoutString();
if (typeof layout === 'string') return layout;
return '<p>Loading layout</p>';
@@ -141,12 +139,12 @@ export class DocumentContentsView extends ObservableReactComponent<
get layoutDoc() {
// bcz: replaced this with below : is it correct? change was made to accommodate passing fieldKey's from a layout script
- // const template: Doc = this._props.LayoutTemplate?.() || Doc.Layout(this._props.Document, this._props.layout_fieldKey ? Cast(this._props.Document[this._props.layout_fieldKey], Doc, null) : undefined);
+ // const template: Doc = this._props.LayoutTemplate?.() || Doc.Layout(this._props.Document, this._props.fieldKey ? Cast(this._props.Document[this._props.fieldKey], Doc, null) : undefined);
const template: Doc =
this._props.LayoutTemplate?.() ||
(this._props.LayoutTemplateString && this._props.Document) ||
- (this._props.layout_fieldKey && StrCast(this._props.Document[this._props.layout_fieldKey]) && this._props.Document) ||
- Doc.Layout(this._props.Document, this._props.layout_fieldKey ? Cast(this._props.Document[this._props.layout_fieldKey], Doc, null) : undefined);
+ (this._props.fieldKey && StrCast(this._props.Document[this._props.fieldKey]) && this._props.Document) ||
+ Doc.Layout(this._props.Document, this._props.fieldKey ? Cast(this._props.Document[this._props.fieldKey], Doc, null) : undefined);
return Doc.expandTemplateLayout(template, this._props.Document);
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 4e13b0ccb..444c300f3 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -89,6 +89,9 @@ export enum OpenWhere {
addRightKeyvalue = 'add:right:keyValue',
}
+export function returnEmptyDocViewList() {
+ return [] as DocumentView[];
+}
export interface DocFocusOptions {
willPan?: boolean; // determines whether to pan to target document
willZoomCentered?: boolean; // determines whether to zoom in on target document. if zoomScale is 0, this just centers the document
@@ -148,6 +151,7 @@ export interface DocComponentView {
* */
export interface DocumentViewSharedProps {
Document: Doc;
+ LayoutTemplateString?: string;
TemplateDataDocument?: Doc;
renderDepth: number;
scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
@@ -161,6 +165,7 @@ export interface DocumentViewSharedProps {
ignoreAutoHeight?: boolean;
disableBrushing?: boolean; // should highlighting for this view be disabled when same document in another view is hovered over.
CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView;
+ containerViewPath?: () => DocumentView[];
fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document
isGroupActive?: () => string | undefined; // is this document part of a group that is active
setContentView?: (view: DocComponentView) => any;
@@ -206,7 +211,6 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
hideLinkButton?: boolean;
hideCaptions?: boolean;
contentPointerEvents?: 'none' | 'all' | undefined; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents
- LayoutTemplateString?: string;
dontCenter?: 'x' | 'y' | 'xy';
childHideDecorationTitle?: boolean;
childHideResizeHandles?: boolean;
@@ -218,7 +222,6 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
NativeWidth?: () => number;
NativeHeight?: () => number;
LayoutTemplate?: () => Opt<Doc>;
- containerViewPath?: () => DocumentView[];
contextMenuItems?: () => { script: ScriptField; filter?: ScriptField; label: string; icon: string }[];
onClick?: () => ScriptField;
onDoubleClick?: () => ScriptField;
@@ -235,13 +238,13 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
* these props correspond to things that the DocumentView creates and thus doesn't need to receive as a prop
*/
export interface DocumentViewInternalSharedProps {
- DocumentView: () => DocumentView;
select: (ctrlPressed: boolean, shiftPress?: boolean) => void;
isSelected: () => boolean;
+ docViewPath: () => DocumentView[];
NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal
}
export interface DocumentViewInternalProps extends DocumentViewProps, DocumentViewInternalSharedProps {
- docViewPath: () => DocumentView[];
+ docViewPublic: () => DocumentView;
}
@observer
@@ -276,7 +279,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
} // this makes mobx trace() statements more descriptive
public get DocumentView() {
- return this._props.DocumentView;
+ return this._props.docViewPublic;
}
public get ContentDiv() {
@@ -426,15 +429,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
}
- defaultRestoreTargetView = (docView: DocumentView, anchor: Doc, focusSpeed: number, options: DocFocusOptions) => {
- const targetMatch =
- Doc.AreProtosEqual(anchor, this.Document) || // anchor is this document, so anchor's properties apply to this document
- (DocCast(anchor)?.layout_unrendered && Doc.AreProtosEqual(DocCast(anchor.annotationOn), this.Document)) // the anchor is an layout_unrendered annotation on this document, so anchor properties apply to this document
- ? true
- : false;
- return targetMatch && PresBox.restoreTargetDocView(docView, anchor, focusSpeed) ? focusSpeed : undefined;
- };
-
// switches text input focus to the title bar of the document (and displays the title bar if it hadn't been)
setTitleFocus = () => {
if (!StrCast(this.layoutDoc._layout_showTitle)) this.layoutDoc._layout_showTitle = 'title';
@@ -923,8 +917,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}}>
<DocumentContentsView
key={1}
- {...this._props}
- fieldKey=""
+ {...this.styleProps}
+ fieldKey={this.finalLayoutKey}
pointerEvents={this.contentPointerEvents}
setContentView={this.setContentView}
childFilters={this.childFilters}
@@ -935,7 +929,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
rootSelected={this.rootSelected}
onClick={this.onClickFunc}
setTitleFocus={this.setTitleFocus}
- layout_fieldKey={this.finalLayoutKey}
/>
{this.layoutDoc.layout_hideAllLinks ? null : this.allLinkEndpoints}
</div>
@@ -1699,7 +1692,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
}}>
<DocumentViewInternal
{...this._props}
- DocumentView={this.selfView}
+ docViewPublic={this.selfView}
docViewPath={this.docViewPath}
PanelWidth={this.PanelWidth}
PanelHeight={this.PanelHeight}
diff --git a/src/client/views/nodes/LabelBox.scss b/src/client/views/nodes/LabelBox.scss
index 42e158584..0b195713d 100644
--- a/src/client/views/nodes/LabelBox.scss
+++ b/src/client/views/nodes/LabelBox.scss
@@ -18,6 +18,9 @@
display: inline-block;
margin: auto;
text-overflow: ellipsis;
+ > span {
+ max-height: 100%; // make sure top of text is in view, otherwise it would center on middle of large text span
+ }
}
.labelBox-params {
@@ -29,4 +32,4 @@
width: 100%;
background: lightgray;
border: dimgray solid 1px;
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 934bce448..cc7c15a10 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -1,7 +1,7 @@
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast } from '../../../fields/Doc';
+import { Doc, DocListCast, Field } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
@@ -43,7 +43,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps & LabelBoxProp
}
@computed get Title() {
- return this.dataDoc.title_custom ? StrCast(this.Document.title) : this._props.label ? this._props.label : typeof this.dataDoc[this.fieldKey] === 'string' ? StrCast(this.dataDoc[this.fieldKey]) : StrCast(this.Document.title);
+ return this.dataDoc.title_custom ? StrCast(this.Document.title) : this._props.label ? this._props.label : Field.toString(this.dataDoc[this.fieldKey] as Field);
}
protected createDropTarget = (ele: HTMLDivElement) => {
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index 864c1955b..362a7def1 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -33,15 +33,16 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps & ViewBox
}
@computed get linkSource() {
- return this.containerViewPath?.().lastElement().Document; // this._props.styleProvider?.(this.dataDoc, this._props, StyleProp.LinkSource);
+ return this.DocumentView?.().containerViewPath?.().lastElement().Document; // this._props.styleProvider?.(this.dataDoc, this._props, StyleProp.LinkSource);
}
onPointerDown = (e: React.PointerEvent) => {
const linkSource = this.linkSource;
- linkSource && setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, (e, doubleTap) => {
- if (doubleTap) LinkFollower.FollowLink(this.Document, linkSource, false);
- else this._props.select(false);
- });
+ linkSource &&
+ setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, (e, doubleTap) => {
+ if (doubleTap) LinkFollower.FollowLink(this.Document, linkSource, false);
+ else this._props.select(false);
+ });
};
onPointerMove = action((e: PointerEvent, down: number[], delta: number[]) => {
const cdiv = this._ref?.current?.parentElement;
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 4221f464d..ba34255dc 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -29,12 +29,12 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get anchor1() {
const anchor1 = DocCast(this.dataDoc.link_anchor_1);
const anchor_1 = anchor1?.layout_unrendered ? DocCast(anchor1.annotationOn) : anchor1;
- return DocumentManager.Instance.getDocumentView(anchor_1, this.containerViewPath?.().lastElement());
+ return DocumentManager.Instance.getDocumentView(anchor_1, this.DocumentView?.().containerViewPath?.().lastElement());
}
@computed get anchor2() {
const anchor2 = DocCast(this.dataDoc.link_anchor_2);
const anchor_2 = anchor2?.layout_unrendered ? DocCast(anchor2.annotationOn) : anchor2;
- return DocumentManager.Instance.getDocumentView(anchor_2, this.containerViewPath?.().lastElement());
+ return DocumentManager.Instance.getDocumentView(anchor_2, this.DocumentView?.().containerViewPath?.().lastElement());
}
screenBounds = () => {
if (this.layoutDoc._layout_isSvg && this.anchor1 && this.anchor2 && this.anchor1.CollectionFreeFormView) {
@@ -66,7 +66,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
const a = (this.anchor1 ?? this.anchor2)!;
const b = (this.anchor2 ?? this.anchor1)!;
- const parxf = this.containerViewPath?.().lastElement().ComponentView as CollectionFreeFormView;
+ const parxf = this.DocumentView?.().containerViewPath?.().lastElement().ComponentView as CollectionFreeFormView;
const this_xf = parxf?.screenToFreeformContentsXf ?? Transform.Identity; //this.ScreenToLocalTransform();
const a_invXf = a.screenToViewTransform().inverse();
const b_invXf = b.screenToViewTransform().inverse();
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 71c1b6a4c..7696a45a0 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -581,6 +581,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}}>
<PDFViewer
{...this._props}
+ pdfBox={this}
sidebarAddDoc={this.sidebarAddDocument}
addDocTab={this.sidebarAddDocTab}
layoutDoc={this.layoutDoc}
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 61576a498..4ae12505e 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -11,7 +11,7 @@ import { DocServer } from '../../../DocServer';
import { Docs, DocUtils } from '../../../documents/Documents';
import { Transform } from '../../../util/Transform';
import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { DocFocusOptions, DocumentView } from '../DocumentView';
+import { DocFocusOptions, DocumentView, returnEmptyDocViewList } from '../DocumentView';
import { FormattedTextBox } from './FormattedTextBox';
var horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side.
@@ -178,6 +178,9 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn
ele && (ele.style.backgroundColor = 'orange');
};
+ @computed get childContainerViewPath() {
+ return this._textBox.DocumentView?.().docViewPath ?? returnEmptyDocViewList;
+ }
componentWillUnmount = () => Object.values(this._disposers).forEach(disposer => disposer?.());
isContentActive = () => this._props.tbox._props.isContentActive() || this._props.tbox.isAnyChildContentActive?.();
@@ -207,7 +210,7 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn
isDocumentActive={returnFalse}
isContentActive={this.isContentActive}
styleProvider={this._textBox._props.styleProvider}
- containerViewPath={this._textBox.docViewPath ?? returnEmptyDoclist}
+ containerViewPath={this.childContainerViewPath}
ScreenToLocalTransform={this.getDocTransform}
addDocTab={this._textBox._props.addDocTab}
pinToPres={returnFalse}
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 3f2ab0ec5..dc9914637 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -148,7 +148,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi
}
createPivotForField = (e: React.MouseEvent) => {
- let container = this._props.tbox.containerViewPath?.().lastElement();
+ let container = this._props.tbox.DocumentView?.().containerViewPath?.().lastElement();
if (container) {
const embedding = Doc.MakeEmbedding(container.Document);
embedding._type_collection = CollectionViewType.Time;
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 8cf01b9de..4bc79176e 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -50,7 +50,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
// the presentation view that renders this slide
@computed get presBoxView() {
- return this.containerViewPath?.().lastElement()?.ComponentView as PresBox;
+ return this.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as PresBox;
}
// the presentation view document that renders this slide
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 89e5944f2..01590749e 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -21,11 +21,12 @@ import { DocFocusOptions, DocumentViewProps } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
import { LinkInfo } from '../nodes/LinkDocPreview';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { StyleProp, testDocProps } from '../StyleProvider';
+import { StyleProp } from '../StyleProvider';
import { AnchorMenu } from './AnchorMenu';
import { Annotation } from './Annotation';
import { GPTPopup } from './GPTPopup/GPTPopup';
import './PDFViewer.scss';
+import { PDFBox } from '../nodes/PDFBox';
const _global = (window /* browser */ || global) /* node */ as any;
//pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`;
@@ -33,6 +34,7 @@ const _global = (window /* browser */ || global) /* node */ as any;
Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.0.379/build/pdf.worker.mjs';
interface IViewerProps extends FieldViewProps {
+ pdfBox: PDFBox;
Document: Doc;
dataDoc: Doc;
layoutDoc: Doc;
@@ -313,7 +315,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
this._ignoreScroll = false;
if (this._scrollTimer) clearTimeout(this._scrollTimer); // wait until a scrolling pause, then create an anchor to audio
this._scrollTimer = setTimeout(() => {
- DocUtils.MakeLinkToActiveAudio(() => this._props.DocumentView?.().ComponentView?.getAnchor!(true)!, false);
+ DocUtils.MakeLinkToActiveAudio(() => this._props.pdfBox.getAnchor(true)!, false);
this._scrollTimer = undefined;
}, 200);
}
@@ -419,7 +421,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
@action
createTextAnnotation = (sel: Selection, selRange: Range) => {
if (this._mainCont.current) {
- this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToContentsTransform().RotateDeg)}deg)`;
+ this._mainCont.current.style.transform = `rotate(${NumCast(this._props.pdfBox.ScreenToLocalBoxXf().RotateDeg)}deg)`;
const boundingRect = this._mainCont.current.getBoundingClientRect();
const clientRects = selRange.getClientRects();
for (let i = 0; i < clientRects.length; i++) {
@@ -499,9 +501,8 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
opaqueFilter = () => [...this._props.childFilters(), Utils.noDragDocsFilter, ...(SnappingManager.CanEmbed && this._props.isContentActive() ? [] : [Utils.OpaqueBackgroundFilter])];
childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
if (doc instanceof Doc && property === StyleProp.PointerEvents) {
- const docProps = testDocProps(props) ? props : undefined;
if (this.inlineTextAnnotations.includes(doc) || this._props.isContentActive() === false) return 'none';
- const isInk = doc.layout_isSvg && !docProps?.LayoutTemplateString;
+ const isInk = doc.layout_isSvg && !props?.LayoutTemplateString;
return isInk ? 'visiblePainted' : 'all';
}
return this._props.styleProvider?.(doc, props, property);
@@ -589,7 +590,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
isNativeScaled={true}
annotationLayerScrollTop={NumCast(this._props.Document._layout_scrollTop)}
addDocument={this.addDocumentWrapper}
- docView={this._props.DocumentView!}
+ docView={this._props.pdfBox.DocumentView!}
finishMarquee={this.finishMarquee}
savedAnnotations={this.savedAnnotations}
selectionText={this.selectionText}
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 188b2eba4..5828313c8 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -22,7 +22,7 @@ import { CollectionDockingView } from '../collections/CollectionDockingView';
import { CollectionLinearView } from '../collections/collectionLinear';
import { DashboardView } from '../DashboardView';
import { Colors } from '../global/globalEnums';
-import { DocumentViewInternal } from '../nodes/DocumentView';
+import { DocumentViewInternal, returnEmptyDocViewList } from '../nodes/DocumentView';
import { DefaultStyleProvider } from '../StyleProvider';
import './TopBar.scss';
@@ -100,6 +100,7 @@ export class TopBar extends React.Component {
<div className="collectionMenu-contMenuButtons" style={{ height: '100%' }}>
<CollectionLinearView
Document={selDoc}
+ docViewPath={returnEmptyDocViewList}
fieldKey="data"
dropAction="embed"
styleProvider={DefaultStyleProvider}
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index d726f7064..9c2350bd0 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1245,6 +1245,11 @@ export namespace Doc {
: undefined;
}
+ export function toggleLockedPosition(doc: Doc) {
+ doc._lockedPosition = !doc._lockedPosition;
+ doc._pointerEvents = doc._lockedPosition ? 'none' : undefined;
+ }
+
export function deiconifyView(doc: Doc) {
StrCast(doc.layout_fieldKey).split('_')[1] === 'icon' && setNativeView(doc);
}