aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--solr-8.3.1/server/solr/dash/conf/characters.txt3
-rw-r--r--solr-8.3.1/server/solr/dash/conf/schema.xml24
-rw-r--r--src/client/documents/Documents.ts2
-rw-r--r--src/client/util/CurrentUserUtils.ts2
-rw-r--r--src/client/util/DocumentManager.ts2
-rw-r--r--src/client/util/HypothesisUtils.ts2
-rw-r--r--src/client/util/SearchUtil.ts7
-rw-r--r--src/client/views/DocComponent.tsx2
-rw-r--r--src/client/views/DocumentButtonBar.tsx2
-rw-r--r--src/client/views/DocumentDecorations.scss2
-rw-r--r--src/client/views/GlobalKeyHandler.ts3
-rw-r--r--src/client/views/InkingStroke.tsx2
-rw-r--r--src/client/views/MainView.scss1
-rw-r--r--src/client/views/MainView.tsx34
-rw-r--r--src/client/views/PreviewCursor.tsx2
-rw-r--r--src/client/views/PropertiesButtons.tsx2
-rw-r--r--src/client/views/PropertiesView.tsx17
-rw-r--r--src/client/views/collections/CollectionDockingView.scss2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx10
-rw-r--r--src/client/views/collections/CollectionLinearView.scss2
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx12
-rw-r--r--src/client/views/collections/CollectionMenu.scss4
-rw-r--r--src/client/views/collections/CollectionMenu.tsx11
-rw-r--r--src/client/views/collections/CollectionSchemaHeaders.tsx2
-rw-r--r--src/client/views/collections/CollectionSchemaMovableTableHOC.tsx1
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx12
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx15
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx11
-rw-r--r--src/client/views/collections/TabDocView.scss4
-rw-r--r--src/client/views/collections/TabDocView.tsx81
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx2
-rw-r--r--src/client/views/linking/LinkMenu.scss2
-rw-r--r--src/client/views/linking/LinkMenu.tsx4
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx3
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx7
-rw-r--r--src/client/views/nodes/DocumentView.tsx11
-rw-r--r--src/client/views/nodes/FontIconBox.scss24
-rw-r--r--src/client/views/nodes/FontIconBox.tsx9
-rw-r--r--src/client/views/nodes/LabelBox.scss1
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx2
-rw-r--r--src/client/views/nodes/MenuIconBox.scss49
-rw-r--r--src/client/views/nodes/MenuIconBox.tsx33
-rw-r--r--src/client/views/nodes/WebBox.tsx6
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx2
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx2
-rw-r--r--src/client/views/pdf/PDFViewer.tsx12
-rw-r--r--src/client/views/search/SearchBox.tsx10
-rw-r--r--src/fields/Doc.ts6
-rw-r--r--src/fields/util.ts2
-rw-r--r--src/server/ApiManagers/SearchManager.ts2
-rw-r--r--src/server/Search.ts5
53 files changed, 228 insertions, 246 deletions
diff --git a/solr-8.3.1/server/solr/dash/conf/characters.txt b/solr-8.3.1/server/solr/dash/conf/characters.txt
new file mode 100644
index 000000000..3a4c81bc8
--- /dev/null
+++ b/solr-8.3.1/server/solr/dash/conf/characters.txt
@@ -0,0 +1,3 @@
+\# => ALPHA
+@ => ALPHA
+\u0023 => ALPHA \ No newline at end of file
diff --git a/solr-8.3.1/server/solr/dash/conf/schema.xml b/solr-8.3.1/server/solr/dash/conf/schema.xml
index 74c4b494c..11078caeb 100644
--- a/solr-8.3.1/server/solr/dash/conf/schema.xml
+++ b/solr-8.3.1/server/solr/dash/conf/schema.xml
@@ -5,19 +5,23 @@
<fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true">
<tokenizer class="solr.KeywordTokenizerFactory"/>
</fieldType>
- <fieldType name="text" class="solr.TextField">
+ <fieldType name="text" class="solr.TextField" positionIncrementGap="100" multiValued="true">
<analyzer type="index">
- <tokenizer class="solr.StandardTokenizerFactory"/>
- <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
- <filter class="solr.LowerCaseFilterFactory"/>
- <filter class="solr.PorterStemFilterFactory"/>
- <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="12"/>
+ <tokenizer class="solr.WhitespaceTokenizerFactory"/>
+ <!-- <tokenizer class="solr.StandardTokenizerFactory"/> -->
+ <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+ <filter class="solr.PorterStemFilterFactory"/>
+ <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="12"/>
+ <!-- <filter catenateAll="0" catenateNumbers="0" catenateWords="0" class="solr.WordDelimiterFilterFactory" generateNumberParts="1" generateWordParts="1" splitOnCaseChange="1" types="characters.txt"/> -->
</analyzer>
<analyzer type="query">
- <tokenizer class="solr.StandardTokenizerFactory"/>
- <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
- <filter class="solr.LowerCaseFilterFactory"/>
- <filter class="solr.PorterStemFilterFactory"/>
+ <tokenizer class="solr.WhitespaceTokenizerFactory"/>
+ <!-- <tokenizer class="solr.StandardTokenizerFactory"/> -->
+ <filter class="solr.StopFilterFactory" words="stopwords.txt"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+ <filter class="solr.PorterStemFilterFactory"/>
+ <!-- <filter catenateAll="0" catenateNumbers="0" catenateWords="0" class="solr.WordDelimiterFilterFactory" generateNumberParts="1" generateWordParts="1" splitOnCaseChange="1" types="characters.txt"/> -->
</analyzer>
</fieldType>
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true">
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 9a24a8052..feb84843d 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -178,7 +178,7 @@ export interface DocumentOptions {
clickFactory?: Doc; // document to create when clicking on a button with a suitable onClick script
onDragStart?: ScriptField; //script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop
clipboard?: Doc;
- UseCors?: boolean;
+ useCors?: boolean;
icon?: string;
target?: Doc; // available for use in scripts as the primary target document
sourcePanel?: Doc; // panel to display in 'targetContainer' as the result of a button onClick script
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 1b0747e9c..734050b05 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -439,7 +439,7 @@ export class CurrentUserUtils {
{ _width: 250, _height: 250, title: "container", system: true, cloneFieldFilter: new List<string>(["system"]) });
}
if (doc.emptyWebpage === undefined) {
- doc.emptyWebpage = Docs.Create.WebDocument("", { title: "webpage", _nativeWidth: 850, _nativeHeight: 962, _width: 400, UseCors: true, system: true, cloneFieldFilter: new List<string>(["system"]) });
+ doc.emptyWebpage = Docs.Create.WebDocument("", { title: "webpage", _nativeWidth: 850, _nativeHeight: 962, _width: 400, useCors: true, system: true, cloneFieldFilter: new List<string>(["system"]) });
}
if (doc.activeMobileMenu === undefined) {
this.setupActiveMobileMenu(doc);
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index f085f615c..2c7dcf49b 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -160,6 +160,8 @@ export class DocumentManager {
docView.props.Document.hidden = !docView.props.Document.hidden;
}
else {
+ const contView = docContext && getFirstDocView(docContext, originatingDoc);
+ contView && contView.topMost && contView.select(false); // bcz: change this to a function prop: popTab() that will make sure the tab for the document is topmost;
docView.select(false);
docView.props.Document.hidden && (docView.props.Document.hidden = undefined);
docView.props.focus(docView.props.Document, willZoom, undefined, focusAndFinish);
diff --git a/src/client/util/HypothesisUtils.ts b/src/client/util/HypothesisUtils.ts
index ddd2b89d1..4a5b52e1e 100644
--- a/src/client/util/HypothesisUtils.ts
+++ b/src/client/util/HypothesisUtils.ts
@@ -21,7 +21,7 @@ export namespace Hypothesis {
export const getSourceWebDoc = async (uri: string) => {
const result = await findWebDoc(uri);
console.log(result ? "existing doc found" : "existing doc NOT found");
- return result || Docs.Create.WebDocument(uri, { title: uri, _nativeWidth: 850, _nativeHeight: 962, _width: 400, UseCors: true }); // create and return a new Web doc with given uri if no matching docs are found
+ return result || Docs.Create.WebDocument(uri, { title: uri, _nativeWidth: 850, _nativeHeight: 962, _width: 400, useCors: true }); // create and return a new Web doc with given uri if no matching docs are found
};
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index afa8ff575..b09eff849 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -23,7 +23,7 @@ export namespace SearchUtil {
}
export interface SearchParams {
- hl?: boolean;
+ hl?: string;
"hl.fl"?: string;
start?: number;
rows?: number;
@@ -39,9 +39,10 @@ export namespace SearchUtil {
export async function Search(query: string, returnDocs: boolean, options: SearchParams = {}) {
query = query || "*"; //If we just have a filter query, search for * as the query
const rpquery = Utils.prepend("/dashsearch");
- let replacedQuery = query.replace(/type_t:([^ )])/g, (substring, arg) => `{!join from=id to=proto_i}type_t:${arg}`);
+ let replacedQuery = query.replace(/type_t:([^ )])/g, (substring, arg) => `{!join from=id to=proto_i}*:* AND ${arg}`);
if (options.onlyAliases) {
- replacedQuery = `{!join from=id to=proto_i}DEFAULT:${replacedQuery}`;
+ const header = query.match(/_[atnb]?:/) ? replacedQuery : "DEFAULT:" + replacedQuery;
+ replacedQuery = `{!join from=id to=proto_i}${header}`;
}
const gotten = await rp.get(rpquery, { qs: { ...options, q: replacedQuery } });
const result: IdSearchResult = gotten.startsWith("<") ? { ids: [], docs: [], numFound: 0, lines: [] } : JSON.parse(gotten);
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index e9469d7bb..aa888b34a 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -178,8 +178,6 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
added.map(doc => doc.context = this.props.Document);
(targetDataDoc[this.annotationKey] as List<Doc>).push(...added);
targetDataDoc[this.annotationKey + "-lastModified"] = new DateField(new Date(Date.now()));
- const lastModified = "lastModified";
- targetDataDoc[lastModified] = new DateField(new Date(Date.now()));
}
}
}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 32434490b..cf2bd5176 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -153,7 +153,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
e.preventDefault();
let googleDoc = await Cast(dataDoc.googleDoc, Doc);
if (!googleDoc) {
- const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, UseCors: false };
+ const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, useCors: false };
googleDoc = Docs.Create.WebDocument(googleDocUrl, options);
dataDoc.googleDoc = googleDoc;
}
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index 8291d7212..e02408559 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -21,7 +21,7 @@ $linkGap : 3px;
background: none;
}
- .documentDecorations-selector {
+ .documentDecorations-levelSelector {
pointer-events: auto;
height: 15px;
width: 15px;
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 076be3ad6..83c02b09b 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -196,7 +196,6 @@ export class KeyManager {
break;
case "f":
SearchBox.Instance._searchFullDB = "My Stuff";
- SearchBox.Instance.newsearchstring = "";
SearchBox.Instance.enter(undefined);
break;
case "o":
@@ -272,8 +271,6 @@ export class KeyManager {
undoBatch(() => {
targetDataDoc[fieldKey] = new List<Doc>([...docList, ...added]);
targetDataDoc[fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
- const lastModified = "lastModified";
- targetDataDoc[lastModified] = new DateField(new Date(Date.now()));
})();
}
}
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 1a1a3d75c..da98eca73 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -119,7 +119,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
const hpoints = InteractionUtils.CreatePolyline(data, left, top,
this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15),
StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"),
- "none", "none", undefined, scaleX, scaleY, "", this.props.active() ? "visiblepainted" : "none", false, true);
+ "none", "none", undefined, scaleX, scaleY, "", "visiblepainted", false, true);
//points for adding
const apoints = InteractionUtils.CreatePoints(data, left, top, strokeColor, strokeWidth, strokeWidth,
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 93cc47215..9ca8f348d 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -31,6 +31,7 @@
bottom: 10px;
left: calc(100% + 5px);
z-index: 1;
+ pointer-events: none;
}
.mainView-snapLines {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 4eccbaeb1..7c7c5b72b 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -55,6 +55,8 @@ import { PDFMenu } from './pdf/PDFMenu';
import { PreviewCursor } from './PreviewCursor';
import { PropertiesView } from './PropertiesView';
import { SearchBox } from './search/SearchBox';
+import { TraceMobx } from '../../fields/util';
+import { SelectionManager } from '../util/SelectionManager';
const _global = (window /* browser */ || global /* node */) as any;
@observer
@@ -152,7 +154,7 @@ export class MainView extends React.Component {
const targets = document.elementsFromPoint(e.x, e.y);
if (targets.length) {
const targClass = targets[0].className.toString();
- if (SearchBox.Instance._searchbarOpen) {
+ if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
const check = targets.some((thing) =>
(thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
thing.className === "collectionSchema-header-menuOptions"));
@@ -285,7 +287,7 @@ export class MainView extends React.Component {
setupMoveUpEvents(this, e,
action(e => (this._flyoutWidth = Math.max(e.clientX - 58, 0)) ? false : false),
() => this._flyoutWidth < 5 && this.closeFlyout(),
- this.toggleFlyout);
+ this.closeFlyout);
}
flyoutWidthFunc = () => this._flyoutWidth;
@@ -370,6 +372,7 @@ export class MainView extends React.Component {
@action
selectMenu = (button: Doc) => {
const title = StrCast(Doc.GetProto(button).title);
+ const closed = !this._flyoutWidth;
this.closeFlyout();
if (this._panelContent !== title || !this._flyoutWidth) {
switch (this._panelContent = title) {
@@ -378,15 +381,10 @@ export class MainView extends React.Component {
break;
case "Catalog":
SearchBox.Instance._searchFullDB = "My Stuff";
- SearchBox.Instance.newsearchstring = "";
SearchBox.Instance.enter(undefined);
break;
default:
- this._sidebarContent.proto = button.target as any;
- this.expandFlyout();
- button._backgroundColor = "lightgrey";
- button.color = "black";
- this._lastButton = button;
+ closed && this.expandFlyout(button);
}
}
return true;
@@ -424,8 +422,14 @@ export class MainView extends React.Component {
</div>;
}
- expandFlyout = action(() => this._flyoutWidth = (this._flyoutWidth || 250));
- toggleFlyout = action(() => this._flyoutWidth < 15 ? this.expandFlyout() : this.closeFlyout());
+ expandFlyout = action((button: Doc) => {
+ this._flyoutWidth = (this._flyoutWidth || 250);
+ this._sidebarContent.proto = button.target as any;
+ button._backgroundColor = "lightgrey";
+ button.color = "black";
+ this._lastButton = button;
+ });
+
closeFlyout = action(() => {
this._lastButton && (this._lastButton.color = "white");
this._lastButton && (this._lastButton._backgroundColor = "");
@@ -516,11 +520,18 @@ export class MainView extends React.Component {
</defs>
</svg>;
}
+ select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); };
@computed get search() {
+ TraceMobx();
return <div className="mainView-searchPanel">
- <DocumentView Document={CurrentUserUtils.MySearchPanelDoc}
+ <SearchBox Document={CurrentUserUtils.MySearchPanelDoc}
DataDoc={undefined}
+ fieldKey="data"
+ dropAction="move"
+ isSelected={returnTrue}
+ active={returnTrue}
+ select={this.select}
LibraryPath={emptyPath}
addDocument={undefined}
addDocTab={this.addDocTabFunc}
@@ -537,7 +548,6 @@ export class MainView extends React.Component {
PanelHeight={this.getPHeight}
renderDepth={0}
focus={emptyFunction}
- parentActive={returnTrue}
whenActiveChanged={emptyFunction}
bringToFront={emptyFunction}
docFilters={returnEmptyFilter}
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 37d837f59..1cadba18a 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -52,7 +52,7 @@ export class PreviewCursor extends React.Component<{}> {
else if (re.test(plain)) {
const url = plain;
undoBatch(() => PreviewCursor._addDocument(Docs.Create.WebDocument(url, {
- title: url, _width: 500, _height: 300, UseCors: true, x: newPoint[0], y: newPoint[1]
+ title: url, _width: 500, _height: 300, useCors: true, x: newPoint[0], y: newPoint[1]
})))();
}
else if (plain.startsWith("__DashDocId(") || plain.startsWith("__DashCloneId(")) {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 921822539..d66cba710 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -153,7 +153,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
e.preventDefault();
let googleDoc = await Cast(dataDoc.googleDoc, Doc);
if (!googleDoc) {
- const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, UseCors: false };
+ const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, useCors: false };
googleDoc = Docs.Create.WebDocument(googleDocUrl, options);
dataDoc.googleDoc = googleDoc;
}
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 7f075d2cd..67c26c392 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -178,9 +178,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const docs = SelectionManager.SelectedDocuments().length < 2 ? [this.dataDoc] : SelectionManager.SelectedDocuments().map(dv => dv.dataDoc);
docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)));
const rows: JSX.Element[] = [];
- const noviceReqFields = ["author", "creationDate"];
+ const noviceReqFields = ["author", "creationDate", "tags"];
const noviceLayoutFields = ["_curPage"];
- const noviceKeys = [...Array.from(Object.keys(ids)).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("ACL") && key !== "UseCors")),
+ const noviceKeys = [...Array.from(Object.keys(ids)).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("ACL"))),
...noviceReqFields, ...noviceLayoutFields];
for (const key of noviceKeys.sort()) {
const docvals = new Set<any>();
@@ -234,11 +234,20 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
docs.forEach(doc => {
if (value.indexOf(":") !== -1) {
const newVal = value[0].toUpperCase() + value.substring(1, value.length);
- KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
+ const splits = newVal.split(":");
+ KeyValueBox.SetField(doc, splits[0], splits[1], true);
+ const tags = StrCast(doc.tags, ":");
+ if (tags.includes(`${splits[0]}:`) && splits[1] === "undefined") {
+ KeyValueBox.SetField(doc, "tags", `"${tags.replace(splits[0] + ":", "")}"`, true);
+ }
return true;
} else if (value[0] === "#") {
const newVal = value + `:'${value}'`;
- KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
+ KeyValueBox.SetField(doc, value, `'${value}'`, true);
+ const tags = StrCast(doc.tags, ":");
+ if (!tags.includes(`#${value}:`)) {
+ KeyValueBox.SetField(doc, "tags", `"${tags + value + ':'}"`, true);
+ }
return true;
}
});
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index d3be1636d..96f5afcd9 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -70,7 +70,7 @@
margin: auto;
}
- .collectionDockingView-dragAsDocument {
+ .collectionDockingView-drag {
touch-action: none;
position: absolute;
padding-left: 5px;
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index d39ef5e80..a3d58f31d 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -173,7 +173,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
rowlayout.config.height = 50;
newContentItem.config.height = 50;
}
- } else if (instance._goldenLayout.root.contentItems[0].isColumn) { // if column
+ } else {// if (instance._goldenLayout.root.contentItems[0].isColumn) { // if column
switch (pullSide) {
case "top": instance._goldenLayout.root.contentItems[0].addChild(newContentItem, 0); break;
case "bottom": instance._goldenLayout.root.contentItems[0].addChild(newContentItem); break;
@@ -360,8 +360,8 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
}
stackCreated = (stack: any) => {
- stack.header.element.on('mousedown', (e: any) => {
- if (e.target === stack.header.element[0] && e.button === 2) {
+ stack.header?.element.on('mousedown', (e: any) => {
+ if (e.target === stack.header?.element[0] && e.button === 2) {
const emptyPane = CurrentUserUtils.EmptyPane;
emptyPane["dragFactory-count"] = NumCast(emptyPane["dragFactory-count"]) + 1;
CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([], {
@@ -370,14 +370,14 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
}
});
- stack.header.controlsContainer.find('.lm_close') //get the close icon
+ stack.header?.controlsContainer.find('.lm_close') //get the close icon
.off('click') //unbind the current click handler
.click(action(() => {
//if (confirm('really close this?')) {
stack.remove();
stack.contentItems.forEach((contentItem: any) => Doc.AddDocToList(CurrentUserUtils.MyRecentlyClosed, "data", contentItem.tab.DashDoc, undefined, true, true));
}));
- stack.header.controlsContainer.find('.lm_popout') //get the close icon
+ stack.header?.controlsContainer.find('.lm_popout') //get the close icon
.off('click') //unbind the current click handler
.click(action(() => {
// stack.config.fixed = !stack.config.fixed; // force the stack to have a fixed size
diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss
index f5c4299a9..ca72b98a5 100644
--- a/src/client/views/collections/CollectionLinearView.scss
+++ b/src/client/views/collections/CollectionLinearView.scss
@@ -4,10 +4,12 @@
.collectionLinearView-outer {
overflow: visible;
height: 100%;
+ pointer-events: none;
.collectionLinearView {
display: flex;
height: 100%;
+ align-items: center;
>span {
background: $dark-color;
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 866d7245a..9eaa02bf8 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -17,6 +17,7 @@ import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { LinkDescriptionPopup } from '../nodes/LinkDescriptionPopup';
import { Tooltip } from '@material-ui/core';
+import { all } from 'bluebird';
type LinearDocument = makeInterface<[typeof documentSchema,]>;
@@ -113,12 +114,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
const backgroundColor = StrCast(this.props.Document.backgroundColor, "black");
const color = StrCast(this.props.Document.color, "white");
- const menuOpener = <label htmlFor={`${guid}`} style={{
- background: backgroundColor === color ? "black" : backgroundColor,
- // width: "18px", height: "18px", fontSize: "12.5px",
- // transition: this.props.Document.linearViewIsExpanded ? "transform 0.2s" : "transform 0.5s",
- // transform: this.props.Document.linearViewIsExpanded ? "" : "rotate(45deg)"
- }}
+ const menuOpener = <label htmlFor={`${guid}`} style={{ pointerEvents: "all", cursor: "default", background: backgroundColor === color ? "black" : backgroundColor, }}
onPointerDown={e => e.stopPropagation()} >
<p>{BoolCast(this.props.Document.linearViewIsExpanded) ? "–" : "+"}</p>
</label>;
@@ -140,6 +136,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
const scalable = pair.layout.onClick || pair.layout.onDragStart;
return <div className={`collectionLinearView-docBtn` + (scalable ? "-scalable" : "")} key={pair.layout[Id]} ref={dref}
style={{
+ pointerEvents: "all",
width: scalable ? (nested ? pair.layout[WidthSym]() : this.dimension() - deltaSize) : undefined,
height: nested && pair.layout.linearViewIsExpanded ? pair.layout[HeightSym]() : this.dimension() - deltaSize,
}} >
@@ -194,9 +191,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
</span>
</Tooltip>
- {/* <FontAwesomeIcon icon="times-circle" size="lg" style={{ color: "red" }}
- onClick={this.exitLongLinks} /> */}
-
</span> : null}
</div>
</div>;
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index 21312e5f3..e36e5caa7 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -377,6 +377,7 @@
.antimodeMenu-button {
text-align: center;
display: block;
+ position: relative;
}
.color-previewI {
@@ -384,12 +385,15 @@
height: 20%;
bottom: 0;
position: absolute;
+ margin-left: 2px;
}
.color-previewII {
width: 80%;
height: 80%;
margin-left: 10%;
+ position: absolute;
+ bottom: 5;
}
.btn-group {
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index eaada32b0..b04c9c2eb 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -187,7 +187,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
immediate: undoBatch((source: Doc[]) => { this.target._docFilters = undefined; this.target._searchFilterDocs = undefined; }),
initialize: (button: Doc) => {
button['target-docFilters'] = Cast(Doc.UserDoc().mySearchPanelDoc, Doc, null)._docFilters instanceof ObjectField ? ObjectField.MakeCopy(Cast(Doc.UserDoc().mySearchPanelDoc, Doc, null)._docFilters as any as ObjectField) : undefined;
- button['target-searchFilterDocs'] = Cast(Doc.UserDoc().mySearchPanelDoc, Doc, null)._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(Cast(Doc.UserDoc().mySearchPanelDoc, Doc, null)._searchFilterDocs as any as ObjectField) : undefined;
+ button['target-searchFilterDocs'] = CurrentUserUtils.ActiveDashboard._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(CurrentUserUtils.ActiveDashboard._searchFilterDocs as any as ObjectField) : undefined;
},
};
@@ -901,15 +901,14 @@ export class CollectionStackingViewChrome extends React.Component<CollectionMenu
if (docs instanceof Doc) {
const keys = Object.keys(docs).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
- (key[0].toUpperCase() === key[0] && key.substring(0, 3) !== "ACL" && key !== "UseCors" && key[0] !== "_"));
+ (key[0].toUpperCase() === key[0] && key.substring(0, 3) !== "ACL" && key[0] !== "_"));
return keys.filter(key => key.toLowerCase().indexOf(val) > -1);
} else {
const keys = new Set<string>();
docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
- const noviceKeys = Array.from(keys).filter(key => key.indexOf("title") >= 0 ||
- key.indexOf("author") >= 0 || key.indexOf("creationDate") >= 0 ||
- key.indexOf("lastModified") >= 0 || (key[0]?.toUpperCase() === key[0] &&
- key.substring(0, 3) !== "ACL" && key !== "UseCors" && key[0] !== "_"));
+ const noviceKeys = Array.from(keys).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
+ key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
+ (key[0]?.toUpperCase() === key[0] && key.substring(0, 3) !== "ACL" && key[0] !== "_"));
return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1);
}
}
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index cecee1de3..94f9d4f92 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -352,7 +352,6 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
// if search term does not already exist as a group type, give option to create new group type
if (this._key !== this._searchTerm.slice(0, this._key.length)) {
- console.log("little further");
if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
options.push(<div key={""} className="key-option" style={{
border: "1px solid lightgray", width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white",
@@ -458,7 +457,6 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
updateFilter() {
const filters = Cast(this.props.Document._docFilters, listSpec("string"));
if (filters === undefined || filters.length === 0 || filters.includes(this._key) === false) {
- console.log("PLEASE");
this.props.col.setColor("rgb(241, 239, 235)");
this.closeResultsVisibility = "none";
}
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 383a9312f..881246bd4 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -201,6 +201,7 @@ export class MovableRow extends React.Component<MovableRowProps> {
}
onRowContextMenu = (e: React.MouseEvent): void => {
+ e.preventDefault();
const description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row";
ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original), icon: "file-pdf" });
}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 04c464b73..e4bb8302f 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -344,9 +344,11 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
sectionStacking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
const key = this.pivotField;
let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
- const types = docList.length ? docList.map(d => typeof d[key]) : this.filteredChildren.map(d => typeof d[key]);
- if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
- type = types[0];
+ if (this.pivotField) {
+ const types = docList.length ? docList.map(d => typeof d[key]) : this.filteredChildren.map(d => typeof d[key]);
+ if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
+ type = types[0];
+ }
}
const cols = () => this.isStackingView ? 1 : Math.max(1, Math.min(this.filteredChildren.length,
Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
@@ -364,10 +366,10 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
this.observer.observe(ref);
}
}}
- key={heading ? heading.heading : ""}
+ key={heading?.heading ?? ""}
cols={cols}
headings={this.headings}
- heading={heading ? heading.heading : ""}
+ heading={heading?.heading ?? ""}
headingObject={heading}
docList={docList}
parent={this}
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 12b7d742b..fd2ae03d8 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -287,7 +287,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
const singleColumn = style.isStackingView;
const columnYMargin = this.props.headingObject ? 0 : NumCast(this.props.parent.props.Document._yMargin, 5);
const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
- const evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
+ const evContents = heading ? heading : this.props?.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
const headerEditableViewProps = {
GetValue: () => evContents,
SetValue: this.headingChanged,
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 7820e2fa3..54e7f790f 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -2,7 +2,7 @@ import { action, computed, IReactionDisposer, reaction, observable, runInAction
import { basename } from 'path';
import CursorField from "../../../fields/CursorField";
import { Doc, Opt, Field, DocListCast } from "../../../fields/Doc";
-import { Id } from "../../../fields/FieldSymbols";
+import { Id, ToString } from "../../../fields/FieldSymbols";
import { List } from "../../../fields/List";
import { listSpec } from "../../../fields/Schema";
import { ScriptField } from "../../../fields/ScriptField";
@@ -142,15 +142,20 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
searchDocs = DocUtils.FilterDocs(searchDocs, this.docFilters(), docRangeFilters, viewSpecScript);
childDocs.forEach((d) => {
let notFiltered = searchDocs.includes(d) || d.z;
- if (d.data !== undefined) {
- let subDocs = DocListCast(d.data);
+ 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 && !notFiltered) {
newarray = [];
subDocs.forEach((t) => {
+ const fieldKey = Doc.LayoutFieldKey(t);
+ const annos = !Field.toString(Doc.LayoutField(t) as Field).includes("CollectionView");
notFiltered = notFiltered || searchDocs.includes(t);
- DocListCast(t.data).forEach((newdoc) => newarray.push(newdoc));
+ DocListCast(t[annos ? fieldKey + "-annotations" : fieldKey]).forEach((newdoc) => newarray.push(newdoc));
});
subDocs = newarray;
}
@@ -397,7 +402,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
_height: 315,
_nativeWidth: 850,
_nativeHeight: 962,
- UseCors: true
+ useCors: true
});
newDoc.data = new WebField(uriList.split("#annotations:")[0]); // clean hypothes.is URLs that reference a specific annotation (eg. https://en.wikipedia.org/wiki/Cartoon#annotations:t7qAeNbCEeqfG5972KR2Ig)
this.addDocument(newDoc);
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 84fd4cbe8..52c3b2793 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -390,7 +390,7 @@ class TreeView extends React.Component<TreeViewProps> {
this: this.doc.isTemplateForField && this.props.dataDoc ? this.props.dataDoc : this.doc,
heading: this.props.containingCollection.title,
checked: this.doc.treeViewChecked === "check" ? "x" : this.doc.treeViewChecked === "x" ? undefined : "check",
- containingTreeView: this.props.treeView,
+ containingTreeView: this.props.treeView.props.Document,
}, console.log);
} else {
this.treeViewOpen = !this.treeViewOpen;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 81403de46..cb053e85c 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -400,12 +400,19 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
const viewSpecScript = ScriptCast(this.props.Document.viewSpecScript);
return viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
}
+
@computed get _allFacets() {
TraceMobx();
- const facets = new Set<string>(["type", "text", "data", "author", "ACL"]);
+ return ["author", "creationDate", "type", "text", "context"];
+ const noviceReqFields = ["author", "creationDate", "type", "text", "context"];
+ const noviceLayoutFields: string[] = [];//["_curPage"];
+ const noviceFields = [...noviceReqFields, ...noviceLayoutFields];
+
+ const facets = new Set<string>([...noviceReqFields, ...noviceLayoutFields]);
this.childDocs.filter(child => child).forEach(child => child && Object.keys(Doc.GetProto(child)).forEach(key => facets.add(key)));
Doc.AreProtosEqual(this.dataDoc, this.props.Document) && this.childDocs.filter(child => child).forEach(child => Object.keys(child).forEach(key => facets.add(key)));
- return Array.from(facets).filter(f => !f.startsWith("_") && !["proto", "zIndex", "isPrototype", "context", "text-noTemplate"].includes(f)).sort();
+
+ return Array.from(facets).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("_") && !key.startsWith("ACL")) || noviceFields.includes(key)).sort();
}
/**
diff --git a/src/client/views/collections/TabDocView.scss b/src/client/views/collections/TabDocView.scss
index 9a4b5cbd1..fdb801e03 100644
--- a/src/client/views/collections/TabDocView.scss
+++ b/src/client/views/collections/TabDocView.scss
@@ -1,4 +1,6 @@
-
+input.lm_title:focus {
+ max-width: max-content !important;
+}
.miniMap {
position: absolute;
overflow: hidden;
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 31e3fbed6..3c230537c 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -53,59 +53,70 @@ export class TabDocView extends React.Component<TabDocViewProps> {
tab._disposers = {} as { [name: string]: IReactionDisposer };
tab.contentItem.config.fixed && (tab.contentItem.parent.config.fixed = true);
tab.DashDoc = doc;
-
CollectionDockingView.Instance.tabMap.add(tab);
- tab.titleElement[0].onchange = (e: any) => {
- tab.titleElement[0].size = e.currentTarget.value.length + 1;
+
+ // setup the title element and set its size according to the # of chars in the title. Show the full title when clicked.
+ const titleEle = tab.titleElement[0];
+ titleEle.size = StrCast(doc.title).length + 3;
+ titleEle.value = doc.title;
+ titleEle.style["max-width"] = "100px";
+ titleEle.onchange = (e: any) => {
+ titleEle.size = e.currentTarget.value.length + 3;
Doc.GetProto(doc).title = e.currentTarget.value;
};
- tab.titleElement[0].size = StrCast(doc.title).length + 1;
- tab.titleElement[0].value = doc.title;
- tab.titleElement[0].style["max-width"] = "100px";
- const gearSpan = document.createElement("span");
- gearSpan.className = "collectionDockingView-gear";
- gearSpan.style.position = "relative";
- gearSpan.style.paddingLeft = "0px";
- gearSpan.style.paddingRight = "12px";
- const stack = tab.contentItem.parent;
- tab.element[0].onclick = (e: any) => e.target.className !== "lm_close_tab" && this.view && SelectionManager.SelectDoc(this.view!, false);
// shifts the focus to this tab when another tab is dragged over it
tab.element[0].onmouseenter = (e: MouseEvent) => {
if (SnappingManager.GetIsDragging() && tab.contentItem !== tab.header.parent.getActiveContentItem()) {
tab.header.parent.setActiveContentItem(tab.contentItem);
+ console.log("Seetting " + titleEle.value);
+ tab.setActive(true);
}
- tab.setActive(true);
};
- const onDown = (e: React.PointerEvent) => {
+ const onPointerDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, (e) => {
- !e.defaultPrevented && DragManager.StartDocumentDrag([gearSpan], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY);
+ !e.defaultPrevented && DragManager.StartDocumentDrag([dragHdl], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY);
return !e.defaultPrevented;
}, returnFalse, emptyFunction);
};
- tab._disposers.selectionDisposer = reaction(() => SelectionManager.SelectedDocuments().some(v => v.props.Document === doc),
- (selected) => {
- selected && tab.contentItem !== tab.header.parent.getActiveContentItem() && UndoManager.RunInBatch(() => tab.header.parent.setActiveContentItem(tab.contentItem), "tab switch");
+ // select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected
+ tab.element[0].onclick = (e: any) => {
+ if (e.target.className !== "lm_close_tab" && this.view) {
+ SelectionManager.SelectDoc(this.view, false);
+ if (Date.now() - titleEle.lastClick < 1000) titleEle.select();
+ titleEle.lastClick = Date.now();
+ (document.activeElement !== titleEle) && titleEle.focus();
}
- );
- tab._disposers.buttonDisposer = reaction(() => this.view,
- (view) => {
- if (view) {
- ReactDOM.render(<span title="Drag as document" className="collectionDockingView-dragAsDocument" onPointerDown={onDown} >
- <CollectionDockingViewMenu views={() => [view]} Stack={stack} />
- </span>,
- gearSpan);
- tab._disposers.buttonDisposer?.();
- }
- }, { fireImmediately: true });
+ };
+ tab._disposers.selectionDisposer = reaction(() => SelectionManager.SelectedDocuments().some(v => v.topMost && v.props.Document === doc),
+ (selected) => selected && tab.contentItem !== tab.header.parent.getActiveContentItem() &&
+ UndoManager.RunInBatch(() => tab.header.parent.setActiveContentItem(tab.contentItem), "tab switch"));
- tab.reactComponents = [gearSpan];
- tab.element.append(gearSpan);
+ //attach the selection doc buttons menu to the drag handle
+ const stack = tab.contentItem.parent;
+ const dragHdl = document.createElement("span");
+ dragHdl.className = "collectionDockingView-gear";
+ dragHdl.style.position = "relative";
+ dragHdl.style.paddingLeft = "0px";
+ dragHdl.style.paddingRight = "12px";
+ tab._disposers.buttonDisposer = reaction(() => this.view, (view) => view &&
+ [ReactDOM.render(
+ <span title="Drag as document" className="collectionDockingView-drag" onPointerDown={onPointerDown} >
+ <CollectionDockingViewMenu views={() => [view]} Stack={stack} />
+ </span>, dragHdl),
+ tab._disposers.buttonDisposer?.()],
+ { fireImmediately: true });
+ tab.reactComponents = [dragHdl];
+ tab.element.append(dragHdl);
+
+ // highlight the tab when the tab document is brushed in any part of the UI
tab._disposers.reactionDisposer = reaction(() => ({ title: doc.title, degree: Doc.IsBrushedDegree(doc) }), ({ title, degree }) => {
- tab.titleElement[0].value = title;
- tab.titleElement[0].style.padding = degree ? 0 : 2;
- tab.titleElement[0].style.border = `${["gray", "gray", "gray"][degree]} ${["none", "dashed", "solid"][degree]} 2px`;
+ titleEle.value = title;
+ titleEle.style.padding = degree ? 0 : 2;
+ titleEle.style.border = `${["gray", "gray", "gray"][degree]} ${["none", "dashed", "solid"][degree]} 2px`;
}, { fireImmediately: true });
+
+ // clean up the tab when it is closed
tab.closeElement.off('click') //unbind the current click handler
.click(function () {
Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index f928e3fb8..d8e1bcc9c 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -76,7 +76,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
const [x, y] = this.props.getTransform().transformPoint(this._downX, this._downY);
if (e.key === "?") {
cm.setDefaultItem("?", (str: string) => this.props.addDocTab(
- Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, { _width: 200, x, y, _nativeHeight: 962, _nativeWidth: 850, isAnnotating: false, title: "bing", UseCors: true }), "add:right"));
+ Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, { _width: 200, x, y, _nativeHeight: 962, _nativeWidth: 850, isAnnotating: false, title: "bing", useCors: true }), "add:right"));
cm.displayMenu(this._downX, this._downY);
e.stopPropagation();
diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss
index 4dc25031d..0e03b46db 100644
--- a/src/client/views/linking/LinkMenu.scss
+++ b/src/client/views/linking/LinkMenu.scss
@@ -4,8 +4,6 @@
width: auto;
height: auto;
position: absolute;
- top: 0;
- left: 0;
z-index: 999;
.linkMenu-list {
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index 31d08edae..f5a1ae8e7 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -91,9 +91,9 @@ export class LinkMenu extends React.Component<Props> {
render() {
const sourceDoc = this.props.docView.props.Document;
const groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc);
- return <div className="linkMenu" ref={this._linkMenuRef} >
+ return <div className="linkMenu" style={{ left: this.position.x, top: this.props.docView.topMost ? undefined : this.position.b + 15, bottom: this.props.docView.topMost ? 20 : undefined }} ref={this._linkMenuRef} >
{!this._editingLink ?
- <div className="linkMenu-list" style={{ left: this.position.x, top: this.position.b + 15 }}>
+ <div className="linkMenu-list" >
{this.renderAllGroups(groups)}
</div> :
<div className="linkMenu-listEditor" style={{ left: this.position.x, top: this.position.b + 15 }}>
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index dc9b7c98f..5d5a1f7f3 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -18,7 +18,6 @@ import { DocHolderBox } from "./DocHolderBox";
import { DocumentViewProps } from "./DocumentView";
import "./DocumentView.scss";
import { FontIconBox } from "./FontIconBox";
-import { MenuIconBox } from "./MenuIconBox";
import { FieldView, FieldViewProps } from "./FieldView";
import { FormattedTextBox, FormattedTextBoxProps } from "./formattedText/FormattedTextBox";
import { ImageBox } from "./ImageBox";
@@ -190,7 +189,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & Fo
blacklistedAttrs={[]}
renderInWrapper={false}
components={{
- FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, MenuIconBox, LabelBox, SliderBox, FieldView,
+ FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, LabelBox, SliderBox, FieldView,
CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox,
PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, SearchBox,
ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, DocHolderBox, LinkBox, ScriptingBox,
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 318f7b7e9..1d346894c 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -25,7 +25,7 @@ export const Flyout = higflyout.default;
interface DocumentLinksButtonProps {
View: DocumentView;
- Offset?: number[];
+ Offset?: (number | undefined)[];
AlwaysOn?: boolean;
InMenu?: boolean;
StartLink?: boolean;
@@ -242,7 +242,10 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
id={"link-icon"}
src={`/assets/${"link.png"}`} />;
- const linkButton = <div ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}>
+ const linkButton = <div className="documentLinksButton-cont" ref={this._linkButton} style={{
+ minWidth: 20, minHeight: 20, position: "absolute",
+ left: this.props.Offset?.[0], top: this.props.Offset?.[1], right: this.props.Offset?.[2], bottom: this.props.Offset?.[3]
+ }}>
<div className={"documentLinksButton"} style={{
backgroundColor: this.props.InMenu ? "" : "#add8e6",
color: this.props.InMenu ? "white" : "black",
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3651f0d5f..0182e652f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -359,7 +359,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if ((this.layoutDoc.onDragStart || this.props.Document.rootDocument) && !(e.ctrlKey || e.button > 0)) { // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplaetForField implies we're clicking on part of a template instance and we want to select the whole template, not the part
stopPropagate = false; // don't stop propagation for field templates -- want the selection to propagate up to the root document of the template
} else {
- SelectionManager.SelectDoc(this, e.ctrlKey || e.shiftKey);
+ this.select(e.ctrlKey || e.shiftKey);
+ //SelectionManager.SelectDoc(this, e.ctrlKey || e.shiftKey);
}
preventDefault = false;
}
@@ -708,8 +709,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this.Document._overflow = this.Document._isBackground ? "visible" : undefined;
if (this.Document._isBackground) {
this.props.bringToFront(this.props.Document, true);
- this.props.Document[DataSym][Doc.LayoutFieldKey(this.Document) + "-nativeWidth"] = this.Document[WidthSym]();
- this.props.Document[DataSym][Doc.LayoutFieldKey(this.Document) + "-nativeHeight"] = this.Document[HeightSym]();
+ const wid = this.Document[WidthSym](); // change the nativewidth and height if the background is to be a collection that aggregates stuff that is added to it.
+ const hgt = this.Document[HeightSym]();
+ this.props.Document[DataSym][Doc.LayoutFieldKey(this.Document) + "-nativeWidth"] = wid;
+ this.props.Document[DataSym][Doc.LayoutFieldKey(this.Document) + "-nativeHeight"] = hgt;
}
}
@@ -855,7 +858,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
return this.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false;
}
childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling());
- @computed.struct get linkOffset() { return [-15, 0]; }
+ @computed.struct get linkOffset() { return this.topMost ? [0, undefined, undefined, 10] : [-15, undefined, undefined, undefined]; }
@computed get contents() {
const pos = this.props.relative ? "relative " : "absolute";
TraceMobx();
diff --git a/src/client/views/nodes/FontIconBox.scss b/src/client/views/nodes/FontIconBox.scss
index 75bc90d7a..33ac85a0e 100644
--- a/src/client/views/nodes/FontIconBox.scss
+++ b/src/client/views/nodes/FontIconBox.scss
@@ -34,12 +34,14 @@
}
}
+.menuButton-circle,
.menuButton-round {
border-radius: 100%;
background-color: black;
+ padding: 0;
.fontIconBox-label {
- margin-left: -10px; // button padding is 10px;
+ //margin-left: -10px; // button padding is 10px;
bottom: 0;
position: absolute;
}
@@ -52,7 +54,6 @@
.menuButton-square {
padding-top: 3px;
padding-bottom: 3px;
- padding-left: 5px;
.fontIconBox-label {
border-radius: 0px;
@@ -62,9 +63,11 @@
}
.menuButton,
+.menuButton-circle,
.menuButton-round,
.menuButton-square {
- width: 100%;
+ margin-left: -5%;
+ width: 110%;
height: 100%;
pointer-events: all;
touch-action: none;
@@ -72,11 +75,7 @@
.menuButton-wrap {
touch-action: none;
border-radius: 8px;
-
- // &:hover {
- // background: rgb(61, 61, 61);
- // cursor: pointer;
- // }
+ width: 100%;
}
.menuButton-icon-square {
@@ -89,4 +88,13 @@
width: 95% !important;
height: 95%;
}
+}
+.menuButton-round {
+ width: 100%;
+ svg {
+ width: 50% !important;
+ height: 50%;
+ position: relative;
+ bottom: 2px;
+ }
} \ No newline at end of file
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 87142babd..a34bf64b0 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -63,12 +63,11 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
const label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title));
const color = StrCast(this.layoutDoc.color, this._foregroundColor);
const backgroundColor = StrCast(this.layoutDoc._backgroundColor, StrCast(this.rootDoc.backgroundColor, this.props.backgroundColor?.(this.rootDoc, this.props.renderDepth)));
- const shape = StrCast(this.layoutDoc.iconShape, "round");
+ const shape = StrCast(this.layoutDoc.iconShape, label ? "round" : "circle");
const icon = StrCast(this.dataDoc.icon, "user") as any;
- const presTrailsIcon = <img
- style={{ width: shape === 'round' ? 25 : 30, height: shape === 'round' ? 25 : 30, filter: color === 'white' ? 'invert(100%)' : 'invert(0%)', transform: shape === 'round' ? 'translate(-5px, -7px)' : undefined }}
- id={"pres-icon"}
- src={`/assets/${"presTrails.png"}`} />;
+ const presSize = shape === 'round' ? 25 : 30;
+ const presTrailsIcon = <img src={`/assets/${"presTrails.png"}`}
+ style={{ width: presSize, height: presSize, filter: `invert(${color === "white" ? "100%" : "0%"})`, marginBottom: "5px" }} />;
const button = <button className={`menuButton-${shape}`} ref={this._ref} onContextMenu={this.specificContextMenu}
style={{
boxShadow: this.layoutDoc.ischecked ? `4px 4px 12px black` : undefined,
diff --git a/src/client/views/nodes/LabelBox.scss b/src/client/views/nodes/LabelBox.scss
index b605df262..109a02df4 100644
--- a/src/client/views/nodes/LabelBox.scss
+++ b/src/client/views/nodes/LabelBox.scss
@@ -8,6 +8,7 @@
}
.labelBox-mainButton {
+ max-width: 100%;
width: fit-content;
height: max-content;
border-radius: inherit;
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index e174a95af..ce8df5195 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -71,7 +71,7 @@ export class LinkDocPreview extends React.Component<Props> {
DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.linkSrc,
(doc: Doc, followLinkLocation: string) => this.props.addDocTab(doc, e.ctrlKey ? "add" : followLinkLocation));
} else if (this.props.href) {
- this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { title: this.props.href, _width: 200, _height: 400, UseCors: true }), "add:right");
+ this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { title: this.props.href, _width: 200, _height: 400, useCors: true }), "add:right");
}
}
width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225));
diff --git a/src/client/views/nodes/MenuIconBox.scss b/src/client/views/nodes/MenuIconBox.scss
deleted file mode 100644
index 1b72f5a8f..000000000
--- a/src/client/views/nodes/MenuIconBox.scss
+++ /dev/null
@@ -1,49 +0,0 @@
-.menuButton {
- //padding: 7px;
- padding-left: 7px;
- width: 100%;
- width: 60px;
- height: 70px;
-
- .menuButton-wrap {
- width: 45px;
- /* padding: 5px; */
- touch-action: none;
- background: black;
- transform-origin: top left;
- /* margin-bottom: 5px; */
- margin-top: 5px;
- margin-right: 25px;
- border-radius: 8px;
-
- &:hover {
- background: rgb(61, 61, 61);
- cursor: pointer;
- }
- }
-
- .menuButton-label {
- color: white;
- margin-right: 4px;
- border-radius: 8px;
- width: 42px;
- position: relative;
- text-align: center;
- font-size: 8px;
- margin-top: 1px;
- letter-spacing: normal;
- padding: 3px;
- background-color: inherit;
- }
-
- .menuButton-icon {
- width: auto;
- height: 35px;
- padding: 5px;
- }
-
- svg {
- width: 95% !important;
- height: 95%;
- }
-} \ No newline at end of file
diff --git a/src/client/views/nodes/MenuIconBox.tsx b/src/client/views/nodes/MenuIconBox.tsx
deleted file mode 100644
index 5ed8a9b78..000000000
--- a/src/client/views/nodes/MenuIconBox.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { createSchema, makeInterface } from '../../../fields/Schema';
-import { StrCast } from '../../../fields/Types';
-import { DocComponent } from '../DocComponent';
-import { FieldView, FieldViewProps } from './FieldView';
-import './MenuIconBox.scss';
-const MenuIconSchema = createSchema({
- icon: "string"
-});
-
-type MenuIconDocument = makeInterface<[typeof MenuIconSchema]>;
-const MenuIconDocument = makeInterface(MenuIconSchema);
-@observer
-export class MenuIconBox extends DocComponent<FieldViewProps, MenuIconDocument>(MenuIconDocument) {
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(MenuIconBox, fieldKey); }
- _ref: React.RefObject<HTMLButtonElement> = React.createRef();
-
- render() {
-
- const color = this.props.backgroundColor?.(this.props.Document, this.props.renderDepth) === "lightgrey" ? "black" : "white";
- const menuBTN = <div className="menuButton" style={{ backgroundColor: this.props.backgroundColor?.(this.props.Document, this.props.renderDepth) }}>
- <div className="menuButton-wrap"
- style={{ backgroundColor: this.props.backgroundColor?.(this.props.Document, this.props.renderDepth) }} >
- <FontAwesomeIcon className="menuButton-icon" icon={StrCast(this.dataDoc.icon, "user") as any} color={color} size="lg" />
- <div className="menuButton-label" style={{ color: color }}> {this.dataDoc.title} </div>
- </div>
- </div>;
-
- return menuBTN;
- }
-} \ No newline at end of file
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index bb544fedc..4dded50b0 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -374,7 +374,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
specificContextMenu = (e: React.MouseEvent): void => {
const cm = ContextMenu.Instance;
const funcs: ContextMenuProps[] = [];
- funcs.push({ description: (this.layoutDoc.UseCors ? "Don't Use" : "Use") + " Cors", event: () => this.layoutDoc.UseCors = !this.layoutDoc.UseCors, icon: "snowflake" });
+ funcs.push({ description: (this.layoutDoc.useCors ? "Don't Use" : "Use") + " Cors", event: () => this.layoutDoc.useCors = !this.layoutDoc.useCors, icon: "snowflake" });
cm.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
}
@@ -389,7 +389,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
if (field instanceof HtmlField) {
view = <span className="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: field.html }} />;
} else if (field instanceof WebField) {
- const url = this.layoutDoc.UseCors ? Utils.CorsProxy(field.url.href) : field.url.href;
+ const url = this.layoutDoc.useCors ? Utils.CorsProxy(field.url.href) : field.url.href;
view = <iframe className="webBox-iframe" enable-annotation={"true"} ref={this._iframeRef} src={url} onLoad={this.iframeLoaded}
// the 'allow-top-navigation' and 'allow-top-navigation-by-user-activation' attributes are left out to prevent iframes from redirecting the top-level Dash page
sandbox={"allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts"} />;
@@ -495,7 +495,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
Doc.GetProto(targetDoc).data = new List<Doc>([clipDoc]);
clipDoc.rootDocument = targetDoc;
targetDoc.layoutKey = "layout";
- const annotationDoc = this.highlight("rgba(146, 245, 95, 0.467)"); // yellowish highlight color when dragging out a text selection
+ const annotationDoc = this.highlight("rgba(173, 216, 230, 0.3)"); // hyperlink color
if (annotationDoc) {
DragManager.StartPdfAnnoDrag([ele], new DragManager.PdfAnnoDragData(this.props.Document, annotationDoc, targetDoc), e.pageX, e.pageY, {
dragComplete: e => {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index c49e38f72..436538eba 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -499,7 +499,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
if (node.isTextblock) {
let index = 0, foundAt;
const ep = this.getNodeEndpoints(pm.state.doc, node);
- const regexp = find.replace("*", "");
+ const regexp = new RegExp(find.replace("*", ""), "i");
if (regexp) {
while (ep && (foundAt = node.textContent.slice(index).search(regexp)) > -1) {
const sel = new TextSelection(pm.state.doc.resolve(ep.from + index + foundAt + 1), pm.state.doc.resolve(ep.from + index + foundAt + find.length + 1));
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index ef0222a4c..b4f648273 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -133,7 +133,7 @@ export class FormattedTextBoxComment {
}
} else if (textBox && (FormattedTextBoxComment.tooltipText as any).href) {
- textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _width: 200, _height: 400, UseCors: true }), "add:right");
+ textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _width: 200, _height: 400, useCors: true }), "add:right");
}
keep && textBox && FormattedTextBoxComment.start !== undefined && textBox.adoptAnnotation(
FormattedTextBoxComment.start, FormattedTextBoxComment.end, FormattedTextBoxComment.mark);
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 8edb0e178..bd9723fc2 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -240,8 +240,10 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
}
pagesinit = action(() => {
- this._pdfViewer.currentScaleValue = this._zoomed = 1;
- this.gotoPage(this.Document._curPage || 1);
+ if (this._pdfViewer._setDocumentViewerElement.offsetParent) {
+ this._pdfViewer.currentScaleValue = this._zoomed = 1;
+ this.gotoPage(this.Document._curPage || 1);
+ }
document.removeEventListener("pagesinit", this.pagesinit);
});
@@ -337,7 +339,9 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
@action
gotoPage = (p: number) => {
- this._pdfViewer?.scrollPageIntoView({ pageNumber: Math.min(Math.max(1, p), this._pageSizes.length) });
+ if (this._pdfViewer?._setDocumentViewerElement?.offsetParent) {
+ this._pdfViewer?.scrollPageIntoView({ pageNumber: Math.min(Math.max(1, p), this._pageSizes.length) });
+ }
}
@action
@@ -597,7 +601,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
// Doc.GetProto(targetDoc).snipped = this.dataDoc[this.props.fieldKey][Copy]();
// const snipLayout = Docs.Create.PdfDocument("http://www.msn.com", { title: "snippetView", isTemplateDoc: true, isTemplateForField: "snipped", _fitWidth: true, _width: this.marqueeWidth(), _height: this.marqueeHeight(), _scrollTop: this.marqueeY() });
// Doc.GetProto(snipLayout).layout = PDFBox.LayoutString("snipped");
- const annotationDoc = this.highlight("lightBlue");
+ const annotationDoc = this.highlight("rgba(173, 216, 230, 0.3)"); // hyperlink color
if (annotationDoc) {
DragManager.StartPdfAnnoDrag([ele], new DragManager.PdfAnnoDragData(this.props.Document, annotationDoc, targetDoc), e.pageX, e.pageY, {
dragComplete: e => {
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index d08cc7f5b..3d564f073 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -102,7 +102,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
this._curRequest = undefined;
this._maxSearchIndex = 0;
}
- })
+ });
enter = action((e: React.KeyboardEvent | undefined) => {
if (!e || e.key === "Enter") {
@@ -250,7 +250,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
this._numTotalResults = -1;
this._searchFullDB ? await this.searchDatabase(query) : this.searchCollection(query);
runInAction(() => {
- this._searchbarOpen = true;
+ this.open = this._searchbarOpen = true;
this.resultsScrolled();
});
}
@@ -286,7 +286,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
this._lockPromise && (await this._lockPromise);
this._lockPromise = new Promise(async res => {
while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) {
- this._curRequest = SearchUtil.Search(query, true, { onlyAliases: true, allowAliases: true, /*sort: this.primarySort,*/ fq: this.filterQuery, start: 0, rows: this._numResultsPerPage, hl: true, "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
+ this._curRequest = SearchUtil.Search(query, true, { onlyAliases: true, allowAliases: true, /*sort: this.primarySort,*/ fq: this.filterQuery, start: 0, rows: this._numResultsPerPage, hl: "on", "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
// happens at the beginning
this.realTotalResults = res.numFound <= 0 ? 0 : res.numFound;
if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) {
@@ -378,7 +378,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
Doc.ClearSearchMatches();
});
close && (this.open = this._searchbarOpen = false);
- })
+ });
@action.bound
closeResults() {
@@ -483,7 +483,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
collectionView.props.Document._searchFilterDocs = docsForFilter?.length ? new List<Doc>(docsForFilter) : undefined;
collectionView.props.Document._docFilters = docsForFilter?.length && docFilters?.length ? new List<string>(docFilters) : undefined;
}
- })
+ });
render() {
const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 1401dd6a1..bc31c1a21 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -23,7 +23,6 @@ import { deleteProperty, getField, getter, makeEditable, makeReadOnly, setter, u
import { LinkManager } from "../client/util/LinkManager";
import JSZip = require("jszip");
import { saveAs } from "file-saver";
-import { result } from "lodash";
export namespace Field {
export function toKeyValueString(doc: Doc, key: string): string {
@@ -923,8 +922,9 @@ export namespace Doc {
brushManager.SearchMatchDoc.has(Doc.GetProto(doc)) ? brushManager.SearchMatchDoc.get(Doc.GetProto(doc)) : undefined;
}
export function SetSearchMatch(doc: Doc, results: { searchMatch: number }) {
- if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate) return doc;
- brushManager.SearchMatchDoc.set(doc, results);
+ if (doc && GetEffectiveAcl(doc) !== AclPrivate && GetEffectiveAcl(Doc.GetProto(doc)) !== AclPrivate) {
+ brushManager.SearchMatchDoc.set(doc, results);
+ }
return doc;
}
export function SearchMatchNext(doc: Doc, backward: boolean) {
diff --git a/src/fields/util.ts b/src/fields/util.ts
index d0c722ddc..82525f92b 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -293,7 +293,7 @@ export function setter(target: any, in_prop: string | symbol | number, value: an
export function getter(target: any, in_prop: string | symbol | number, receiver: any): any {
let prop = in_prop;
- if (in_prop === ToString || in_prop === ToScriptString || in_prop === FieldsSym || in_prop === Id || in_prop === HandleUpdate || in_prop === CachedUpdates) return target.__fields[prop] || target[prop];
+ if (in_prop === "toString" || in_prop === ToString || in_prop === ToScriptString || in_prop === FieldsSym || in_prop === Id || in_prop === HandleUpdate || in_prop === CachedUpdates) return target.__fields[prop] || target[prop];
if (in_prop === AclSym) return _overrideAcl ? undefined : target[AclSym];
if (GetEffectiveAcl(target) === AclPrivate && !_overrideAcl) return prop === HeightSym || prop === WidthSym ? returnZero : undefined;
if (prop === LayoutSym) {
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts
index a5aaab63e..a52430ee8 100644
--- a/src/server/ApiManagers/SearchManager.ts
+++ b/src/server/ApiManagers/SearchManager.ts
@@ -62,7 +62,7 @@ export class SearchManager extends ApiManager {
subscription: "/dashsearch",
secureHandler: async ({ req, res }) => {
const solrQuery: any = {};
- ["q", "fq", "start", "rows", "sort", "hl", "hl.fl"].forEach(key => solrQuery[key] = req.query[key]);
+ ["q", "fq", "start", "rows", "sort", "hl.maxAnalyzedChars", "hl", "hl.fl"].forEach(key => solrQuery[key] = req.query[key]);
if (solrQuery.q === undefined) {
res.send([]);
return;
diff --git a/src/server/Search.ts b/src/server/Search.ts
index 3869867cd..68f61deb2 100644
--- a/src/server/Search.ts
+++ b/src/server/Search.ts
@@ -29,9 +29,8 @@ export namespace Search {
export async function search(query: any) {
try {
- const searchResults = JSON.parse(await rp.get(pathTo("select"), {
- qs: query
- }));
+ const output = await rp.get(pathTo("select"), { qs: query });
+ const searchResults = JSON.parse(output);
const { docs, numFound } = searchResults.response;
const ids = docs.map((field: any) => field.id);
return { ids, numFound, highlighting: searchResults.highlighting };