diff options
Diffstat (limited to 'src/client/views/PropertiesView.tsx')
-rw-r--r-- | src/client/views/PropertiesView.tsx | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 024db82a4..daa8e1720 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1,7 +1,4 @@ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable prettier/prettier */ -import { IconLookup } from '@fortawesome/fontawesome-svg-core'; +import { IconLookup, IconProp } from '@fortawesome/fontawesome-svg-core'; import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, Tooltip } from '@mui/material'; @@ -12,9 +9,10 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { ColorResult, SketchPicker } from 'react-color'; import * as Icons from 'react-icons/bs'; // {BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs" -import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../ClientUtils'; +import ResizeObserver from 'resize-observer-polyfill'; +import { ClientUtils, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; -import { Doc, Field, FieldResult, FieldType, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc'; +import { Doc, Field, FieldResult, FieldType, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast, returnEmptyDoclist } from '../../fields/Doc'; import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { InkField } from '../../fields/InkField'; @@ -38,14 +36,12 @@ import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector import { PropertiesDocContextSelector } from './PropertiesDocContextSelector'; import { PropertiesSection } from './PropertiesSection'; import './PropertiesView.scss'; -import { DefaultStyleProvider, SetFilterOpener as SetPropertiesFilterOpener } from './StyleProvider'; +import { DefaultStyleProvider, SetFilterOpener as SetPropertiesFilterOpener, returnEmptyDocViewList } from './StyleProvider'; import { DocumentView } from './nodes/DocumentView'; import { StyleProviderFuncType } from './nodes/FieldView'; import { OpenWhere } from './nodes/OpenWhere'; import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails'; -const _global = (window /* browser */ || global) /* node */ as any; - interface PropertiesViewProps { width: number; height: number; @@ -59,7 +55,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps // eslint-disable-next-line no-use-before-define public static Instance: PropertiesView | undefined; - constructor(props: any) { + constructor(props: PropertiesViewProps) { super(props); makeObservable(this); PropertiesView.Instance = this; @@ -142,7 +138,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps return this.selectedDoc?.isGroup; } @computed get isStack() { - return [CollectionViewType.Masonry, CollectionViewType.Multicolumn, CollectionViewType.Multirow, CollectionViewType.Stacking, CollectionViewType.NoteTaking].includes(this.selectedDoc?.type_collection as any); + return [CollectionViewType.Masonry, CollectionViewType.Multicolumn, CollectionViewType.Multirow, CollectionViewType.Stacking, CollectionViewType.NoteTaking].includes(this.selectedDoc?.type_collection as CollectionViewType); } rtfWidth = () => (!this.selectedLayoutDoc ? 0 : Math.min(NumCast(this.selectedLayoutDoc?._width), this._props.width - 20)); @@ -275,7 +271,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps @observable transform: Transform = Transform.Identity(); getTransform = () => this.transform; propertiesDocViewRef = (ref: HTMLDivElement) => { - const resizeObserver = new _global.ResizeObserver( + const resizeObserver = new ResizeObserver( action(() => { const cliRect = ref.getBoundingClientRect(); this.transform = new Transform(-cliRect.x, -cliRect.y, 1); @@ -326,7 +322,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps renderDepth={1} fitContentsToBox={returnTrue} styleProvider={DefaultStyleProvider} - containerViewPath={returnEmptyDoclist} + containerViewPath={returnEmptyDocViewList} dontCenter="y" isDocumentActive={returnFalse} isContentActive={emptyFunction} @@ -357,7 +353,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps * Handles the changing of a user's permissions from the permissions panel. */ @undoBatch - changePermissions = (e: any, user: string) => { + changePermissions = (e: React.ChangeEvent<HTMLSelectElement>, user: string) => { const docs = DocumentView.Selected().length < 2 ? [this.selectedDoc] : DocumentView.Selected().map(dv => (this.layoutDocAcls ? dv.layoutDoc : dv.dataDoc)); SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, docs, this.layoutDocAcls); }; @@ -456,7 +452,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps /** * Sorting algorithm to sort users. */ - sortUsers = (u1: String, u2: String) => (u1 > u2 ? -1 : u1 === u2 ? 0 : 1); + sortUsers = (u1: string, u2: string) => (u1 > u2 ? -1 : u1 === u2 ? 0 : 1); /** * Sorting algorithm to sort groups. @@ -711,7 +707,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps ); } - inputBox = (key: string, value: any, setter: (val: string) => {}, title: string) => ( + inputBox = (key: string, value: string | number | undefined, setter: (val: string) => void, title: string) => ( <div className="inputBox" style={{ @@ -721,17 +717,29 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="inputBox-title"> {title} </div> <input className="inputBox-input" type="text" value={value} style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }} onChange={e => setter(e.target.value)} onKeyDown={e => e.stopPropagation()} /> <div className="inputBox-button"> - <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}> + <div + className="inputBox-button-up" + key="up2" + onPointerDown={undoable( + action(() => this.upDownButtons('up', key)), + 'down btn' + )}> <FontAwesomeIcon icon="caret-up" size="sm" /> </div> - <div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}> + <div + className="inputbox-Button-down" + key="down2" + onPointerDown={undoable( + action(() => this.upDownButtons('down', key)), + 'up btn' + )}> <FontAwesomeIcon icon="caret-down" size="sm" /> </div> </div> </div> ); - inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => ( + inputBoxDuo = (key: string, value: string | number | undefined, setter: (val: string) => void, title1: string, key2: string, value2: string | number | undefined, setter2: (val: string) => void, title2: string) => ( <div className="inputBox-duo"> {this.inputBox(key, value, setter, title1)} {title2 === '' ? null : this.inputBox(key2, value2, setter2, title2)} @@ -841,7 +849,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps @observable private _fillBtn = false; @observable private _lineBtn = false; - private _lastDash: any = '2'; + private _lastDash: string = '2'; @computed get colorFil() { return StrCast(this.selectedDoc?.[DocData].fillColor); } // prettier-ignore set colorFil(value) { this.selectedDoc && (this.selectedDoc[DocData].fillColor = value || undefined); } // prettier-ignore @@ -917,7 +925,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps ); } - @computed get dashdStk() { return this.selectedDoc?.stroke_dash || ''; } // prettier-ignore + @computed get dashdStk() { return StrCast(this.selectedDoc?.stroke_dash); } // prettier-ignore set dashdStk(value) { value && (this._lastDash = value); this.selectedDoc && (this.selectedDoc[DocData].stroke_dash = value ? this._lastDash : undefined); @@ -939,14 +947,26 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps this.selectedDoc && (this.selectedDoc[DocData].stroke_endMarker = value); } - regInput = (key: string, value: any, setter: (val: string) => {}) => ( + regInput = (key: string, value: string | number | undefined, setter: (val: string) => void) => ( <div className="inputBox"> <input className="inputBox-input" type="text" value={value} style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }} onChange={e => setter(e.target.value)} /> <div className="inputBox-button"> - <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}> + <div + className="inputBox-button-up" + key="up2" + onPointerDown={undoable( + action(() => this.upDownButtons('up', key)), + 'up' + )}> <FontAwesomeIcon icon="caret-up" size="sm" /> </div> - <div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}> + <div + className="inputbox-Button-down" + key="down2" + onPointerDown={undoable( + action(() => this.upDownButtons('down', key)), + 'down' + )}> <FontAwesomeIcon icon="caret-down" size="sm" /> </div> </div> @@ -1002,7 +1022,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps className="arrows-head-input" type="checkbox" checked={this.markHead !== ''} - onChange={undoBatch(action(() => { this.markHead = this.markHead ? '' : 'arrow'; }))} + onChange={undoable(action(() => { this.markHead = this.markHead ? '' : 'arrow'; }), "change arrow head")} /> </div> <div className="arrows-tail"> @@ -1012,8 +1032,8 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps className="arrows-tail-input" type="checkbox" checked={this.markTail !== ''} - onChange={undoBatch( - action(() => { this.markTail = this.markTail ? '' : 'arrow'; }) + onChange={undoable( + action(() => { this.markTail = this.markTail ? '' : 'arrow'; }) ,"change arrow tail" )} /> </div> @@ -1044,7 +1064,8 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps setFinalNumber = () => { this._sliderBatch?.end(); }; - getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: any, autorange?: number, autorangeMinVal?: number) => ( + + getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: (val: number) => void, autorange?: number, autorangeMinVal?: number) => ( <div key={label + (this.selectedDoc?.title ?? '')}> <NumberInput formLabel={label} formLabelPlacement="left" type={Type.SEC} unit={unit} fillWidth color={this.color} number={number} setNumber={setNumber} min={min} max={max} /> <Slider @@ -1234,7 +1255,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps } @computed get description() { - return Field.toString(this.selectedLink?.link_description as any as FieldType); + return Field.toString(this.selectedLink?.link_description as FieldType); } @computed get relationship() { return StrCast(this.selectedLink?.link_relationship); @@ -1332,7 +1353,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div style={{ ...opts, border: direction === PresEffectDirection.Center ? `solid 2px ${color}` : undefined, borderRadius: '20%', cursor: 'pointer', gridColumn, gridRow, justifySelf: 'center', background: color, color: 'black' }} onClick={() => this.changeEffectDirection(direction)}> - {icon ? <FontAwesomeIcon icon={icon as any} /> : null} + {icon ? <FontAwesomeIcon icon={icon as IconProp} /> : null} </div> </Tooltip> ); @@ -1368,7 +1389,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps e, returnFalse, emptyFunction, - undoBatch(action(() => { this.selectedLink && (this.selectedLink[prop] = !this.selectedLink[prop]); })) // prettier-ignore + undoable(action(() => { this.selectedLink && (this.selectedLink[prop] = !this.selectedLink[prop]); }), `toggle prop: ${prop}`) // prettier-ignore ); }; @@ -1385,17 +1406,17 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps return selAnchor ?? (this.selectedLink && this.destinationAnchor ? Doc.getOppositeAnchor(this.selectedLink, this.destinationAnchor) : this.selectedLink); } - toggleAnchorProp = (e: React.PointerEvent, prop: string, anchor?: Doc, value: any = true, ovalue: any = false, cb: (val: any) => any = val => val) => { + toggleAnchorProp = (e: React.PointerEvent, prop: string, anchor?: Doc, value: FieldType = true, ovalue: FieldType = false, cb: (val: FieldType) => void = val => val) => { anchor && setupMoveUpEvents( this, e, returnFalse, emptyFunction, - undoBatch(action(() => { + undoable(action(() => { anchor[prop] = anchor[prop] === value ? ovalue : value; - this.selectedDoc && cb(anchor[prop]); - })) // prettier-ignore + this.selectedDoc && cb(anchor[prop] as boolean); + }), `toggle anchor prop: ${prop}`) // prettier-ignore ); }; @@ -1433,7 +1454,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps } // Converts seconds to ms and updates presTransition - setZoom = (number: String, change?: number) => { + setZoom = (number: string, change?: number) => { let scale = Number(number) / 100; if (change) scale += change; if (scale < 0.01) scale = 0.01; @@ -1530,7 +1551,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-input inline"> <p>Play Target Audio</p> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label <button type="button" style={{ background: !this.sourceAnchor?.followLinkAudio ? '' : '#4476f7', borderRadius: 3 }} @@ -1544,7 +1564,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-input inline"> <p>Play Target Video</p> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label <button type="button" style={{ background: !this.sourceAnchor?.followLinkVideo ? '' : '#4476f7', borderRadius: 3 }} @@ -1558,7 +1577,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-input inline"> <p>Zoom Text Selections</p> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label <button type="button" style={{ background: !this.sourceAnchor?.followLinkZoomText ? '' : '#4476f7', borderRadius: 3 }} @@ -1572,7 +1590,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-input inline"> <p>Toggle Follow to Outer Context</p> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label <button type="button" style={{ background: !this.sourceAnchor?.followLinkToOuterContext ? '' : '#4476f7', borderRadius: 3 }} @@ -1586,7 +1603,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-input inline"> <p>Toggle Target (Show/Hide)</p> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label <button type="button" style={{ background: !this.sourceAnchor?.followLinkToggle ? '' : '#4476f7', borderRadius: 3 }} @@ -1600,7 +1616,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-input inline"> <p>Ease Transitions</p> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label <button type="button" style={{ background: this.sourceAnchor?.followLinkEase === 'linear' ? '' : '#4476f7', borderRadius: 3 }} @@ -1614,7 +1629,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-input inline"> <p>Capture Offset to Target</p> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label <button type="button" style={{ background: this.sourceAnchor?.followLinkXoffset === undefined ? '' : '#4476f7', borderRadius: 3 }} @@ -1631,7 +1645,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="propertiesView-input inline"> <p>Center Target (no zoom)</p> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label <button type="button" style={{ background: this.sourceAnchor?.followLinkZoom ? '' : '#4476f7', borderRadius: 3 }} @@ -1647,16 +1660,15 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="ribbon-property" style={{ display: !targZoom ? 'none' : 'inline-flex' }}> <input className="presBox-input" style={{ width: '100%', color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }} readOnly type="number" value={zoom} /> <div className="ribbon-propertyUpDown" style={{ display: 'flex', flexDirection: 'column' }}> - <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), 0.1))}> + <div className="ribbon-propertyUpDownItem" onClick={undoable(() => this.setZoom(String(zoom), 0.1), 'Zoom out')}> <FontAwesomeIcon icon="caret-up" /> </div> - <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), -0.1))}> + <div className="ribbon-propertyUpDownItem" onClick={undoable(() => this.setZoom(String(zoom), -0.1), 'Zoom in')}> <FontAwesomeIcon icon="caret-down" /> </div> </div> </div> { - // eslint-disable-next-line jsx-a11y/control-has-associated-label <button type="button" style={{ background: !targZoom || this.sourceAnchor?.followLinkZoomScale === 0 ? '' : '#4476f7', borderRadius: 3, gridColumn: 3 }} @@ -1746,8 +1758,8 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps } if (this.isPres && PresBox.Instance) { const selectedItem: boolean = PresBox.Instance.selectedArray.size > 0; - const type = [DocumentType.AUDIO, DocumentType.VID].includes(DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as any as DocumentType) - ? (DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as any as DocumentType) + const type = [DocumentType.AUDIO, DocumentType.VID].includes(DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as DocumentType) + ? (DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as DocumentType) : PresBox.targetRenderedDoc(PresBox.Instance.activeItem)?.type; return ( <div className="propertiesView" style={{ width: this._props.width }}> |