import { IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { Doc, DocListCast, Field } from "../../new_fields/Doc";
import { List } from "../../new_fields/List";
import { listSpec } from "../../new_fields/Schema";
import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField";
import { ComputedField } from "../../new_fields/ScriptField";
import { Cast, StrCast } from "../../new_fields/Types";
import { Utils } from "../../Utils";
import { DocServer } from "../DocServer";
import { CollectionViewType } from "../views/collections/CollectionView";
import { FormattedTextBox } from "../views/nodes/FormattedTextBox";
import React = require("react");
import * as ReactDOM from 'react-dom';
import "./DashFieldView.scss";
export class DashFieldView {
_fieldWrapper: HTMLDivElement; // container for label and value
constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
this._fieldWrapper = document.createElement("p");
this._fieldWrapper.style.width = node.attrs.width;
this._fieldWrapper.style.height = node.attrs.height;
this._fieldWrapper.style.fontWeight = "bold";
this._fieldWrapper.style.position = "relative";
this._fieldWrapper.style.display = "inline-block";
ReactDOM.render(, this._fieldWrapper);
(this as any).dom = this._fieldWrapper;
}
destroy() {
ReactDOM.unmountComponentAtNode(this._fieldWrapper);
}
}
interface IDashFieldViewInternal {
node: any,
view: any,
getPos: any,
tbox: FormattedTextBox
}
export class DashFieldViewInternal extends React.Component {
_reactionDisposer: IReactionDisposer | undefined;
_textBoxDoc?: Doc; //Added "?""
@observable _dashDoc: Doc | undefined;
_fieldKey?: string; //Added "?" and added "as string"
_options: Doc[] = [];
constructor(props: IDashFieldViewInternal) {
super(props)
this._fieldKey = this.props.node.attrs.fieldKey;
this._textBoxDoc = this.props.tbox.props.Document;
if (this.props.node.attrs.docid) {
DocServer.GetRefField(this.props.node.attrs.docid).
then(async dashDoc => dashDoc instanceof Doc && runInAction(() => this.setDashDoc(dashDoc)));
} else {
this.setDashDoc(this.props.tbox.props.DataDoc || this.props.tbox.dataDoc);
}
}
componentWillUnmount() {
this._reactionDisposer?.();
}
componentDidMount() {
var elementFieldCheck = document.getElementById("fieldCheckId") as HTMLInputElement;
if (elementFieldCheck) {
this._reactionDisposer = reaction(() => { // this reaction will update the displayed text whenever the document's fieldKey's value changes
const dashVal = this._dashDoc?.[this._fieldKey as string];
return StrCast(dashVal).startsWith(":=") || dashVal === "" ? Doc.Layout(this.props.tbox.props.Document)[this._fieldKey as string] : dashVal;
}, fval => {
const boolVal = Cast(fval, "boolean", null);
if (boolVal === true || boolVal === false) {
elementFieldCheck.checked = boolVal;
} else {
// elementFieldCheck.innerHTML = Field.toString(fval as Field) || "";
}
elementFieldCheck.style.display = (boolVal === true || boolVal === false) ? "inline-block" : "none";
elementFieldCheck.style.display = !(boolVal === true || boolVal === false) ? "inline-block" : "none";
}, { fireImmediately: true });
}
}
setDashDoc = (doc: Doc) => {
this._dashDoc = doc;
if (this._options?.length && !this._dashDoc[this._fieldKey as string]) {
this._dashDoc[this._fieldKey as string] = StrCast(this._options[0].title);
}
// NOTE: if the field key starts with "@", then the actual field key is stored in the field 'fieldKey' (removing the @).
this._fieldKey = this._fieldKey?.startsWith("@") ? StrCast(this.props.tbox.props.Document[StrCast(this._fieldKey as string).substring(1)]) : this._fieldKey as string;
// var elementlabelSpan = document.getElementById("labelSpanId") as HTMLElement;
// elementlabelSpan.innerHTML = `${this._fieldKey}: `;
// const fieldVal = Cast(this._dashDoc?.[this._fieldKey], "boolean", null);
// var elementfieldCheck = document.getElementById("fieldCheckId") as HTMLElement;
// elementfieldCheck.style.display = (fieldVal === true || fieldVal === false) ? "inline-block" : "none";
// elementfieldCheck.style.display = !(fieldVal === true || fieldVal === false) ? "inline-block" : "none";
};
updateText = (forceMatch: boolean) => {
var elementEnumarables = document.getElementById("enumarablesId") as HTMLElement;
elementEnumarables.style.display = "none";
var elementfieldSpan = document.getElementById("fieldSpanId") as HTMLElement;
const newText = elementfieldSpan.innerText.startsWith(":=") || elementfieldSpan.innerText.startsWith("=:=") ? ":=-computed-" : elementfieldSpan.innerText;
// look for a document whose id === the fieldKey being displayed. If there's a match, then that document
// holds the different enumerated values for the field in the titles of its collected documents.
// if there's a partial match from the start of the input text, complete the text --- TODO: make this an auto suggest box and select from a drop down.
DocServer.GetRefField(this._fieldKey as string).then(options => {
let modText = "";
(options instanceof Doc) && DocListCast(options.data).forEach(opt => (forceMatch ? StrCast(opt.title).startsWith(newText) : StrCast(opt.title) === newText) && (modText = StrCast(opt.title)));
var elementfieldSpan = document.getElementById("fieldSpanId") as HTMLElement;
if (modText) {
// elementfieldSpan.innerHTML = this._dashDoc![this._fieldKey as string] = modText;
Doc.addFieldEnumerations(this._textBoxDoc, this._fieldKey as string, []);
} // if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key
else if (elementfieldSpan.innerText.startsWith(":=")) {
this._dashDoc![this._fieldKey as string] = ComputedField.MakeFunction(elementfieldSpan.innerText.substring(2));
} else if (elementfieldSpan.innerText.startsWith("=:=")) {
Doc.Layout(this.props.tbox.props.Document)[this._fieldKey as string] = ComputedField.MakeFunction(elementfieldSpan.innerText.substring(3));
} else {
this._dashDoc![this._fieldKey as string] = newText;
}
});
};
onPointerDownEnumerables = async (e: any) => {
e.stopPropagation();
var elementfieldSpan = document.getElementById("fieldSpanId") as HTMLElement;
const collview = await Doc.addFieldEnumerations(this._textBoxDoc, this._fieldKey as string, [{ title: elementfieldSpan.innerText }]);
collview instanceof Doc && this.props.tbox.props.addDocTab(collview, "onRight");
};
onChangefieldCheck = (e: any) => {
this._dashDoc![this._fieldKey as string] = e.target.checked;
};
onKeyPressfieldSpan = function (e: any) { e.stopPropagation(); };
onKeyUpfieldSpan = function (e: any) { e.stopPropagation(); };
onMouseDownfieldSpan = function (e: any) {
e.stopPropagation();
var element = document.getElementById("enumerables") as HTMLElement;
element.style.display = "inline-block";
};
onBlurfieldSpan = (e: any) => { this.updateText(false); }; //Pas importé
onKeyDownfieldSpan = (e: any) => {
e.stopPropagation();
if ((e.key === "a" && e.ctrlKey) || (e.key === "a" && e.metaKey)) {
if (window.getSelection) {
const range = document.createRange();
var elementfieldSpan = document.getElementById("fieldSpanId") as HTMLElement;
range.selectNodeContents(elementfieldSpan);
window.getSelection()!.removeAllRanges();
window.getSelection()!.addRange(range);
}
e.preventDefault();
}
if (e.key === "Enter") {
e.preventDefault();
var elementfieldSpan = document.getElementById("fieldSpanId") as HTMLElement;
e.ctrlKey && Doc.addFieldEnumerations(this._textBoxDoc, this._fieldKey as string, [{ title: elementfieldSpan.innerText }]);
this.updateText(true); //added this
}
};
onPointerDownLabelSpan = (e: any) => {
e.stopPropagation();
let container = this.props.tbox.props.ContainingCollectionView;
while (container?.props.Document.isTemplateForField || container?.props.Document.isTemplateDoc) {
container = container.props.ContainingCollectionView;
}
if (container) {
const alias = Doc.MakeAlias(container.props.Document);
alias.viewType = CollectionViewType.Time;
let list = Cast(alias.schemaColumns, listSpec(SchemaHeaderField));
if (!list) {
alias.schemaColumns = list = new List();
}
list.map(c => c.heading).indexOf(this._fieldKey as string) === -1 && list.push(new SchemaHeaderField(this._fieldKey, "#f1efeb"));
list.map(c => c.heading).indexOf("text") === -1 && list.push(new SchemaHeaderField("text", "#f1efeb"));
alias._pivotField = this._fieldKey as string;
this.props.tbox.props.addDocTab(alias, "onRight");
}
};
destroy() {
this._reactionDisposer?.();
}
selectNode() { }
render() {
const fieldStyle = {
width: this.props.node.attrs.width,
height: this.props.node.attrs.height,
};
const fieldCheckStyle = {
minWidth: "12px",
position: 'relative' as 'relative',
display: 'none',
backgroundColor: "rgba(155, 155, 155, 0.24)"
};
const fieldSpanStyle = {
minWidth: "12px",
position: 'relative' as 'relative',
display: 'none',
backgroundColor: "rgba(155, 155, 155, 0.24)"
};
const labelSpanStyle = {
position: 'relative' as 'relative',
display: 'inline-block',
backgroundColor: "rgba(155, 155, 155, 0.44)",
fontSize: "small",
title: "click to see related tags"
};
const fieldCheckId = Utils.GenerateGuid();
const fieldSpanId = Utils.GenerateGuid();
return (
)
}
}