aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/SidebarAnnos.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
committerbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
commit9b41da1af16b982ee8ac2fc09f2f8b5d67eac9fb (patch)
treebc3f57cd5b31fd453d272c925f6d5b728ab63bae /src/client/views/SidebarAnnos.tsx
parent9dae453967183b294bf4f7444b948023a1d52d39 (diff)
parent8f7e99641f84ad15f34ba9e4a60b664ac93d2e5d (diff)
Merge branch 'master' into data-visualization-view-naafi
Diffstat (limited to 'src/client/views/SidebarAnnos.tsx')
-rw-r--r--src/client/views/SidebarAnnos.tsx120
1 files changed, 95 insertions, 25 deletions
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 90d9c3c43..2d2b0f83e 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -1,12 +1,14 @@
import { computed } from 'mobx';
import { observer } from 'mobx-react';
-import { Doc, DocListCast, StrListCast } from '../../fields/Doc';
+import { Doc, DocListCast, Field, FieldResult, StrListCast } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
-import { NumCast, StrCast } from '../../fields/Types';
-import { emptyFunction, OmitKeys, returnAll, returnOne, returnTrue, returnZero } from '../../Utils';
+import { RichTextField } from '../../fields/RichTextField';
+import { DocCast, NumCast, StrCast } from '../../fields/Types';
+import { emptyFunction, returnAll, returnFalse, returnOne, returnTrue, returnZero } from '../../Utils';
import { Docs, DocUtils } from '../documents/Documents';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
+import { LinkManager } from '../util/LinkManager';
import { Transform } from '../util/Transform';
import { CollectionStackingView } from './collections/CollectionStackingView';
import { FieldViewProps } from './nodes/FieldView';
@@ -24,6 +26,7 @@ interface ExtraProps {
// usePanelWidth: boolean;
showSidebar: boolean;
nativeWidth: number;
+ usePanelWidth?: boolean;
whenChildContentsActiveChanged: (isActive: boolean) => void;
ScreenToLocalTransform: () => Transform;
sidebarAddDocument: (doc: Doc | Doc[], suffix: string) => boolean;
@@ -38,12 +41,13 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
}
_stackRef = React.createRef<CollectionStackingView>();
@computed get allMetadata() {
- const keys = new Set<string>();
- DocListCast(this.props.rootDoc[this.sidebarKey]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key)));
- return Array.from(keys.keys())
- .filter(key => key[0])
- .filter(key => key[0] !== '_' && key[0] === key[0].toUpperCase())
- .sort();
+ const keys = new Map<string, FieldResult<Field>>();
+ DocListCast(this.props.rootDoc[this.sidebarKey]).forEach(doc =>
+ SearchBox.documentKeys(doc)
+ .filter(key => key[0] && key[0] !== '_' && key[0] === key[0].toUpperCase())
+ .map(key => keys.set(key, doc[key]))
+ );
+ return keys;
}
@computed get allUsers() {
const keys = new Set<string>();
@@ -70,14 +74,74 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
});
FormattedTextBox.SelectOnLoad = target[Id];
FormattedTextBox.DontSelectInitialText = true;
- this.allMetadata.map(tag => (target[tag] = tag));
- DocUtils.MakeLink({ doc: anchor }, { doc: target }, 'inline comment:comment on');
+ const link = DocUtils.MakeLink(anchor, target, { linkRelationship: 'inline comment:comment on' });
+ link && (link.linkDisplay = false);
+
+ const taggedContent = this.docFilters()
+ .filter(data => data.split(':')[0])
+ .map(data => {
+ const key = data.split(':')[0];
+ const val = Field.Copy(this.allMetadata.get(key));
+ Doc.GetProto(target)[key] = val;
+ return {
+ type: 'dashField',
+ attrs: { fieldKey: key, docId: '', hideKey: false, editable: true },
+ marks: [{ type: 'pFontSize', attrs: { fontSize: '12px' } }, { type: 'strong' }, { type: 'user_mark', attrs: { userid: Doc.CurrentUserEmail, modified: 0 } }],
+ };
+ });
+
+ if (!anchor.text) Doc.GetProto(anchor).text = '-selection-';
+ const textLines: any = [
+ {
+ type: 'paragraph',
+ attrs: { align: null, color: null, id: null, indent: null, inset: null, lineSpacing: null, paddingBottom: null, paddingTop: null },
+ content: [
+ {
+ type: 'dashField',
+ marks: [
+ {
+ type: 'linkAnchor',
+ attrs: {
+ allAnchors: [{ href: `/doc/${target[Id]}`, title: 'Anchored Selection', anchorId: `${target[Id]}` }],
+ location: 'add:right',
+ title: 'Anchored Selection',
+ noPreview: true,
+ docref: false,
+ },
+ },
+ { type: 'pFontSize', attrs: { fontSize: '8px' } },
+ { type: 'em' },
+ ],
+ attrs: { fieldKey: 'text', docId: anchor[Id], hideKey: true, editable: false },
+ },
+ ],
+ },
+ { type: 'paragraph', attrs: { align: null, color: null, id: null, indent: null, inset: null, lineSpacing: null, paddingBottom: null, paddingTop: null } },
+ ];
+ const metadatatext = {
+ type: 'paragraph',
+ attrs: { align: null, color: null, id: null, indent: null, inset: null, lineSpacing: null, paddingBottom: null, paddingTop: null },
+ content: taggedContent,
+ };
+ if (taggedContent.length) textLines.push(metadatatext);
+ if (textLines.length) {
+ Doc.GetProto(target).text = new RichTextField(
+ JSON.stringify({
+ doc: {
+ type: 'doc',
+ content: textLines,
+ },
+ selection: { type: 'text', anchor: 4, head: 4 }, // set selection to middle paragraph
+ }),
+ ''
+ );
+ }
this.addDocument(target);
- this._stackRef.current?.focusDocument(target);
+ setTimeout(() => this._stackRef.current?.focusDocument(target, {}));
return target;
};
makeDocUnfiltered = (doc: Doc) => {
- if (DocListCast(this.props.rootDoc[this.sidebarKey]).includes(doc)) {
+ if (DocListCast(this.props.rootDoc[this.sidebarKey]).find(anno => Doc.AreProtosEqual(doc.unrendered ? DocCast(doc.annotationOn) : doc, anno))) {
if (this.props.layoutDoc[this.filtersKey]) {
this.props.layoutDoc[this.filtersKey] = new List<string>();
}
@@ -95,13 +159,10 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
.ScreenToLocalTransform()
.translate(Doc.NativeWidth(this.props.dataDoc), 0)
.scale(this.props.NativeDimScaling?.() || 1);
- // panelWidth = () => !this.props.layoutDoc._showSidebar ? 0 :
- // this.props.usePanelWidth ? this.props.PanelWidth() :
- // (NumCast(this.props.layoutDoc.nativeWidth) - Doc.NativeWidth(this.props.dataDoc)) * this.props.PanelWidth() / NumCast(this.props.layoutDoc.nativeWidth);
panelWidth = () =>
!this.props.showSidebar
? 0
- : this.props.layoutDoc.type === DocumentType.RTF || this.props.layoutDoc.type === DocumentType.MAP
+ : this.props.usePanelWidth // [DocumentType.RTF, DocumentType.MAP].includes(this.props.layoutDoc.type as any)
? this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1)
: ((NumCast(this.props.nativeWidth) - Doc.NativeWidth(this.props.dataDoc)) * this.props.PanelWidth()) / NumCast(this.props.nativeWidth);
panelHeight = () => this.props.PanelHeight() - this.filtersHeight();
@@ -111,6 +172,11 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
docFilters = () => [...StrListCast(this.props.layoutDoc._docFilters), ...StrListCast(this.props.layoutDoc[this.filtersKey])];
showTitle = () => 'title';
setHeightCallback = (height: number) => this.props.setHeight?.(height + this.filtersHeight());
+ sortByLinkAnchorY = (a: Doc, b: Doc) => {
+ const ay = LinkManager.Links(a).length && DocCast(LinkManager.Links(a)[0].anchor1).y;
+ const by = LinkManager.Links(b).length && DocCast(LinkManager.Links(b)[0].anchor1).y;
+ return NumCast(ay) - NumCast(by);
+ };
render() {
const renderTag = (tag: string) => {
const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`${tag}:${tag}:check`);
@@ -120,10 +186,10 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
</div>
);
};
- const renderMeta = (tag: string) => {
- const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`${tag}:${tag}:exists`);
+ const renderMeta = (tag: string, dflt: FieldResult<Field>) => {
+ const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`${tag}:${dflt}:exists`);
return (
- <div key={tag} className={`sidebarAnnos-filterTag${active ? '-active' : ''}`} onClick={e => Doc.setDocFilter(this.props.rootDoc, tag, tag, 'exists', true, this.sidebarKey, e.shiftKey)}>
+ <div key={tag} className={`sidebarAnnos-filterTag${active ? '-active' : ''}`} onClick={e => Doc.setDocFilter(this.props.rootDoc, tag, dflt, 'exists', true, this.sidebarKey, e.shiftKey)}>
{tag}
</div>
);
@@ -150,23 +216,27 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
}}>
<div className="sidebarAnnos-tagList" style={{ height: this.filtersHeight() }} onWheel={e => e.stopPropagation()}>
{this.allUsers.map(renderUsers)}
- {this.allMetadata.map(renderMeta)}
+ {Array.from(this.allMetadata.keys())
+ .sort()
+ .map(key => renderMeta(key, this.allMetadata.get(key)))}
</div>
<div style={{ width: '100%', height: `calc(100% - 38px)`, position: 'relative' }}>
<CollectionStackingView
- {...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit}
- ref={this._stackRef}
+ {...this.props}
+ setContentView={emptyFunction}
NativeWidth={returnZero}
NativeHeight={returnZero}
+ ref={this._stackRef}
PanelHeight={this.panelHeight}
PanelWidth={this.panelWidth}
docFilters={this.docFilters}
- scaleField={this.sidebarKey + '-scale'}
+ sortFunc={this.sortByLinkAnchorY}
setHeight={this.setHeightCallback}
isAnnotationOverlay={false}
select={emptyFunction}
NativeDimScaling={returnOne}
- childShowTitle={this.showTitle}
+ //childShowTitle={this.showTitle}
+ isAnyChildContentActive={returnFalse}
childDocumentsActive={this.props.isContentActive}
whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
childHideDecorationTitle={returnTrue}