diff options
author | Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> | 2022-06-30 12:28:25 -0700 |
---|---|---|
committer | Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> | 2022-06-30 12:28:25 -0700 |
commit | 891b03238ee7bf6bd9e83cc20c1720c42059ce04 (patch) | |
tree | b912f6f1e8177106ce015896882cdc8bb11acafd /src/client/views/PropertiesView.tsx | |
parent | bb02d3a052efdbf25d1069059a92b7a9d9cc1708 (diff) | |
parent | ea6e63648b21c46672b1b7cb1da0cbaa6857d0c1 (diff) |
Merge branch 'master' into parker
Diffstat (limited to 'src/client/views/PropertiesView.tsx')
-rw-r--r-- | src/client/views/PropertiesView.tsx | 162 |
1 files changed, 106 insertions, 56 deletions
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index d10ca61ed..d7d6f8586 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -11,7 +11,7 @@ import { Id } from "../../fields/FieldSymbols"; import { InkField } from "../../fields/InkField"; import { List } from "../../fields/List"; import { ComputedField } from "../../fields/ScriptField"; -import { BoolCast, Cast, NumCast, StrCast } from "../../fields/Types"; +import { Cast, NumCast, StrCast, DocCast } from "../../fields/Types"; import { denormalizeEmail, GetEffectiveAcl, SharingPermissions } from "../../fields/util"; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from "../../Utils"; import { DocumentType } from "../documents/DocumentTypes"; @@ -34,6 +34,7 @@ import "./PropertiesView.scss"; import { DefaultStyleProvider } from "./StyleProvider"; import { PresBox } from "./nodes/trails"; import { IconLookup } from "@fortawesome/fontawesome-svg-core"; +import { PropertiesDocBacklinksSelector } from "./PropertiesDocBacklinksSelector"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -43,6 +44,7 @@ interface PropertiesViewProps { width: number; height: number; styleProvider?: StyleProviderFunc; + addDocTab: (doc: Doc, where: string) => boolean; } @observer @@ -72,6 +74,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @observable openFields: boolean = true; @observable openLayout: boolean = false; @observable openContexts: boolean = true; + @observable openLinks: boolean = true; @observable openAppearance: boolean = true; @observable openTransform: boolean = true; @observable openFilters: boolean = true; // should be false @@ -277,7 +280,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get contexts() { - return !this.selectedDoc ? (null) : <PropertiesDocContextSelector Document={this.selectedDoc} hideTitle={true} addDocTab={(doc, where) => CollectionDockingView.AddSplit(doc, "right")} />; + return !this.selectedDoc ? (null) : <PropertiesDocContextSelector DocView={this.selectedDocumentView} hideTitle={true} addDocTab={this.props.addDocTab} />; + } + + @computed get links() { + return !this.selectedDoc ? (null) : <PropertiesDocBacklinksSelector Document={this.selectedDoc} hideTitle={true} addDocTab={this.props.addDocTab} />; } @computed get layoutPreview() { @@ -293,12 +300,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { Document={layoutDoc} DataDoc={this.dataDoc} renderDepth={1} - fitContentsToDoc={returnTrue} + fitContentsToBox={returnTrue} rootSelected={returnFalse} styleProvider={DefaultStyleProvider} - layerProvider={undefined} docViewPath={returnEmptyDoclist} - freezeDimensions={true} dontCenter={"y"} isDocumentActive={returnFalse} isContentActive={emptyFunction} @@ -334,7 +339,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { */ @undoBatch changePermissions = (e: any, user: string) => { - const docs = SelectionManager.Views().length < 2 ? [this.selectedDoc] : SelectionManager.Views().map(docView => docView.props.Document); + const docs = SelectionManager.Views().length < 2 ? (this.selectedDoc ? [this.selectedDoc]:[]) : SelectionManager.Views().map(docView => docView.props.Document); SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, docs); } @@ -349,7 +354,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { value={permission} onChange={e => this.changePermissions(e, user)}> {dropdownValues.filter(permission => - !Doc.UserDoc().noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any)).map(permission => + !Doc.noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any)).map(permission => <option key={permission} value={permission}> {permission} </option>)} </select>; } @@ -413,7 +418,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { // all selected docs const docs = SelectionManager.Views().length < 2 ? - [this.layoutDocAcls ? this.selectedDoc : this.selectedDoc[DataSym]] + [this.layoutDocAcls ? this.selectedDoc : this.selectedDoc?.[DataSym]] : SelectionManager.Views().map(docView => this.layoutDocAcls ? docView.props.Document : docView.props.Document[DataSym]); const target = docs[0]; @@ -901,7 +906,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { {!this.openSharing ? (null) : <div className="propertiesView-sharing-content"> <div className="propertiesView-buttonContainer"> - {!Doc.UserDoc().noviceMode ? (<div className="propertiesView-acls-checkbox"> + {!Doc.noviceMode ? (<div className="propertiesView-acls-checkbox"> <Checkbox color="primary" onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)} @@ -925,43 +930,46 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { * If it doesn't exist, it creates it. */ checkFilterDoc() { - if (!this.selectedDoc.currentFilter) CurrentUserUtils.setupFilterDocs(this.selectedDoc); + if (!this.selectedDoc?.currentFilter) this.selectedDoc!.currentFilter = CurrentUserUtils.createFilterDoc(); } /** * Creates a new currentFilter for this.filterDoc, */ createNewFilterDoc = () => { - const currentDocFilters = this.selectedDoc._docFilters; - const currentDocRangeFilters = this.selectedDoc._docRangeFilters; - this.selectedDoc._docFilters = new List<string>(); - this.selectedDoc._docRangeFilters = new List<string>(); - (this.selectedDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; - (this.selectedDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; - this.selectedDoc.currentFilter = undefined; - CurrentUserUtils.setupFilterDocs(this.selectedDoc); + if (this.selectedDoc) { + const currentDocFilters = this.selectedDoc._docFilters; + const currentDocRangeFilters = this.selectedDoc._docRangeFilters; + this.selectedDoc._docFilters = new List<string>(); + this.selectedDoc._docRangeFilters = new List<string>(); + (this.selectedDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; + (this.selectedDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; + this.selectedDoc.currentFilter = CurrentUserUtils.createFilterDoc(); + } } /** * Updates this.filterDoc's currentFilter and saves the docFilters on the currentFilter */ updateFilterDoc = (doc: Doc) => { - if (doc === this.selectedDoc.currentFilter) return; // causes problems if you try to reapply the same doc - const savedDocFilters = doc._docFiltersList; - const currentDocFilters = this.selectedDoc._docFilters; - this.selectedDoc._docFilters = new List<string>(); - (this.selectedDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; - this.selectedDoc.currentFilter = doc; - doc._docFiltersList = new List<string>(); - this.selectedDoc._docFilters = savedDocFilters; - - const savedDocRangeFilters = doc._docRangeFiltersList; - const currentDocRangeFilters = this.selectedDoc._docRangeFilters; - this.selectedDoc._docRangeFilters = new List<string>(); - (this.selectedDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; - this.selectedDoc.currentFilter = doc; - doc._docRangeFiltersList = new List<string>(); - this.selectedDoc._docRangeFilters = savedDocRangeFilters; + if (this.selectedDoc) { + if (doc === this.selectedDoc.currentFilter) return; // causes problems if you try to reapply the same doc + const savedDocFilters = doc._docFiltersList; + const currentDocFilters = this.selectedDoc._docFilters; + this.selectedDoc._docFilters = new List<string>(); + (this.selectedDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; + this.selectedDoc.currentFilter = doc; + doc._docFiltersList = new List<string>(); + this.selectedDoc._docFilters = savedDocFilters; + + const savedDocRangeFilters = doc._docRangeFiltersList; + const currentDocRangeFilters = this.selectedDoc._docRangeFilters; + this.selectedDoc._docRangeFilters = new List<string>(); + (this.selectedDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; + this.selectedDoc.currentFilter = doc; + doc._docRangeFiltersList = new List<string>(); + this.selectedDoc._docRangeFilters = savedDocRangeFilters; + } } @computed get filtersSubMenu() { @@ -1003,7 +1011,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { createNewFilterDoc={this.createNewFilterDoc} updateFilterDoc={this.updateFilterDoc} docViewPath={returnEmptyDoclist} - layerProvider={undefined} dontCenter="y" /> </div> @@ -1055,13 +1062,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" /> </div> </div> - {!Doc.UserDoc().noviceMode && this.openFields ? <div className="propertiesView-fields-checkbox"> + {!Doc.noviceMode && this.openFields ? <div className="propertiesView-fields-checkbox"> {this.fieldsCheckbox} <div className="propertiesView-fields-checkbox-text">Layout</div> </div> : null} {!this.openFields ? (null) : <div className="propertiesView-fields-content"> - {Doc.UserDoc().noviceMode ? this.noviceFields : this.expandedField} + {Doc.noviceMode ? this.noviceFields : this.expandedField} </div>} </div>; } @@ -1071,7 +1078,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <div className="propertiesView-contexts-title" onPointerDown={action(() => this.openContexts = !this.openContexts)} style={{ backgroundColor: this.openContexts ? "black" : "" }}> - Contexts + Other Contexts <div className="propertiesView-contexts-title-icon"> <FontAwesomeIcon icon={this.openContexts ? "caret-down" : "caret-right"} size="lg" color="white" /> </div> @@ -1080,6 +1087,20 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { </div>; } + @computed get linksSubMenu() { + return <div className="propertiesView-contexts"> + <div className="propertiesView-contexts-title" + onPointerDown={action(() => this.openLinks = !this.openLinks)} + style={{ backgroundColor: this.openLinks ? "black" : "" }}> + Linked To + <div className="propertiesView-contexts-title-icon"> + <FontAwesomeIcon icon={this.openLinks ? "caret-down" : "caret-right"} size="lg" color="white" /> + </div> + </div> + {this.openLinks ? <div className="propertiesView-contexts-content" >{this.links}</div> : null} + </div>; + } + @computed get layoutSubMenu() { return <div className="propertiesView-layout"> <div className="propertiesView-layout-title" @@ -1104,7 +1125,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @undoBatch handleDescriptionChange = action((value: string) => { - if (LinkManager.currentLink) { + if (LinkManager.currentLink && this.selectedDoc) { this.selectedDoc.description = value; this.description = value; return true; @@ -1113,7 +1134,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @undoBatch handleLinkRelationshipChange = action((value: string) => { - if (LinkManager.currentLink) { + if (LinkManager.currentLink && this.selectedDoc) { this.selectedDoc.linkRelationship = value; this.relationship = value; return true; @@ -1170,7 +1191,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @undoBatch changeFollowBehavior = action((follow: string) => { - if (LinkManager.currentLink) { + if (LinkManager.currentLink && this.selectedDoc) { this.selectedDoc.followLinkLocation = follow; return true; } @@ -1201,11 +1222,18 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } toggleAnchor = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc.linkAutoMove = !this.selectedDoc.linkAutoMove))); + setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc && (this.selectedDoc.linkAutoMove = !this.selectedDoc.linkAutoMove)))); } toggleArrow = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc.displayArrow = !this.selectedDoc.displayArrow))); + setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc && (this.selectedDoc.displayArrow = !this.selectedDoc.displayArrow)))); + } + + toggleZoomToTarget1 = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc && (DocCast(this.selectedDoc.anchor1).followLinkZoom = !DocCast(this.selectedDoc.anchor1).followLinkZoom)))); + } + toggleZoomToTarget2 = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc && (DocCast(this.selectedDoc.anchor2).followLinkZoom = !DocCast(this.selectedDoc.anchor2).followLinkZoom)))); } @computed @@ -1213,7 +1241,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return <input autoComplete={"off"} id="link_relationship_input" - value={StrCast(this.selectedDoc.linkRelationship)} + value={StrCast(this.selectedDoc?.linkRelationship)} onKeyDown={this.onRelationshipKey} onBlur={this.onSelectOutRelationship} onChange={e => this.handleLinkRelationshipChange(e.currentTarget.value)} @@ -1227,7 +1255,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return <input autoComplete={"off"} id="link_description_input" - value={StrCast(this.selectedDoc.description)} + value={StrCast(this.selectedDoc?.description)} onKeyDown={this.onDescriptionKey} onBlur={this.onSelectOutDesc} onChange={e => this.handleDescriptionChange(e.currentTarget.value)} @@ -1248,7 +1276,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { // } render() { - const isNovice = BoolCast(Doc.UserDoc().noviceMode); + const isNovice = Doc.noviceMode; if (!this.selectedDoc && !this.isPres) { return <div className="propertiesView" style={{ width: this.props.width }}> <div className="propertiesView-title" style={{ width: this.props.width }}> @@ -1264,18 +1292,18 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { </div> <div className="propertiesView-section"> <p className="propertiesView-label">Information</p> - <div className="propertiesView-input first" id="propertiesView-category"> + <div className="propertiesView-input first"> <p>Link Relationship</p> {this.editRelationship} </div> - <div className="propertiesView-input" id="propertiesView-description"> + <div className="propertiesView-input"> <p>Description</p> {this.editDescription} </div> </div> <div className="propertiesView-section"> <p className="propertiesView-label">Behavior</p> - <div className="propertiesView-input inline first" id="propertiesView-follow"> + <div className="propertiesView-input inline first"> <p>Follow</p> <select name="selectList" @@ -1295,7 +1323,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { : null} </select> </div> - <div className="propertiesView-input inline" id="propertiesView-anchor"> + <div className="propertiesView-input inline"> <p>Auto-move anchor</p> <button style={{ background: this.selectedDoc.hidden ? "gray" : !this.selectedDoc.linkAutoMove ? "" : "#4476f7", borderRadius: 3 }} @@ -1305,7 +1333,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" /> </button> </div> - <div className="propertiesView-input inline" id="propertiesView-displayArrow"> + <div className="propertiesView-input inline"> <p>Display arrow</p> <button style={{ background: this.selectedDoc.hidden ? "gray" : !this.selectedDoc.displayArrow ? "" : "#4476f7", borderRadius: 3 }} @@ -1315,6 +1343,26 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" /> </button> </div> + <div className="propertiesView-input inline"> + <p>Zoom to target</p> + <button + style={{ background: this.selectedDoc.hidden ? "gray" : !Cast(this.selectedDoc.anchor1, Doc, null).followLinkZoom ? "" : "#4476f7", borderRadius: 3 }} + onPointerDown={this.toggleZoomToTarget1} onClick={e => e.stopPropagation()} + className="propertiesButton" + > + <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" /> + </button> + </div> + <div className="propertiesView-input inline"> + <p>Zoom to source</p> + <button + style={{ background: this.selectedDoc.hidden ? "gray" : !Cast(this.selectedDoc.anchor2, Doc, null).followLinkZoom ? "" : "#4476f7", borderRadius: 3 }} + onPointerDown={this.toggleZoomToTarget2} onClick={e => e.stopPropagation()} + className="propertiesButton" + > + <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" /> + </button> + </div> </div> </div >; } @@ -1331,17 +1379,19 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { {this.editableTitle} </div> + {this.contextsSubMenu} + + {this.linksSubMenu} + {this.inkSubMenu} {this.optionsSubMenu} - {this.sharingSubMenu} - - {isNovice ? null : this.filtersSubMenu} + {this.fieldsSubMenu} - {isNovice ? null : this.fieldsSubMenu} + {isNovice ? null : this.sharingSubMenu} - {isNovice ? null : this.contextsSubMenu} + {isNovice ? null : this.filtersSubMenu} {isNovice ? null : this.layoutSubMenu} </div>; |