aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx19
-rw-r--r--src/client/views/nodes/FilterBox.tsx48
-rw-r--r--src/client/views/nodes/PresBox.tsx16
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx82
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx13
5 files changed, 94 insertions, 84 deletions
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 67e7c1986..e8c3662aa 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -114,22 +114,13 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
}> {
@computed get layout(): string {
TraceMobx();
- if (!this.layoutDoc) return "<p>awaiting layout</p>";
- // const layout = Cast(this.layoutDoc[StrCast(this.layoutDoc.layoutKey, this.layoutDoc === this.props.Document ? this.props.layoutKey : "layout")], "string"); // bcz: replaced this with below... is it right?
if (this.props.LayoutTemplateString) return this.props.LayoutTemplateString;
+ if (!this.layoutDoc) return "<p>awaiting layout</p>";
+ if (this.props.layoutKey === "layout_keyValue") return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString("data"));
const layout = Cast(this.layoutDoc[this.layoutDoc === this.props.Document && this.props.layoutKey ? this.props.layoutKey : StrCast(this.layoutDoc.layoutKey, "layout")], "string");
- if (this.props.layoutKey === "layout_keyValue") {
- return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString("data"));
- } else
- if (layout === undefined) {
- return this.props.Document.data ?
- "<FieldView {...props} fieldKey='data' />" :
- KeyValueBox.LayoutString(this.layoutDoc.proto ? "proto" : "");
- } else if (typeof layout === "string") {
- return layout;
- } else {
- return "<p>Loading layout</p>";
- }
+ if (layout === undefined) return this.props.Document.data ? "<FieldView {...props} fieldKey='data' />" : KeyValueBox.LayoutString(this.layoutDoc.proto ? "proto" : "");
+ if (typeof layout === "string") return layout;
+ return "<p>Loading layout</p>";
}
get dataDoc() {
diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx
index 748af89ef..067477dcf 100644
--- a/src/client/views/nodes/FilterBox.tsx
+++ b/src/client/views/nodes/FilterBox.tsx
@@ -19,6 +19,7 @@ import { SearchBox } from "../search/SearchBox";
import { FieldView, FieldViewProps } from './FieldView';
import './FilterBox.scss';
import { Scripting } from "../../util/Scripting";
+import { values } from "lodash";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -49,6 +50,39 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
this.allDocs.forEach(doc => SearchBox.documentKeys(doc).filter(key => keys.add(key)));
return Array.from(keys.keys()).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("_") && !key.startsWith("acl")) || noviceFields.includes(key)).sort();
}
+
+ gatherFieldValues(dashboard: Doc, facetKey: string) {
+ const childDocs = DocListCast((dashboard.data as any)[0].data);
+ const valueSet = new Set<string>();
+ let rtFields = 0;
+ childDocs.forEach((d) => {
+ const facetVal = d[facetKey];
+ if (facetVal instanceof RichTextField) rtFields++;
+ valueSet.add(Field.toString(facetVal as Field));
+ const fieldKey = Doc.LayoutFieldKey(d);
+ const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView");
+ const data = d[annos ? fieldKey + "-annotations" : fieldKey];
+ if (data !== undefined) {
+ let subDocs = DocListCast(data);
+ if (subDocs.length > 0) {
+ let newarray: Doc[] = [];
+ while (subDocs.length > 0) {
+ newarray = [];
+ subDocs.forEach((t) => {
+ const facetVal = t[facetKey];
+ if (facetVal instanceof RichTextField) rtFields++;
+ valueSet.add(Field.toString(facetVal as Field));
+ const fieldKey = Doc.LayoutFieldKey(t);
+ const annos = !Field.toString(Doc.LayoutField(t) as Field).includes("CollectionView");
+ DocListCast(t[annos ? fieldKey + "-annotations" : fieldKey]).forEach((newdoc) => newarray.push(newdoc));
+ });
+ subDocs = newarray;
+ }
+ }
+ }
+ });
+ return { strings: Array.from(valueSet.keys()), rtFields };
+ }
/**
* Responds to clicking the check box in the flyout menu
*/
@@ -73,17 +107,11 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
}
} else {
const allCollectionDocs = DocListCast((targetDoc.data as any)[0].data);
- var rtfields = 0;
- const facetValues = Array.from(allCollectionDocs.reduce((set, child) => {
- const field = child[facetHeader] as Field;
- const fieldStr = Field.toString(field);
- if (field instanceof RichTextField || (typeof (field) === "string" && fieldStr.split(" ").length > 2)) rtfields++;
- return set.add(fieldStr);
- }, new Set<string>()));
+ const facetValues = this.gatherFieldValues(targetDoc, facetHeader);
let nonNumbers = 0;
let minVal = Number.MAX_VALUE, maxVal = -Number.MAX_VALUE;
- facetValues.map(val => {
+ facetValues.strings.map(val => {
const num = Number(val);
if (Number.isNaN(num)) {
nonNumbers++;
@@ -93,13 +121,13 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
}
});
let newFacet: Opt<Doc>;
- if (facetHeader === "text" || rtfields / allCollectionDocs.length > 0.1) {
+ if (facetHeader === "text" || facetValues.rtFields / allCollectionDocs.length > 0.1) {
newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, forceActive: true, ignoreClick: true });
Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
newFacet._textBoxPadding = 4;
const scriptText = `setDocFilter(this?.target, "${facetHeader}", text, "match")`;
newFacet.onTextChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, text: "string" });
- } else if (facetHeader !== "tags" && nonNumbers / facetValues.length < .1) {
+ } else if (facetHeader !== "tags" && nonNumbers / facetValues.strings.length < .1) {
newFacet = Docs.Create.SliderDocument({ title: facetHeader, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", treeViewOpen: true });
const newFacetField = Doc.LayoutFieldKey(newFacet);
const ranged = Doc.readDocRangeFilter(targetDoc, facetHeader);
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index c5a64af3e..7eca09f8c 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -265,19 +265,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
this.layoutDoc.presCollection = srcContext;
} else if (targetDoc) this.layoutDoc.presCollection = targetDoc;
}
- if (collectionDocView) {
- if (srcContext && srcContext !== presCollection) {
- // Case 1: new srcContext inside of current collection so add a new tab to the current pres collection
- collectionDocView.props.addDocTab(srcContext, "inPlace");
- }
- }
+ // if (collectionDocView) {
+ // if (srcContext && srcContext !== presCollection) {
+ // // Case 1: new srcContext inside of current collection so add a new tab to the current pres collection
+ // collectionDocView.props.addDocTab(srcContext, "inPlace");
+ // }
+ // }
this.updateCurrentPresentation();
const docToJump = curDoc;
const willZoom = false;
// If openDocument is selected then it should open the document for the user
if (activeItem.openDocument) {
- this.props.addDocTab(activeItem, "replace:right");
+ collectionDocView ? collectionDocView.props.addDocTab(activeItem, "inPlace") : this.props.addDocTab(activeItem, "replace:right");
} else
//docToJump stayed same meaning, it was not in the group or was the last element in the group
if (activeItem.zoomProgressivize && this.rootDoc.presStatus !== 'edit') {
@@ -1047,7 +1047,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
activeItem.presPinViewX = x;
activeItem.presPinViewY = y;
activeItem.presPinViewScale = scale;
- }}>Update</div> : (null)};
+ }}>Update</div> : (null)}
</div>
<div style={{ display: activeItem.presPinView ? "block" : "none" }}>
<div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index ff2ce90b7..e92efd708 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1189,7 +1189,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this.endUndoTypingBatch();
Object.values(this._disposers).forEach(disposer => disposer?.());
this._editorView?.destroy();
- FormattedTextBoxComment.Hide();
+ FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
}
_downEvent: any;
@@ -1522,16 +1522,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
render() {
TraceMobx();
+ const selected = this.props.isSelected();
+ const active = this.active();
const scale = this.props.hideOnLeave ? 1 : this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc._isBackground;
- this.props.isSelected() && setTimeout(() => this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props), 0); // need to make sure that we update a text box that is selected after updating the one that was deselected
- if (!this.props.isSelected() && FormattedTextBoxComment.textBox === this) {
- setTimeout(() => FormattedTextBoxComment.Hide(), 0);
- }
+ selected && setTimeout(() => this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props)); // need to make sure that we update a text box that is selected after updating the one that was deselected
+ if (!selected && FormattedTextBoxComment.textBox === this) { FormattedTextBoxComment.Hide(); }
const minimal = this.props.ignoreAutoHeight;
- const selPad = (this.props.isSelected() && !this.layoutDoc._singleLine) || minimal ? -10 : 0;
- const selclass = this.props.isSelected() && !this.layoutDoc._singleLine ? "-selected" : "";
+ const selPad = (selected && !this.layoutDoc._singleLine) || minimal ? -10 : 0;
+ const selclass = selected && !this.layoutDoc._singleLine ? "-selected" : "";
return (
<div className={"formattedTextBox-cont"} ref={this._boxRef}
style={{
@@ -1564,65 +1564,53 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
onMouseUp={this.onMouseUp}
onWheel={this.onPointerWheel}
onPointerEnter={action(() => this._entered = true)}
- onPointerLeave={action((e: React.PointerEvent<HTMLDivElement>) => {
+ onPointerLeave={action(e => {
this._entered = false;
const target = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y);
for (let child: any = target; child; child = child?.parentElement) {
- if (child === this._ref.current!) {
- this._entered = true;
- }
+ child === this._ref.current! && (this._entered = true);
}
})}
onDoubleClick={this.onDoubleClick}
>
<div className={`formattedTextBox-outer`} ref={this._scrollRef}
- style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.active() ? "none" : undefined }}
+ style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !active ? "none" : undefined }}
onScroll={this.onscrolled} onDrop={this.ondrop} >
<div className={minimal ? "formattedTextBox-minimal" : `formattedTextBox-inner${rounded}${selclass}`} ref={this.createDropTarget}
style={{
overflow: this.layoutDoc._singleLine ? "hidden" : undefined,
padding: this.layoutDoc._textBoxPadding ? StrCast(this.layoutDoc._textBoxPadding) :
`${Math.max(0, NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0) + selPad)}px ${NumCast(this.layoutDoc._xMargin, this.props.xMargin || 0) + selPad}px`,
- pointerEvents: !this.props.active() ? ((this.layoutDoc.isLinkButton || this.props.onClick) ? "none" : undefined) : undefined
+ pointerEvents: !active ? ((this.layoutDoc.isLinkButton || this.props.onClick) ? "none" : undefined) : undefined
}}
/>
</div>
- {!this.layoutDoc._showSidebar ? (null) : <>
- <div className={"formattedTextBox-sidebar" + (Doc.GetSelectedTool() !== InkTool.None ? "-inking" : "")}
- style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
- {this.sidebarWidthPercent === "0%" ? (null) :
- <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
- PanelHeight={this.active() ? () => 1000 : this.props.PanelHeight}
- PanelWidth={this.sidebarWidth}
- scaleField={this.annotationKey + "-scale"}
- annotationsKey={this.annotationKey}
- isAnnotationOverlay={true}
- focus={this.props.focus}
- isSelected={this.props.isSelected}
- select={emptyFunction}
- active={this.annotationsActive}
- ContentScaling={returnOne}
- whenActiveChanged={this.whenActiveChanged}
- removeDocument={this.removeDocument}
- moveDocument={this.moveDocument}
- addDocument={this.addDocument}
- CollectionView={undefined}
- ScreenToLocalTransform={this.sidebarScreenToLocal}
- renderDepth={this.props.renderDepth + 1}
- ContainingCollectionDoc={this.props.ContainingCollectionDoc} />
- }
- </div>
- {this.props.isSelected() ? <div className="formattedTextBox-sidebar-handle" style={{ left: `max(0px, calc(100% - ${this.sidebarWidthPercent} - 5px))` }} onPointerDown={this.sidebarDown} /> : (null)}
- </>}
+ {!this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) :
+ <div className={"formattedTextBox-sidebar" + (Doc.GetSelectedTool() !== InkTool.None ? "-inking" : "")} style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
+ <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
+ PanelHeight={active ? () => 1000 : this.props.PanelHeight}
+ PanelWidth={this.sidebarWidth}
+ scaleField={this.annotationKey + "-scale"}
+ annotationsKey={this.annotationKey}
+ isAnnotationOverlay={true}
+ focus={this.props.focus}
+ isSelected={this.props.isSelected}
+ select={emptyFunction}
+ active={this.annotationsActive}
+ ContentScaling={returnOne}
+ whenActiveChanged={this.whenActiveChanged}
+ removeDocument={this.removeDocument}
+ moveDocument={this.moveDocument}
+ addDocument={this.addDocument}
+ CollectionView={undefined}
+ ScreenToLocalTransform={this.sidebarScreenToLocal}
+ renderDepth={this.props.renderDepth + 1}
+ ContainingCollectionDoc={this.props.ContainingCollectionDoc} />
+ </div>}
+ {selected ? <div className="formattedTextBox-sidebar-handle" style={{ left: `max(0px, calc(100% - ${this.sidebarWidthPercent} - 5px))` }} onPointerDown={this.sidebarDown} /> : (null)}
{!this.layoutDoc._showAudio ? (null) :
<div className="formattedTextBox-dictation" onClick={action(e => this._recording = !this._recording)} >
- <FontAwesomeIcon className="formattedTextBox-audioFont"
- style={{
- color: this._recording ? "red" : "blue",
- transitionDelay: "0.6s",
- opacity: this._recording ? 1 : 0.25,
- }}
- icon={"microphone"} size="sm" />
+ <FontAwesomeIcon className="formattedTextBox-audioFont" style={{ color: this._recording ? "red" : "blue", transitionDelay: "0.6s", opacity: this._recording ? 1 : 0.25, }} icon={"microphone"} size="sm" />
</div>}
</div>
</div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index a37210de6..14bbee1ac 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -143,9 +143,12 @@ export class FormattedTextBoxComment {
public static Hide() {
FormattedTextBoxComment.textBox = undefined;
- FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
- ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText);
FormattedTextBoxComment.linkDoc = undefined;
+ FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
+ try {
+ ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText);
+ FormattedTextBoxComment.tooltip.removeChild(FormattedTextBoxComment.tooltipText);
+ } catch (e) { }
}
public static SetState(textBox: any, start: number, end: number, mark: Mark) {
FormattedTextBoxComment.textBox = textBox;
@@ -228,17 +231,17 @@ export class FormattedTextBoxComment {
if (forceUrl || (href && child && nbef && naft && mark?.attrs.showPreview)) {
try {
ReactDOM.unmountComponentAtNode(FormattedTextBoxComment.tooltipText);
+ FormattedTextBoxComment.tooltip.removeChild(FormattedTextBoxComment.tooltipText);
} catch (e) { }
- FormattedTextBoxComment.tooltip.removeChild(FormattedTextBoxComment.tooltipText);
FormattedTextBoxComment.tooltipText = document.createElement("div");
FormattedTextBoxComment.tooltipText.style.width = "100%";
FormattedTextBoxComment.tooltipText.style.height = "100%";
FormattedTextBoxComment.tooltipText.style.textOverflow = "ellipsis";
FormattedTextBoxComment.tooltipText.style.cursor = "pointer";
- FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
-
FormattedTextBoxComment.tooltipText.textContent = "URL: " + href;
(FormattedTextBoxComment.tooltipText as any).href = href;
+ FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
+
if (href.startsWith("https://en.wikipedia.org/wiki/")) {
wiki().page(href.replace("https://en.wikipedia.org/wiki/", "")).then(page => page.summary().then(summary => FormattedTextBoxComment.tooltipText.textContent = summary.substring(0, 500)));
} else {