aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/PropertiesView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/PropertiesView.tsx')
-rw-r--r--src/client/views/PropertiesView.tsx92
1 files changed, 45 insertions, 47 deletions
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 76ea9123d..2fcb5d12a 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -1,14 +1,15 @@
-import React = require('react');
import { IconLookup } 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 '@material-ui/core';
+import { Checkbox, Tooltip } from '@mui/material';
import { Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components';
import { concat } from 'lodash';
-import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
-import { ColorState, SketchPicker } from 'react-color';
+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 { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
import { AclAdmin, DocAcl, DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
@@ -16,8 +17,7 @@ import { InkField } from '../../fields/InkField';
import { List } from '../../fields/List';
import { ComputedField } from '../../fields/ScriptField';
import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
-import { GetEffectiveAcl, normalizeEmail, SharingPermissions } from '../../fields/util';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../Utils';
+import { GetEffectiveAcl, SharingPermissions, normalizeEmail } from '../../fields/util';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
import { DocumentManager } from '../util/DocumentManager';
import { GroupManager } from '../util/GroupManager';
@@ -26,19 +26,20 @@ import { SelectionManager } from '../util/SelectionManager';
import { SettingsManager } from '../util/SettingsManager';
import { SharingManager } from '../util/SharingManager';
import { Transform } from '../util/Transform';
-import { undoable, undoBatch, UndoManager } from '../util/UndoManager';
+import { UndoManager, undoBatch, undoable } from '../util/UndoManager';
import { EditableView } from './EditableView';
import { FilterPanel } from './FilterPanel';
import { InkStrokeProperties } from './InkStrokeProperties';
-import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView';
-import { KeyValueBox } from './nodes/KeyValueBox';
-import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
+import { ObservableReactComponent } from './ObservableReactComponent';
import { PropertiesButtons } from './PropertiesButtons';
import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector';
import { PropertiesDocContextSelector } from './PropertiesDocContextSelector';
import { PropertiesSection } from './PropertiesSection';
import './PropertiesView.scss';
import { DefaultStyleProvider } from './StyleProvider';
+import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView';
+import { KeyValueBox } from './nodes/KeyValueBox';
+import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
const _global = (window /* browser */ || global) /* node */ as any;
interface PropertiesViewProps {
@@ -49,12 +50,13 @@ interface PropertiesViewProps {
}
@observer
-export class PropertiesView extends React.Component<PropertiesViewProps> {
+export class PropertiesView extends ObservableReactComponent<PropertiesViewProps> {
private _widthUndo?: UndoManager.Batch;
public static Instance: PropertiesView | undefined;
constructor(props: any) {
super(props);
+ makeObservable(this);
PropertiesView.Instance = this;
}
@@ -63,14 +65,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
@computed get selectedDoc() {
- return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.Document || Doc.ActiveDashboard;
+ return SelectionManager.SelectedSchemaDoc || this.selectedDocumentView?.Document || Doc.ActiveDashboard;
}
@computed get selectedLayoutDoc() {
- return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.layoutDoc || Doc.ActiveDashboard;
+ return SelectionManager.SelectedSchemaDoc || this.selectedDocumentView?.layoutDoc || Doc.ActiveDashboard;
}
@computed get selectedDocumentView() {
- if (SelectionManager.Views().length) return SelectionManager.Views()[0];
+ if (SelectionManager.Views.length) return SelectionManager.Views[0];
if (PresBox.Instance?.selectedArray.size) return DocumentManager.Instance.getDocumentView(PresBox.Instance.Document);
return undefined;
}
@@ -130,7 +132,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
return [CollectionViewType.Stacking, CollectionViewType.NoteTaking].includes(this.selectedDoc?.type_collection as any);
}
- rtfWidth = () => (!this.selectedLayoutDoc ? 0 : Math.min(NumCast(this.selectedLayoutDoc?._width), this.props.width - 20));
+ rtfWidth = () => (!this.selectedLayoutDoc ? 0 : Math.min(NumCast(this.selectedLayoutDoc?._width), this._props.width - 20));
rtfHeight = () => (!this.selectedLayoutDoc ? 0 : this.rtfWidth() <= NumCast(this.selectedLayoutDoc?._width) ? Math.min(NumCast(this.selectedLayoutDoc?._height), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT);
@action
@@ -138,8 +140,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const layoutDoc = this.selectedLayoutDoc;
if (layoutDoc) {
const aspect = Doc.NativeAspect(layoutDoc, undefined, !layoutDoc._layout_fitWidth);
- if (aspect) return Math.min(NumCast(layoutDoc._width), Math.min(this.MAX_EMBED_HEIGHT * aspect, this.props.width - 20));
- return Doc.NativeWidth(layoutDoc) ? Math.min(NumCast(layoutDoc._width), this.props.width - 20) : this.props.width - 20;
+ if (aspect) return Math.min(NumCast(layoutDoc._width), Math.min(this.MAX_EMBED_HEIGHT * aspect, this._props.width - 20));
+ return Doc.NativeWidth(layoutDoc) ? Math.min(NumCast(layoutDoc._width), this._props.width - 20) : this._props.width - 20;
}
return 0;
};
@@ -155,10 +157,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
Doc.NativeAspect(layoutDoc, undefined, true)
? this.docWidth() / Doc.NativeAspect(layoutDoc, undefined, true)
: layoutDoc._layout_fitWidth
- ? !Doc.NativeHeight(this.dataDoc)
- ? NumCast(this.props.height)
- : Math.min((this.docWidth() * Doc.NativeHeight(layoutDoc)) / Doc.NativeWidth(layoutDoc) || NumCast(this.props.height))
- : NumCast(layoutDoc._height) || 50
+ ? !Doc.NativeHeight(this.dataDoc)
+ ? NumCast(this._props.height)
+ : Math.min((this.docWidth() * Doc.NativeHeight(layoutDoc)) / Doc.NativeWidth(layoutDoc) || NumCast(this._props.height))
+ : NumCast(layoutDoc._height) || 50
)
);
}
@@ -169,7 +171,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const rows: JSX.Element[] = [];
if (this.dataDoc && this.selectedDoc) {
const ids = new Set<string>(reqdKeys);
- const docs: Doc[] = SelectionManager.Views().length < 2 ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : SelectionManager.Views().map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc));
+ const docs: Doc[] = SelectionManager.Views.length < 2 ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : SelectionManager.Views.map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc));
docs.forEach(doc => Object.keys(doc).forEach(key => doc[key] !== ComputedField.undefined && ids.add(key)));
// prettier-ignore
@@ -218,7 +220,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@undoBatch
setKeyValue = (value: string) => {
- const docs = SelectionManager.Views().length < 2 && this.selectedDoc ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc!] : SelectionManager.Views().map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc));
+ const docs = SelectionManager.Views.length < 2 && this.selectedDoc ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc!] : SelectionManager.Views.map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc));
docs.forEach(doc => {
if (value.indexOf(':') !== -1) {
const newVal = value[0].toUpperCase() + value.substring(1, value.length);
@@ -254,12 +256,12 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
};
@computed get contexts() {
- return !this.selectedDoc ? null : <PropertiesDocContextSelector DocView={this.selectedDocumentView} hideTitle={true} addDocTab={this.props.addDocTab} />;
+ return !this.selectedDoc ? null : <PropertiesDocContextSelector DocView={this.selectedDocumentView} hideTitle={true} addDocTab={this._props.addDocTab} />;
}
@computed get contextCount() {
if (this.selectedDocumentView) {
- const target = this.selectedDocumentView.props.Document;
+ const target = this.selectedDocumentView.Document;
const embeddings = DocListCast(target.proto_embeddings);
return embeddings.length - 1;
} else {
@@ -269,7 +271,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@computed get links() {
const selAnchor = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.currentLinkAnchor ?? this.selectedDoc;
- return !selAnchor ? null : <PropertiesDocBacklinksSelector Document={selAnchor} hideTitle={true} addDocTab={this.props.addDocTab} />;
+ return !selAnchor ? null : <PropertiesDocBacklinksSelector Document={selAnchor} hideTitle={true} addDocTab={this._props.addDocTab} />;
}
@computed get linkCount() {
@@ -282,7 +284,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
@computed get layoutPreview() {
- if (SelectionManager.Views().length > 1) {
+ if (SelectionManager.Views.length > 1) {
return '-- multiple selected --';
}
if (this.selectedDoc) {
@@ -293,10 +295,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div ref={this.propertiesDocViewRef} style={{ pointerEvents: 'none', display: 'inline-block', height: panelHeight() }} key={this.selectedDoc[Id]}>
<DocumentView
Document={this.selectedDoc}
- DataDoc={this.dataDoc}
+ TemplateDataDocument={Doc.AreProtosEqual(this.dataDoc, this.selectedDoc) ? undefined : this.dataDoc}
renderDepth={1}
fitContentsToBox={returnTrue}
- rootSelected={returnFalse}
styleProvider={DefaultStyleProvider}
docViewPath={returnEmptyDoclist}
dontCenter={'y'}
@@ -332,7 +333,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(dv => (this.layoutDocAcls ? dv.layoutDoc : dv.dataDoc));
+ const docs = SelectionManager.Views.length < 2 ? [this.selectedDoc] : SelectionManager.Views.map(dv => (this.layoutDocAcls ? dv.layoutDoc : dv.dataDoc));
SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, docs, this.layoutDocAcls);
};
@@ -378,7 +379,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
color={SettingsManager.userColor}
onClick={action(() => {
if (this.selectedDocumentView || this.selectedDoc) {
- SharingManager.Instance.open(this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined, this.selectedDoc);
+ SharingManager.Instance.open(this.selectedDocumentView?.Document === this.selectedDoc ? this.selectedDocumentView : undefined, this.selectedDoc);
}
})}
/>
@@ -450,7 +451,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
*/
@computed get sharingTable() {
// all selected docs
- const docs = SelectionManager.Views().length < 2 && this.selectedDoc ? [this.selectedDoc] : SelectionManager.Views().map(docView => docView.rootDoc);
+ const docs = SelectionManager.Views.length < 2 && this.selectedDoc ? [this.selectedDoc] : SelectionManager.Views.map(docView => docView.Document);
const target = docs[0];
const showAdmin = GetEffectiveAcl(target) == AclAdmin;
@@ -566,7 +567,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@computed get editableTitle() {
const titles = new Set<string>();
- SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title)));
+ SelectionManager.Views.forEach(dv => titles.add(StrCast(dv.Document.title)));
const title = Array.from(titles.keys()).length > 1 ? '--multiple selected--' : StrCast(this.selectedDoc?.title);
return (
<div>
@@ -620,10 +621,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
@undoBatch
- @action
setTitle = (value: string | number) => {
- if (SelectionManager.Views().length > 1) {
- SelectionManager.Views().map(dv => Doc.SetInPlace(dv.rootDoc, 'title', value, true));
+ if (SelectionManager.Views.length > 1) {
+ SelectionManager.Views.map(dv => Doc.SetInPlace(dv.Document, 'title', value, true));
} else if (this.dataDoc) {
if (this.selectedDoc) Doc.SetInPlace(this.selectedDoc, 'title', value, true);
else KeyValueBox.SetField(this.dataDoc, 'title', value as string, true);
@@ -631,7 +631,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
};
@undoBatch
- @action
rotate = (angle: number) => {
const _centerPoints: { X: number; Y: number }[] = [];
const doc = this.selectedDoc;
@@ -876,7 +875,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
return (
<SketchPicker
onChange={undoable(
- action((color: ColorState) => setter(color.hex)),
+ action((color: ColorResult) => setter(color.hex)),
'set stroke color property'
)}
presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
@@ -1058,7 +1057,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
@undoBatch
- @action
changeDash = () => {
this.dashdStk = this.dashdStk === '2' ? '0' : '2';
};
@@ -1173,7 +1171,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
return (
<PropertiesSection title="Filters" isOpen={this.openFilters} setIsOpen={bool => (this.openFilters = bool)} onDoubleClick={() => this.CloseAll()}>
<div className="propertiesView-content filters" style={{ position: 'relative', height: 'auto' }}>
- <FilterPanel rootDoc={this.selectedDoc ?? Doc.ActiveDashboard!} />
+ <FilterPanel Document={this.selectedDoc ?? Doc.ActiveDashboard!} />
</div>
</PropertiesSection>
);
@@ -1677,8 +1675,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const hasSelectedAnchor = LinkManager.Links(this.sourceAnchor).includes(LinkManager.currentLink!);
if (!this.selectedDoc && !this.isPres) {
return (
- <div className="propertiesView" style={{ width: this.props.width }}>
- <div className="propertiesView-title" style={{ width: this.props.width }}>
+ <div className="propertiesView" style={{ width: this._props.width }}>
+ <div className="propertiesView-title" style={{ width: this._props.width }}>
No Document Selected
</div>
</div>
@@ -1691,11 +1689,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
style={{
background: SettingsManager.userBackgroundColor,
color: SettingsManager.userColor,
- width: this.props.width,
- minWidth: this.props.width,
+ width: this._props.width,
+ minWidth: this._props.width,
}}>
<div className="propertiesView-propAndInfoGrouping">
- <div className="propertiesView-title" style={{ width: this.props.width }}>
+ <div className="propertiesView-title" style={{ width: this._props.width }}>
Properties
<div className="propertiesView-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/properties')}>
<IconButton icon={<FontAwesomeIcon icon="info-circle" />} color={SettingsManager.userColor} />
@@ -1723,8 +1721,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
? (DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as any as DocumentType)
: PresBox.targetRenderedDoc(PresBox.Instance.activeItem)?.type;
return (
- <div className="propertiesView" style={{ width: this.props.width }}>
- <div className="propertiesView-sectionTitle" style={{ width: this.props.width }}>
+ <div className="propertiesView" style={{ width: this._props.width }}>
+ <div className="propertiesView-sectionTitle" style={{ width: this._props.width }}>
Presentation
</div>
<div className="propertiesView-name" style={{ borderBottom: 0 }}>