1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
import { Property } from 'csstype';
import { computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { DateField } from '../../../fields/DateField';
import { Doc, Field, FieldType, Opt } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { ScriptField } from '../../../fields/ScriptField';
import { WebField } from '../../../fields/URLField';
import { DragManager } from '../../util/DragManager';
import { dropActionType } from '../../util/DropActionTypes';
import { Transform } from '../../util/Transform';
import { ContextMenuProps } from '../ContextMenuItem';
import { PinProps } from '../PinFuncs';
import { ViewBoxInterface } from '../ViewBoxInterface';
import { DocumentView } from './DocumentView';
import { FocusViewOptions } from './FocusViewOptions';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
import { OpenWhere } from './OpenWhere';
export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt<number>;
export type StyleProviderFuncType = (
doc: Opt<Doc>,
// eslint-disable-next-line no-use-before-define
props: Opt<FieldViewProps>,
property: string
) =>
| Opt<FieldType>
| ContextMenuProps[]
| { clipPath: string; jsx: JSX.Element }
| JSX.Element
| JSX.IntrinsicElements
| null
| {
[key: string]:
| {
color: string;
icon: JSX.Element | string;
}
| undefined;
}
| { highlightStyle: string; highlightColor: string; highlightIndex: number; highlightStroke: boolean }
| undefined;
//
// these properties get assigned through the render() method of the DocumentView when it creates this node.
// However, that only happens because the properties are "defined" in the markup for the field view.
// See the LayoutString method on each field view : ImageBox, FormattedTextBox, etc.
//
export interface FieldViewSharedProps {
Document: Doc;
TemplateDataDocument?: Doc;
renderDepth: number;
scriptContext?: unknown; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
screenXPadding?: (view: DocumentView | undefined) => number; // padding in screen space coordinates (used by text box to reflow around UI buttons in carouselView)
xMargin?: number;
yMargin?: number;
dontRegisterView?: boolean;
dropAction?: dropActionType;
dragAction?: dropActionType;
forceAutoHeight?: boolean;
ignoreAutoHeight?: boolean;
disableBrushing?: boolean; // should highlighting for this view be disabled when same document in another view is hovered over.
hideClickBehaviors?: boolean; // whether to suppress menu item options for changing click behaviors
suppressSetHeight?: boolean;
dontCenter?: 'x' | 'y' | 'xy' | undefined;
LocalRotation?: () => number | undefined; // amount of rotation applied to freeformdocumentview containing document view
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
// eslint-disable-next-line no-use-before-define
setContentViewBox?: (view: ViewBoxInterface<FieldViewProps>) => void; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox
rejectDrop?: (de: DragManager.DropEvent, subView?: DocumentView) => boolean; // whether a document drop is rejected
PanelWidth: () => number;
PanelHeight: () => number;
isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events
isContentActive: () => boolean | undefined; // whether document contents should handle pointer events
dontSelect?: () => boolean | undefined;
childFilters: () => string[];
childFiltersByRanges: () => string[];
styleProvider: Opt<StyleProviderFuncType>;
setTitleFocus?: () => void;
focus: FocusFuncType;
onClickScript?: () => ScriptField | undefined;
onDoubleClickScript?: () => ScriptField | undefined;
onPointerDownScript?: () => ScriptField;
onPointerUpScript?: () => ScriptField;
onKey?: (e: KeyboardEvent, textBox: FormattedTextBox) => boolean | undefined;
fitWidth?: (doc: Doc) => boolean | undefined;
searchFilterDocs: () => Doc[];
showTitle?: () => string;
whenChildContentsActiveChanged: (isActive: boolean) => void;
rootSelected?: () => boolean; // whether the root of a template has been selected
addDocTab: (doc: Doc | Doc[], where: OpenWhere) => boolean;
filterAddDocument?: (doc: Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean;
removeDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean;
moveDocument?: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) => boolean;
pinToPres: (document: Doc, pinProps: PinProps) => void;
ScreenToLocalTransform: () => Transform;
bringToFront?: (doc: Doc, sendToBack?: boolean) => void;
waitForDoubleClickToClick?: () => 'never' | 'always' | undefined;
defaultDoubleClick?: () => 'default' | 'ignore' | undefined;
pointerEvents?: () => Opt<Property.PointerEvents>;
}
/**
* FieldView specific props that are not shared with DocumentView props
* */
export interface FieldViewProps extends FieldViewSharedProps {
DocumentView?: () => DocumentView;
isSelected: () => boolean;
select: (ctrlPressed: boolean, shiftPress?: boolean) => void;
docViewPath: () => DocumentView[];
setHeight?: (height: number) => void;
NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal
isHovering?: () => boolean;
fieldKey: string;
// properties intended to be used from within layout strings (otherwise use the function equivalents that work more efficiently with React)
// See currentUserUtils headerTemplate for examples of creating text boxes from html which set some of these fields
// Also, see InkingStroke for examples of creating text boxes from render() methods which set some of these fields
backgroundColor?: string;
color?: string;
height?: number;
width?: number;
dontSelectOnLoad?: boolean; // suppress selecting (e.g.,. text box) when loaded (and mark as not being associated with scrollTop document field)
noSidebar?: boolean;
dontScale?: boolean;
}
@observer
export class FieldView extends React.Component<FieldViewProps> {
public static LayoutString(fieldType: { name: string }, fieldStr: string) {
return `<${fieldType.name} {...props} fieldKey={'${fieldStr}'}/>`; // e.g., "<ImageBox {...props} fieldKey={'data'} />"
}
@computed get fieldval() {
return this.props.Document[this.props.fieldKey];
}
render() {
const field = this.fieldval;
// prettier-ignore
if (field instanceof Doc) return <p> <b>{field.title?.toString()}</b></p>;
if (field === undefined) return <p />;
if (field instanceof DateField) return <p>{field.date.toLocaleString()}</p>;
if (field instanceof List) return <div> {field.map(f => Field.toString(f)).join(', ')} </div>;
if (field instanceof WebField) return <p>{Field.toString(field.url.href)}</p>;
if (!(field instanceof Promise)) return <p>{Field.toString(field)}</p>;
return <p> Waiting for server... </p>;
}
}
|