From 4c8eee9811abd072d2a6adfe24eaf04f980ccf21 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 9 Aug 2023 15:21:20 -0400 Subject: updated file system to include recentlyClosed, Shared, and Dashboards and fixed drag drop to make sense for the filesystem. Fixed loading documents to happen in one batch by fixing UPDATE_CACHED_DOCS to save only documents accessible from current dashboard. --- src/fields/Doc.ts | 81 +++++++++++++++++++++++++++++++++------------- src/fields/FieldLoader.tsx | 5 ++- 2 files changed, 60 insertions(+), 26 deletions(-) (limited to 'src/fields') diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 5a411a201..eb52cff88 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -238,22 +238,6 @@ export class Doc extends RefField { public static get MyFilesystem() { return DocCast(Doc.UserDoc().myFilesystem); } - public static get MyFileOrphans() { - return DocCast(Doc.UserDoc().myFileOrphans); - } - public static AddFileOrphan(doc: Doc) { - if ( - doc && - Doc.MyFileOrphans instanceof Doc && - Doc.IsDataProto(doc) && - !Doc.IsSystem(doc) && - ![DocumentType.CONFIG, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR].includes(doc.type as any) && - !doc.isFolder && - !doc.annotationOn - ) { - Doc.AddDocToList(Doc.MyFileOrphans, undefined, doc); - } - } public static get MyTools() { return DocCast(Doc.UserDoc().myTools); } @@ -388,7 +372,7 @@ export class Doc extends RefField { } else { return Cast(layoutField, Doc, null); } - return Cast(self[renderFieldKey + '-layout[' + templateLayoutDoc[Id] + ']'], Doc, null) || templateLayoutDoc; + return Cast(self[renderFieldKey + '_layout[' + templateLayoutDoc[Id] + ']'], Doc, null) || templateLayoutDoc; } return undefined; } @@ -701,7 +685,8 @@ export namespace Doc { } export function BestEmbedding(doc: Doc) { - const bestEmbedding = Doc.GetProto(doc) ? DocListCast(doc.proto_embeddings).find(doc => !doc.embedContainer && doc.author === Doc.CurrentUserEmail) : doc; + const bestEmbedding = Doc.GetProto(doc) ? [doc, ...DocListCast(doc.proto_embeddings)].find(doc => !doc.embedContainer && doc.author === Doc.CurrentUserEmail) : doc; + bestEmbedding && Doc.AddDocToList(Doc.GetProto(doc), 'protoEmbeddings', doc); return bestEmbedding ?? Doc.MakeEmbedding(doc); } @@ -782,7 +767,6 @@ export namespace Doc { copy.cloneOf = doc; cloneMap.set(doc[Id], copy); - Doc.AddFileOrphan(copy); return copy; } export function repairClone(clone: Doc, cloneMap: Map, visited: Set) { @@ -917,7 +901,7 @@ export namespace Doc { // If it doesn't find the expanded layout, then it makes a delegate of the template layout and // saves it on the data doc indexed by the template layout's id. // - const expandedLayoutFieldKey = templateField + '-layout[' + templateLayoutDoc[Id] + ']'; + const expandedLayoutFieldKey = templateField + '_layout[' + templateLayoutDoc[Id] + ']'; let expandedTemplateLayout = targetDoc?.[expandedLayoutFieldKey]; if (templateLayoutDoc.resolvedDataDoc instanceof Promise) { @@ -985,6 +969,59 @@ export namespace Doc { return overwrite; } + export function FindReferences(infield: Doc | List, references: Set, system: boolean | undefined) { + if (infield instanceof List) { + infield.forEach(val => (val instanceof Doc || val instanceof List) && FindReferences(val, references, system)); + return; + } + const doc = infield as Doc; + if (references.has(doc)) { + references.add(doc); + return; + } + const excludeLists = doc.title === 'My Recently Closed' || doc.title === 'My Header Bar' || doc.title === 'My Dashboards'; + if (system !== undefined && ((system && !Doc.IsSystem(doc)) || (!system && Doc.IsSystem(doc)))) return; + references.add(doc); + Object.keys(doc).forEach(key => { + if (key === 'proto') { + if (doc.proto instanceof Doc) { + Doc.FindReferences(doc.proto, references, system); + } + } else { + const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); + const field = key === 'author' ? Doc.CurrentUserEmail : ProxyField.WithoutProxy(() => doc[key]); + if (field instanceof RefField) { + if (field instanceof Doc) { + if (key === 'myLinkDatabase') { + field instanceof Doc && references.add(field); + // skip docs that have been closed and are scheduled for garbage collection + } else { + Doc.FindReferences(field, references, system); + } + } + } else if (cfield instanceof ComputedField) { + } else if (field instanceof ObjectField) { + if (field instanceof Doc) { + Doc.FindReferences(field, references, system); + } else if (field instanceof List) { + !excludeLists && Doc.FindReferences(field, references, system); + } else if (field instanceof ProxyField) { + if (key === 'myLinkDatabase') { + field instanceof Doc && references.add(field); + // skip docs that have been closed and are scheduled for garbage collection + } else { + Doc.FindReferences(field.value, references, system); + } + } else if (field instanceof PrefetchProxy) { + Doc.FindReferences(field.value, references, system); + } + } else if (field instanceof Promise) { + debugger; //This shouldn't happend... + } + } + }); + } + export function MakeCopy(doc: Doc, copyProto: boolean = false, copyProtoId?: string, retitle = false): Doc { const copy = new Doc(copyProtoId, true); updateCachedAcls(copy); @@ -1025,7 +1062,6 @@ export namespace Doc { if (retitle) { copy.title = incrementTitleCopy(StrCast(copy.title)); } - Doc.AddFileOrphan(copy); return copy; } @@ -1044,7 +1080,6 @@ export namespace Doc { if (!Doc.IsSystem(doc)) Doc.AddDocToList(doc[DocData], 'proto_embeddings', delegate); title && (delegate.title = title); delegate[Initializing] = false; - Doc.AddFileOrphan(delegate); return delegate; } return undefined; @@ -1177,7 +1212,7 @@ export namespace Doc { // the document containing the view layout information - will be the Document itself unless the Document has // a layout field or 'layout' is given. export function Layout(doc: Doc, layout?: Doc): Doc { - const overrideLayout = layout && Cast(doc[`${StrCast(layout.isTemplateForField, 'data')}-layout[` + layout[Id] + ']'], Doc, null); + const overrideLayout = layout && Cast(doc[`${StrCast(layout.isTemplateForField, 'data')}_layout[` + layout[Id] + ']'], Doc, null); return overrideLayout || doc[DocLayout] || doc; } export function SetLayout(doc: Doc, layout: Doc | string) { diff --git a/src/fields/FieldLoader.tsx b/src/fields/FieldLoader.tsx index 2a7b936f7..a5a71833c 100644 --- a/src/fields/FieldLoader.tsx +++ b/src/fields/FieldLoader.tsx @@ -6,10 +6,9 @@ import './FieldLoader.scss'; @observer export class FieldLoader extends React.Component { - @observable public static ServerLoadStatus = { requested: 0, retrieved: 0 }; - public static active = false; + @observable public static ServerLoadStatus = { requested: 0, retrieved: 0, message: '' }; render() { - return
{`Requested: ${FieldLoader.ServerLoadStatus.requested} ... ${FieldLoader.ServerLoadStatus.retrieved} `}
; + return
{`${FieldLoader.ServerLoadStatus.message} request: ${FieldLoader.ServerLoadStatus.requested} ... ${FieldLoader.ServerLoadStatus.retrieved} `}
; } } -- cgit v1.2.3-70-g09d2 From 45fa677df8f95789a6308a75067139648b9b683e Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 10 Aug 2023 12:46:06 -0400 Subject: out of data version alert client side --- src/client/util/CurrentUserUtils.ts | 4 +++- src/client/util/SettingsManager.tsx | 4 ++-- src/client/views/topbar/TopBar.tsx | 7 ++++--- src/fields/DocSymbols.ts | 2 ++ src/fields/Types.ts | 9 ++++----- src/mobile/MobileMain.tsx | 2 +- src/server/ApiManagers/UserManager.ts | 14 +++++++++++++- 7 files changed, 29 insertions(+), 13 deletions(-) (limited to 'src/fields') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f8fc2b531..ad9913c7d 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -914,10 +914,12 @@ export class CurrentUserUtils { }); } + public static ServerVersion: string = ';' public static async loadCurrentUser() { return rp.get(Utils.prepend("/getCurrentUser")).then(async response => { if (response) { - const result: { userDocumentId: string, sharingDocumentId: string, linkDatabaseId: string, email: string, cacheDocumentIds: string, resolvedPorts: string } = JSON.parse(response); + const result: { version: string, userDocumentId: string, sharingDocumentId: string, linkDatabaseId: string, email: string, cacheDocumentIds: string, resolvedPorts: string } = JSON.parse(response); + CurrentUserUtils.ServerVersion = result.version; Doc.CurrentUserEmail = result.email; resolvedPorts = result.resolvedPorts as any; DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts.socket, result.email); diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 534a5dbc6..b2b5be070 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -6,6 +6,7 @@ import * as React from 'react'; import { BsGoogle } from 'react-icons/bs'; import { FaFillDrip, FaPalette } from 'react-icons/fa'; import { Doc } from '../../fields/Doc'; +import { DashVersion } from '../../fields/DocSymbols'; import { BoolCast, Cast, StrCast } from '../../fields/Types'; import { addStyleSheet, addStyleSheetRule, Utils } from '../../Utils'; import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager'; @@ -36,7 +37,6 @@ export enum freeformScrollMode { @observer export class SettingsManager extends React.Component<{}> { - static Version = 'v0.5.2'; public static Instance: SettingsManager; static _settingsStyle = addStyleSheet(); @observable public isOpen = false; @@ -450,7 +450,7 @@ export class SettingsManager extends React.Component<{}> {
-
{SettingsManager.Version}
+
{DashVersion}
{Doc.CurrentUserEmail}
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx index 8caba930d..bdea07fe7 100644 --- a/src/client/views/topbar/TopBar.tsx +++ b/src/client/views/topbar/TopBar.tsx @@ -5,7 +5,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { FaBug, FaCamera, FaStamp } from 'react-icons/fa'; import { Doc, DocListCast } from '../../../fields/Doc'; -import { AclAdmin } from '../../../fields/DocSymbols'; +import { AclAdmin, DashVersion } from '../../../fields/DocSymbols'; import { StrCast } from '../../../fields/Types'; import { GetEffectiveAcl } from '../../../fields/util'; import { DocumentManager } from '../../util/DocumentManager'; @@ -21,6 +21,7 @@ import { MainView } from '../MainView'; import { CollectionDockingView } from '../collections/CollectionDockingView'; import { Colors } from '../global/globalEnums'; import './TopBar.scss'; +import { CurrentUserUtils } from '../../util/CurrentUserUtils'; /** * ABOUT: This is the topbar in Dash, which included the current Dashboard as well as access to information on the user @@ -155,8 +156,8 @@ export class TopBar extends React.Component { size={Size.SMALL} onClick={ServerStats.Instance.open} type={Type.TERT} - tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running ' + SettingsManager.Version} - color={this.happyHeart ? Colors.LIGHT_BLUE : Colors.ERROR_RED} + tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running ' + DashVersion} + color={this.happyHeart ? (DashVersion === CurrentUserUtils.ServerVersion ? Colors.LIGHT_BLUE : Colors.YELLOW) : Colors.ERROR_RED} icon={} /> {/*