import { observable, computed, action } from "mobx";
import React = require("react");
import { SelectionManager } from "../../util/SelectionManager";
import { observer } from "mobx-react";
import './LinkEditor.scss';
import { props } from "bluebird";
import { DocumentView } from "./DocumentView";
import { link } from "fs";
import { StrCast, Cast } from "../../../new_fields/Types";
import { Doc } from "../../../new_fields/Doc";
import { List } from "../../../new_fields/List";
import { listSpec } from "../../../new_fields/Schema";
import { LinkManager, LinkUtils } from "../../util/LinkManager";
import { Docs } from "../../documents/Documents";
import { Utils } from "../../../Utils";
import { faArrowLeft, faEllipsisV } from '@fortawesome/free-solid-svg-icons';
import { library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { string } from "prop-types";
library.add(faArrowLeft);
library.add(faEllipsisV);
// this dropdown could be generalizeds
@observer
class LinkGroupsDropdown extends React.Component<{ groupId: string, groupType: string, setGroup: (groupId: string, group: string) => void }> {
@observable private _searchTerm: string = "";
@observable private _groupType: string = this.props.groupType;
@action
setSearchTerm(value: string) {
this._searchTerm = value;
}
@action
setGroupType(value: string) {
this._groupType = value;
}
createGroup(value: string) {
LinkManager.Instance.allGroups.set(value, []);
this.props.setGroup(this.props.groupId, value);
}
renderOptions = (): JSX.Element[] => {
let allGroups: string[], searchTerm: string, results: string[], exactFound: boolean;
if (this._searchTerm !== "") {
allGroups = Array.from(LinkManager.Instance.allGroups.keys());
searchTerm = this._searchTerm.toUpperCase();
results = allGroups.filter(group => group.toUpperCase().indexOf(searchTerm) > -1);
exactFound = results.findIndex(group => group.toUpperCase() === searchTerm) > -1;
} else {
results = [];
exactFound = false;
}
let options = [];
results.forEach(result => {
options.push(
{ this.props.setGroup(this.props.groupId, result); this.setGroupType(result); this.setSearchTerm("") }}>{result}
)
});
if (!exactFound && this._searchTerm !== "") {
options.push( { this.createGroup(this._searchTerm); this.setGroupType(this._searchTerm); this.setSearchTerm("") }}>Create new "{this._searchTerm}" group
)
}
return options;
}
render() {
return (
)
}
}
interface LinkEditorProps {
sourceDoc: Doc;
linkDoc: Doc;
// groups: Map;
// metadata: Map>;
showLinks: () => void;
}
@observer
export class LinkEditor extends React.Component {
@observable private _groups: Map = new Map();
@observable private _metadata: Map> = new Map();
constructor(props: LinkEditorProps) {
super(props);
let groups = new Map();
let metadata: Map> = new Map();
let groupList = (Doc.AreProtosEqual(props.sourceDoc, Cast(props.linkDoc.anchor1, Doc, new Doc))) ?
Cast(props.linkDoc.anchor1Groups, listSpec(Doc), []) : Cast(props.linkDoc.anchor2Groups, listSpec(Doc), []);
groupList.forEach(groupDoc => {
if (groupDoc instanceof Doc) {
let id = Utils.GenerateGuid();
groups.set(id, groupDoc);
let metadataMap = new Map();
let metadataDocs = Cast(groupDoc.proto!.metadata, listSpec(Doc), []);
metadataDocs.forEach(mdDoc => {
if (mdDoc && mdDoc instanceof Doc) { // TODO: handle promise doc
metadataMap.set(Utils.GenerateGuid(), mdDoc);
}
})
metadata.set(id, metadataMap);
} else {
// promise doc
}
})
this._groups = groups;
this._metadata = metadata;
}
// @action
// editGroup(groupId: string, value: string) {
// let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc;
// let groupDoc = this._groups.get(groupId);
// if (groupDoc) {
// groupDoc.proto!.type = value;
// LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, [groupDoc]);
// }
// }
@action
addGroup = (e: React.MouseEvent): void => {
// create new document for group
let groupDoc = Docs.TextDocument();
groupDoc.proto!.title = "";
groupDoc.proto!.metadata = new List([]);
this._groups.set(Utils.GenerateGuid(), groupDoc);
let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc;
LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, Array.from(this._groups.values()));
}
@action
setGroup = (groupId: string, group: string): void => {
let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc;
let groupDoc = this._groups.get(groupId);
if (groupDoc) {
groupDoc.proto!.type = group;
LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, [groupDoc]);
}
}
renderGroup(groupId: string, groupDoc: Doc) {
console.log("testing", groupDoc["strawberry"], groupDoc["type"]);
return (
{this.renderMetadata(groupId)}
)
}
@action
addMetadata = (groupType: string): void => {
let mdKeys = LinkManager.Instance.allGroups.get(groupType);
if (mdKeys) {
if (mdKeys.indexOf("new key") > -1) {
mdKeys.push("new key");
}
} else {
mdKeys = ["new key"];
}
LinkManager.Instance.allGroups.set(groupType, mdKeys);
console.log("md added", groupType, LinkManager.Instance.allGroups.get(groupType), LinkManager.Instance.allGroups);
// // create new metadata doc
// let mdDoc = Docs.TextDocument();
// mdDoc.proto!.title = "";
// mdDoc.proto!.value = "";
// // append to map
// let mdMap = this._metadata.get(groupId);
// if (mdMap) {
// mdMap.set(Utils.GenerateGuid(), mdDoc);
// } else {
// mdMap = new Map();
// mdMap.set(Utils.GenerateGuid(), mdDoc);
// }
// // add to internal representation of metadata
// this._metadata.set(groupId, mdMap);
// // add to internatal representation of group
// let groupDoc = this._groups.get(groupId);
// if (groupDoc) {
// groupDoc.proto!.metadata = new List(Array.from(mdMap.values()));
// this._groups.set(groupId, groupDoc);
// }
// // add to link doc
// let linkDoc = this.props.linkDoc.proto ? this.props.linkDoc.proto : this.props.linkDoc;
// LinkUtils.setAnchorGroups(linkDoc, this.props.sourceDoc, Array.from(this._groups.values()));
}
// @action
// editMetadataTitle(groupId: string, mdId: string, value: string) {
// let groupMd = this._metadata.get(groupId);
// if (groupMd) {
// let mdDoc = groupMd.get(mdId);
// if (mdDoc) {
// mdDoc.proto!.title = value;
// }
// }
// // set group and link?
// }
// @action
// editMetadataValue(groupId: string, mdId: string, value: string) {
// let groupMd = this._metadata.get(groupId);
// if (groupMd) {
// let mdDoc = groupMd.get(mdId);
// if (mdDoc) {
// mdDoc.proto!.value = value;
// }
// }
// // set group and link?
// }
renderMetadata(groupId: string) {
let metadata: Array = [];
let groupDoc = this._groups.get(groupId);
if (groupDoc) {
let mdDoc = Cast(groupDoc.proto!.metadata, Doc, new Doc);
let groupType = StrCast(groupDoc.proto!.type);
let groupMdKeys = LinkManager.Instance.allGroups.get(groupType);
console.log("rendering md", groupType, groupMdKeys, LinkManager.Instance.allGroups);
if (groupMdKeys) {
groupMdKeys.forEach(key => {
metadata.push(
:
)
})
}
}
// let metadataMap = this._metadata.get(groupId);
// if (metadataMap) {
// metadataMap.forEach((mdDoc, mdId) => {
// metadata.push(
//
// this.editMetadataTitle(groupId, mdId, e.target.value)}>
// :
// this.editMetadataValue(groupId, mdId, e.target.value)}>
//
// )
// })
// }
return metadata;
}
render() {
let destination = LinkUtils.findOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
let groups: Array = [];
this._groups.forEach((groupDoc, groupId) => {
groups.push(this.renderGroup(groupId, groupDoc))
});
return (
editing link to: {destination.proto!.title}
Groups:
{groups}
);
}
}