aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/Documents.ts20
-rw-r--r--src/client/views/DocComponent.tsx13
-rw-r--r--src/client/views/collections/CollectionView.tsx14
-rw-r--r--src/client/views/nodes/FontIconBox.tsx8
-rw-r--r--src/fields/Doc.ts4
5 files changed, 32 insertions, 27 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 71fc5c40d..0a3865a13 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -175,7 +175,7 @@ export class DocumentOptions {
hideAllLinks?: boolean; // whether all individual blue anchor dots should be hidden
isTemplateForField?: string; // the field key for which the containing document is a rendering template
isTemplateDoc?: boolean;
- watchedDocuments?: Doc; // list of documents to "watch" in an icon doc to display a badge
+ watchedDocuments?: Doc; // list of documents an icon doc monitors in order to display a badge count
targetScriptKey?: string; // where to write a template script (used by collections with click templates which need to target onClick, onDoubleClick, etc)
templates?: List<string>;
hero?: ImageField; // primary image that best represents a compound document (e.g., for a buxton device document that has multiple images)
@@ -1351,6 +1351,24 @@ export namespace DocUtils {
}
}
+ export function LeavePushpin(doc: Doc) {
+ if (doc.isPushpin) return undefined;
+ const context = Cast(doc.context, Doc, null) ?? Cast(doc.annotationOn, Doc, null);
+ const hasContextAnchor = DocListCast(doc.links).some(l => (l.anchor2 === doc && Cast(l.anchor1, Doc, null)?.annotationOn === context) || (l.anchor1 === doc && Cast(l.anchor2, Doc, null)?.annotationOn === context));
+ if (context && !hasContextAnchor && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) {
+ const pushpin = Docs.Create.FontIconDocument({
+ title: "pushpin", label: "", annotationOn: Cast(doc.annotationOn, Doc, null), isPushpin: true,
+ icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), backgroundColor: "#ACCEF7",
+ _width: 15, _height: 15, _xPadding: 0, isLinkButton: true, _timecodeToShow: Cast(doc._timecodeToShow, "number", null)
+ });
+ Doc.AddDocToList(context, Doc.LayoutFieldKey(context) + "-annotations", pushpin);
+ const pushpinLink = DocUtils.MakeLink({ doc: pushpin }, { doc: doc }, "pushpin", "");
+ doc._timecodeToShow = undefined;
+ return pushpin;
+ }
+ return undefined;
+ }
+
export async function addFieldEnumerations(doc: Opt<Doc>, enumeratedFieldKey: string, enumerations: { title: string, _backgroundColor?: string, color?: string }[]) {
let optionsCollection = await DocServer.GetRefField(enumeratedFieldKey);
if (!(optionsCollection instanceof Doc)) {
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index f8aede717..876fbac54 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -9,6 +9,7 @@ import { DateField } from '../../fields/DateField';
import { ScriptField } from '../../fields/ScriptField';
import { GetEffectiveAcl, SharingPermissions, distributeAcls, denormalizeEmail } from '../../fields/util';
import { CurrentUserUtils } from '../util/CurrentUserUtils';
+import { DocUtils } from '../documents/Documents';
/// DocComponent returns a generic React base class used by views that don't have 'fieldKey' props (e.g.,CollectionFreeFormDocumentView, DocumentView)
@@ -127,16 +128,15 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
public get annotationKey() { return this.fieldKey + "-" + this._annotationKey; }
@action.bound
- removeDocument(doc: Doc | Doc[], annotationKey?: string): boolean {
+ removeDocument(doc: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean): boolean {
const effectiveAcl = GetEffectiveAcl(this.dataDoc);
const indocs = doc instanceof Doc ? [doc] : doc;
const docs = indocs.filter(doc => effectiveAcl === AclEdit || effectiveAcl === AclAdmin || GetEffectiveAcl(doc) === AclAdmin);
if (docs.length) {
- const docs = doc instanceof Doc ? [doc] : doc;
- docs.map(doc => {
+ setTimeout(() => docs.map(doc => { // this allows 'addDocument' to see the annotationOn field in order to create a pushin
Doc.SetInPlace(doc, "isPushpin", undefined, true);
- Doc.SetInPlace(doc, "annotationOn", undefined, true);
- });
+ doc.annotationOn === this.props.Document && Doc.SetInPlace(doc, "annotationOn", undefined, true);
+ }));
const targetDataDoc = this.dataDoc;
const value = DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]);
const toRemove = value.filter(v => docs.includes(v));
@@ -144,6 +144,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
if (toRemove.length !== 0) {
const recent = Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc) as Doc;
toRemove.forEach(doc => {
+ leavePushpin && DocUtils.LeavePushpin(doc);
Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, doc);
doc.context = undefined;
recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
@@ -159,7 +160,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
// otherwise, if the document can be removed from where it was, it will then be added to this document's overlay collection.
@action.bound
moveDocument(doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean, annotationKey?: string): boolean {
- return Doc.AreProtosEqual(this.props.Document, targetCollection) ? true : this.removeDocument(doc, annotationKey) ? addDocument(doc) : false;
+ return Doc.AreProtosEqual(this.props.Document, targetCollection) ? true : this.removeDocument(doc, annotationKey, true) ? addDocument(doc) : false;
}
@action.bound
addDocument(doc: Doc | Doc[], annotationKey?: string): boolean {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index be5a4b852..34fd20f1a 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -154,19 +154,7 @@ export class CollectionView extends Touchable<CollectionViewProps> {
}
else {
added.filter(doc => [AclAdmin, AclEdit].includes(GetEffectiveAcl(doc))).map(doc => { // only make a pushpin if we have acl's to edit the document
- const context = Cast(doc.context, Doc, null);
- const hasContextAnchor = DocListCast(doc.links).some(l => (l.anchor2 === doc && Cast(l.anchor1, Doc, null)?.annotationOn === context) || (l.anchor1 === doc && Cast(l.anchor2, Doc, null)?.annotationOn === context));
- if (context && !hasContextAnchor && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) {
- const pushpin = Docs.Create.FontIconDocument({
- title: "pushpin", label: "", annotationOn: Cast(doc.annotationOn, Doc, null), isPushpin: true,
- icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), backgroundColor: "#0000003d", color: "#ACCEF7",
- _width: 15, _height: 15, _xPadding: 0, isLinkButton: true, _timecodeToShow: Cast(doc._timecodeToShow, "number", null)
- });
- Doc.SetInPlace(doc, "annotationOn", undefined, true);
- Doc.AddDocToList(context, Doc.LayoutFieldKey(context) + "-annotations", pushpin);
- const pushpinLink = DocUtils.MakeLink({ doc: pushpin }, { doc: doc }, "pushpin", "");
- doc._timecodeToShow = undefined;
- }
+ DocUtils.LeavePushpin(doc);
doc._stayInCollection = undefined;
doc.context = this.props.Document;
});
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 56c79cde9..22815388d 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -49,14 +49,12 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
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}`} onContextMenu={this.specificContextMenu}
- style={{
- backgroundColor: this.layoutDoc.iconShape === "square" ? backgroundColor : "",
- }}>
+ style={{ backgroundColor: backgroundColor, }}>
<div className="menuButton-wrap">
{icon === 'pres-trail' ? presTrailsIcon : <FontAwesomeIcon className={`menuButton-icon-${shape}`} icon={icon} color={color}
size={this.layoutDoc.iconShape === "square" ? "sm" : "sm"} />}
{!label ? (null) : <div className="fontIconBox-label" style={{ color, backgroundColor }}> {label} </div>}
- {this.props.Document.watchedDocuments ? <FontIconBadge collection={Cast(this.props.Document.watchedDocuments, Doc, null)} /> : (null)}
+ <FontIconBadge collection={Cast(this.rootDoc.watchedDocuments, Doc, null)} />
</div>
</button>;
return !this.layoutDoc.toolTip ? button :
@@ -67,7 +65,7 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
}
interface FontIconBadgeProps {
- collection: Doc;
+ collection: Doc | undefined;
}
@observer
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index e26d771d3..5a8b1097a 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1063,9 +1063,9 @@ export namespace Doc {
// filters document in a container collection:
// all documents with the specified value for the specified key are included/excluded
// based on the modifiers :"check", "x", undefined
- export function setDocFilter(target: Opt<Doc>, key: string, value: any, modifiers: "remove" | "match" | "check" | "x", toggle?: boolean, fieldSuffix?:string) {
+ export function setDocFilter(target: Opt<Doc>, key: string, value: any, modifiers: "remove" | "match" | "check" | "x", toggle?: boolean, fieldSuffix?: string) {
const container = target ?? CollectionDockingView.Instance.props.Document;
- const filterField = "_"+(fieldSuffix ? fieldSuffix+"-":"")+"docFilters";
+ const filterField = "_" + (fieldSuffix ? fieldSuffix + "-" : "") + "docFilters";
const docFilters = Cast(container[filterField], listSpec("string"), []);
runInAction(() => {
for (let i = 0; i < docFilters.length; i++) {