diff options
Diffstat (limited to 'src/client/documents')
| -rw-r--r-- | src/client/documents/DocUtils.ts | 70 | ||||
| -rw-r--r-- | src/client/documents/DocumentTypes.ts | 5 | ||||
| -rw-r--r-- | src/client/documents/Documents.ts | 74 |
3 files changed, 90 insertions, 59 deletions
diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index 0c9fe0315..4d105e372 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -35,14 +35,15 @@ import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox'; import { DocumentType } from './DocumentTypes'; import { Docs, DocumentOptions } from './Documents'; +// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports const { DFLT_IMAGE_NATIVE_DIM } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', '')); export namespace DocUtils { - function matchFieldValue(doc: Doc, key: string, valueIn: any): boolean { + function matchFieldValue(doc: Doc, key: string, valueIn: unknown): boolean { let value = valueIn; - const hasFunctionFilter = ClientUtils.HasFunctionFilter(value); + const hasFunctionFilter = ClientUtils.HasFunctionFilter(value as string); if (hasFunctionFilter) { return hasFunctionFilter(StrCast(doc[key])); } @@ -57,8 +58,8 @@ export namespace DocUtils { // prettier-ignore return (value === Doc.FilterNone && !allLinks.length) || (value === Doc.FilterAny && !!allLinks.length) || - (allLinks.some(link => matchLink(value,DocCast(link.link_anchor_1)) || - matchLink(value,DocCast(link.link_anchor_2)) )); + (allLinks.some(link => matchLink(value as string, DocCast(link.link_anchor_1)) || + matchLink(value as string, DocCast(link.link_anchor_2)) )); } if (typeof value === 'string') { value = value.replace(`,${ClientUtils.noRecursionHack}`, ''); @@ -71,9 +72,9 @@ export namespace DocUtils { } const vals = StrListCast(fieldVal); // list typing is very imperfect. casting to a string list doesn't mean that the entries will actually be strings if (vals.length) { - return vals.some(v => typeof v === 'string' && v.includes(value)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring + return vals.some(v => typeof v === 'string' && v.includes(value as string)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring } - return Field.toString(fieldVal as FieldType).includes(value); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring + return Field.toString(fieldVal as FieldType).includes(value as string); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring } /** * @param docs @@ -215,13 +216,13 @@ export namespace DocUtils { { acl_Guest: SharingPermissions.Augment, _acl_Guest: SharingPermissions.Augment, - title: ComputedField.MakeFunction('generateLinkTitle(this)') as any, + title: ComputedField.MakeFunction('generateLinkTitle(this)') as unknown as string, // title can accept functions even though type says it can't link_anchor_1_useSmallAnchor: source.useSmallAnchor ? true : undefined, link_anchor_2_useSmallAnchor: target.useSmallAnchor ? true : undefined, link_relationship: linkSettings.link_relationship, link_description: linkSettings.link_description, - x: ComputedField.MakeFunction(`((this.${a}?.x||0)+(this.${b}?.x||0))/2`) as any, - y: ComputedField.MakeFunction(`((this.${a}?.y||0)+(this.${b}?.y||0))/2`) as any, + x: ComputedField.MakeFunction(`((this.${a}?.x||0)+(this.${b}?.x||0))/2`) as unknown as number, // x can accept functions even though type says it can't + y: ComputedField.MakeFunction(`((this.${a}?.y||0)+(this.${b}?.y||0))/2`) as unknown as number, // y can accept functions even though type says it can't link_autoMoveAnchors: true, _lockedPosition: true, _layout_showCaption: '', // removed since they conflict with showing a link with a LinkBox (ie, line, not comparison box) @@ -235,12 +236,15 @@ export namespace DocUtils { ); } - export function AssignScripts(doc: Doc, scripts?: { [key: string]: string | undefined }, funcs?: { [key: string]: string }) { + export function AssignScripts(doc: Doc, scripts?: { [key: string]: string | undefined }, funcs?: { [key: string]: string | undefined }) { scripts && Object.keys(scripts).forEach(key => { - const script = scripts[key]; + const script = scripts[key] as string; if (ScriptCast(doc[key])?.script.originalScript !== scripts[key] && script) { + const additionalItems: { [key: string]: unknown } = {}; + script.match(/_[a-zA-Z]*_/)?.forEach(match => (additionalItems[match] = 'any')); (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = ScriptField.MakeScript(script, { + ...additionalItems, this: Doc.name, dragData: Doc.DocDragDataName, value: 'any', @@ -261,16 +265,17 @@ export namespace DocUtils { .filter(key => !key.endsWith('-setter')) .forEach(key => { const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); - if (ScriptCast(cfield)?.script.originalScript !== funcs[key]) { + const func = funcs[key]; + if (ScriptCast(cfield)?.script.originalScript !== func) { const setFunc = Cast(funcs[key + '-setter'], 'string', null); - (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = funcs[key] ? ComputedField.MakeFunction(funcs[key], { dragData: Doc.DocDragDataName }, { _readOnly_: true }, setFunc) : undefined; + (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = func ? ComputedField.MakeFunction(func, { dragData: Doc.DocDragDataName }, { _readOnly_: true }, setFunc) : undefined; } }); return doc; } export function AssignOpts(doc: Doc | undefined, reqdOpts: DocumentOptions, items?: Doc[]) { if (doc) { - const compareValues = (val1: any, val2: any) => { + const compareValues = (val1: unknown, val2: unknown) => { if (val1 instanceof List && val2 instanceof List && val1.length === val2.length) { return !val1.some(v => !val2.includes(v)) || !val2.some(v => val1.includes(v)); } @@ -334,7 +339,7 @@ export namespace DocUtils { if (path.includes(window.location.hostname)) { const s = path.split('/'); const id = s[s.length - 1]; - return DocServer.GetRefField(id).then(field => { + return DocServer.GetRefField(id)?.then(field => { if (field instanceof Doc) { const embedding = Doc.MakeEmbedding(field); embedding.x = (options.x as number) || 0; @@ -354,7 +359,7 @@ export namespace DocUtils { return ctor ? ctor(path, overwriteDoc ? { ...options, title: StrCast(overwriteDoc.title, path) } : options, overwriteDoc) : undefined; } - export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false, pivotField?: string, pivotValue?: string): void { + export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false, pivotField?: string, pivotValue?: string | number | boolean): void { const documentList: ContextMenuProps[] = DocListCast(DocListCast(Doc.MyTools?.data)[0]?.data) .filter(btnDoc => !btnDoc.hidden) .map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)) @@ -451,7 +456,7 @@ export namespace DocUtils { batch.end(); return doc; } - export function findTemplate(templateName: string, type: string) { + export function findTemplate(templateName: string, doc: Doc) { let docLayoutTemplate: Opt<Doc>; const iconViews = DocListCast(Cast(Doc.UserDoc().template_icons, Doc, null)?.data); const templBtns = DocListCast(Cast(Doc.UserDoc().template_buttons, Doc, null)?.data); @@ -464,12 +469,13 @@ export namespace DocUtils { .concat(userTypes) .concat(clickFuncs) .map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc) - .filter(doc => doc.isTemplateDoc); + .filter(d => d.isTemplateDoc); // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document. but type is not reliable and there could be other types of template searches so this should be generalized // first try to find a template that matches the specific document type (<typeName>_<templateName>). otherwise, fallback to a general match on <templateName> !docLayoutTemplate && allTemplates.forEach(tempDoc => { - StrCast(tempDoc.title) === templateName + '_' + type && (docLayoutTemplate = tempDoc); + const templateType = StrCast(doc[templateName + '_fieldKey'] || doc.type); + StrCast(tempDoc.title) === templateName + '_' + templateType && (docLayoutTemplate = tempDoc); }); !docLayoutTemplate && allTemplates.forEach(tempDoc => { @@ -481,7 +487,7 @@ export namespace DocUtils { const templateName = templateSignature.replace(/\(.*\)/, ''); doc.layout_fieldKey = 'layout_' + (templateSignature || (docLayoutTemplate?.title ?? '')); // eslint-disable-next-line no-param-reassign - docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, StrCast(doc.isGroup && doc.transcription ? 'transcription' : doc.type)); + docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, doc); const customName = 'layout_' + templateSignature; const _width = NumCast(doc._width); @@ -619,7 +625,7 @@ export namespace DocUtils { const proto = protoIn; if (Upload.isImageInformation(result)) { const maxNativeDim = Math.min(Math.max(result.nativeHeight, result.nativeWidth), defaultNativeImageDim); - const exifRotation = StrCast((result.exifData?.data as any)?.Orientation).toLowerCase(); + const exifRotation = StrCast(result.exifData?.data?.Orientation).toLowerCase(); proto.data_nativeOrientation = result.exifData?.data?.image?.Orientation ?? (exifRotation.includes('rotate 90') || exifRotation.includes('rotate 270') ? 5 : undefined); proto.data_nativeWidth = result.nativeWidth < result.nativeHeight ? (maxNativeDim * result.nativeWidth) / result.nativeHeight : maxNativeDim; proto.data_nativeHeight = result.nativeWidth < result.nativeHeight ? maxNativeDim : maxNativeDim / (result.nativeWidth / result.nativeHeight); @@ -697,10 +703,10 @@ export namespace DocUtils { source: { newFilename, mimetype }, result, } = upfiles.lastElement(); - if ((result as any).message) { + if (result instanceof Error) { if (overwriteDoc) { overwriteDoc.isLoading = false; - overwriteDoc.loadingError = (result as any).message; + overwriteDoc.loadingError = result.message; Doc.removeCurrentlyLoading(overwriteDoc); } } else newFilename && processFileupload(generatedDocuments, newFilename, mimetype ?? '', result, options, overwriteDoc); @@ -735,10 +741,10 @@ export namespace DocUtils { const { source: { newFilename, mimetype }, result, - } = upfiles.lastElement() ?? { source: { newFilename: '', mimetype: '' }, result: { message: 'upload failed' } }; - if ((result as any).message) { + } = upfiles.lastElement() ?? { source: { newFilename: '', mimetype: '' }, result: new Error('upload failed') }; + if (result instanceof Error) { if (overwriteDoc) { - overwriteDoc.loadingError = (result as any).message; + overwriteDoc.loadingError = result.message; Doc.removeCurrentlyLoading(overwriteDoc); } } else newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options, overwriteDoc); @@ -768,7 +774,7 @@ export namespace DocUtils { export async function Zip(doc: Doc, zipFilename = 'dashExport.zip') { const { clone, map, linkMap } = await Doc.MakeClone(doc); const proms = new Set<string>(); - function replacer(key: any, value: any) { + function replacer(key: string, value: { url: string; [key: string]: unknown }) { if (key && ['branchOf', 'cloneOf', 'cursors'].includes(key)) return undefined; if (value?.__type === 'image') { const extension = value.url.replace(/.*\./, ''); @@ -804,8 +810,8 @@ export namespace DocUtils { return value; } - const docs: { [id: string]: any } = {}; - const links: { [id: string]: any } = {}; + const docs: { [id: string]: unknown } = {}; + const links: { [id: string]: unknown } = {}; Array.from(map.entries()).forEach(f => { docs[f[0]] = f[1]; }); @@ -826,13 +832,13 @@ export namespace DocUtils { } else promArr.forEach((url, i) => { // loading a file and add it in a zip file - JSZipUtils.getBinaryContent(window.location.origin + '/' + url, (err: any, data: any) => { + JSZipUtils.getBinaryContent(window.location.origin + '/' + url, (err: unknown, data: unknown) => { if (err) throw err; // or handle the error // // Generate a directory within the Zip file structure // const assets = zip.folder("assets"); // assets.file(filename, data, {binary: true}); const assetPathOnServer = promArr[i].replace(window.location.origin + '/', '').replace(/\//g, '%%%'); - zip.file(assetPathOnServer, data, { binary: true }); + zip.file(assetPathOnServer, data as string, { binary: true }); console.log(' => ' + url); if (++count === promArr.length) { zip.file('docs.json', jsonDocs); @@ -862,7 +868,7 @@ ScriptingGlobals.add(function copyDragFactory(dragFactory: Doc, asDelegate?: boo return dragFactory instanceof Doc ? (asDelegate ? DocUtils.delegateDragFactory(dragFactory) : DocUtils.copyDragFactory(dragFactory)) : dragFactory; }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function makeDelegate(proto: any) { +ScriptingGlobals.add(function makeDelegate(proto: Doc) { const d = Docs.Create.DelegateDocument(proto, { title: 'child of ' + proto.title }); return d; }); diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 8f95068db..56d505681 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -16,6 +16,9 @@ export enum DocumentType { SCREENSHOT = 'screenshot', FONTICON = 'fonticonbox', SEARCH = 'search', // search query + IMAGEGROUPER = 'imagegrouper', + FACECOLLECTION = 'facecollection', + UFACE = 'uniqueface', // unique face collection doc LABEL = 'label', // simple text label BUTTON = 'button', // onClick button WEBCAM = 'webcam', // webcam @@ -31,13 +34,11 @@ export enum DocumentType { // special purpose wrappers that either take no data or are compositions of lower level types LINK = 'link', - IMPORT = 'import', PRES = 'presentation', PRESELEMENT = 'preselement', COMPARISON = 'comparison', PUSHPIN = 'pushpin', MAPROUTE = 'maproute', - CALENDAR = 'calendar', SCRIPTDB = 'scriptdb', // database of scripts GROUPDB = 'groupdb', // database of groups diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 2d96796a2..f6dc8d800 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -38,6 +38,7 @@ export enum FInfoFieldType { date = 'date', list = 'list', rtf = 'rich text', + map = 'map', } export class FInfo { description: string = ''; @@ -142,12 +143,12 @@ class RtfInfo extends FInfo { } class ListInfo extends FInfo { fieldType? = FInfoFieldType.list; - values?: List<any>[] = []; + values?: List<FieldType>[] = []; } type BOOLt = BoolInfo | boolean; type NUMt = NumInfo | number; type STRt = StrInfo | string; -type LISTt = ListInfo | List<any>; +type LISTt = ListInfo | List<FieldType>; type DOCt = DocInfo | Doc; type RTFt = RtfInfo | RichTextField; type DIMt = DimInfo; // | typeof DimUnit.Pixel | typeof DimUnit.Ratio; @@ -270,8 +271,10 @@ export class DocumentOptions { _layout_nativeDimEditable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers', false); _layout_reflowVertical?: BOOLt = new BoolInfo('permit vertical resizing with content "reflow"'); _layout_reflowHorizontal?: BOOLt = new BoolInfo('permit horizontal resizing with content reflow'); + _layout_noSidebar?: BOOLt = new BoolInfo('whether to display the sidebar toggle button'); layout_boxShadow?: string; // box-shadow css string OR "standard" to use dash standard box shadow layout_maxShown?: NUMt = new NumInfo('maximum number of children to display at one time (see multicolumnview)'); + _layout_dontCenter?: STRt = new StrInfo("whether collections will center their content - values of 'x', 'xy', or 'y'"); _layout_autoHeight?: BOOLt = new BoolInfo('whether document automatically resizes vertically to display contents'); _layout_autoHeightMargins?: NUMt = new NumInfo('Margin heights to be added to the computed auto height of a Doc'); _layout_curPage?: NUMt = new NumInfo('current page of a PDF or other? paginated document', false); @@ -284,6 +287,7 @@ export class DocumentOptions { _layout_showTitle?: string; // field name to display in header (:hover is an optional suffix) _layout_showSidebar?: BOOLt = new BoolInfo('whether an annotationsidebar should be displayed for text docuemnts'); _layout_showCaption?: string; // which field to display in the caption area. leave empty to have no caption + _layout_showTags?: BOOLt = new BoolInfo('whether to show the list of document tags at the bottom of a DocView'); _chromeHidden?: BOOLt = new BoolInfo('whether the editing chrome for a document is hidden'); hideClickBehaviors?: BOOLt = new BoolInfo('whether to hide click behaviors in context menu'); @@ -329,11 +333,11 @@ export class DocumentOptions { contextMenuLabels?: List<string>; contextMenuIcons?: List<string>; childContentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents - childFilters_boolean?: string; + childFilters_boolean?: STRt = new StrInfo('boolean operator to apply to filters on different metadata fields. Value should be AND or OR. Default is AND'); childFilters?: List<string>; childLimitHeight?: NUMt = new NumInfo('whether to limit the height of collection children. 0 - means height can be no bigger than width', false); childLayoutTemplate?: Doc; // template for collection to use to render its children (see PresBox layout in tree view) - childLayoutString?: string; // template string for collection to use to render its children + childLayoutString?: STRt = new StrInfo('JSX layout string for rendering children of a (collection) Doc'); // template string for collection to use to render its children childDocumentsActive?: BOOLt = new BoolInfo('whether child documents are active when parent is document active'); childLayoutFitWidth?: BOOLt = new BoolInfo("whether a child doc's fitWith should be overriden by collection"); childDontRegisterViews?: BOOLt = new BoolInfo('whether child document views should be registered so that they can be found when following links, etc'); @@ -372,8 +376,11 @@ export class DocumentOptions { presentation_duration?: NUMt = new NumInfo('the duration of the slide in presentation view', false); presentation_zoomText?: BOOLt = new BoolInfo('whether text anchors should shown in a larger box when following links to make them stand out', false); - data?: any; + data?: FieldType; data_useCors?: BOOLt = new BoolInfo('whether CORS protocol should be used for web page'); + _face_showImages?: BOOLt = new BoolInfo('whether to show images in uniqe face Doc'); + face?: DOCt = new DocInfo('face document'); + faceDescriptor?: List<number>; columnHeaders?: List<SchemaHeaderField>; // headers for stacking views schemaHeaders?: List<SchemaHeaderField>; // headers for schema view dockingConfig?: STRt = new StrInfo('configuration of golden layout windows (applies only if doc is rendered as a CollectionDockingView)', false); @@ -459,6 +466,7 @@ export class DocumentOptions { onDragStart?: ScriptField; // script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop target?: Doc; // available for use in scripts. used to provide a document parameter to the script (Note, this is a convenience entry since any field could be used for parameterizing a script) tags?: LISTt = new ListInfo('hashtags added to document, typically using a text view', true); + tags_chat?: LISTt = new ListInfo('hashtags added to document by chatGPT', true); treeView_HideTitle?: BOOLt = new BoolInfo('whether to hide the top document title of a tree view'); treeView_HideUnrendered?: BOOLt = new BoolInfo("tells tree view not to display documents that have an 'layout_unrendered' tag unless they also have a treeView_FieldKey tag (presBox)"); treeView_HideHeaderIfTemplate?: BOOLt = new BoolInfo('whether to hide the header for a document in a tree view only if a childLayoutTemplate is provided (presBox)'); @@ -478,13 +486,14 @@ export class DocumentOptions { sidebar_color?: string; // background color of text sidebar sidebar_type_collection?: string; // collection type of text sidebar - data_dashboards?: List<any>; // list of dashboards used in shareddocs; + data_dashboards?: List<FieldType>; // list of dashboards used in shareddocs; textTransform?: string; letterSpacing?: string; iconTemplate?: string; // name of icon template style + icon_fieldKey?: string; // specifies the icon template to use (e.g., icon_fieldKey='george', then the icon template's name is icon_george; otherwise, the template's name would be icon_<type> where type is the Doc's type(pdf,rich text, etc)) selectedIndex?: NUMt = new NumInfo("which item in a linear view has been selected using the 'thumb doc' ui"); - fieldValues?: List<any>; // possible values a field can have (used by FieldInfo's only) + fieldValues?: List<FieldType>; // possible values a field can have (used by FieldInfo's only) fieldType?: string; // display type of a field, e.g. string, number, enumeration (used by FieldInfo's only) clipboard?: Doc; @@ -493,11 +502,11 @@ export class DocumentOptions { userColor?: STRt = new StrInfo('color associated with a Dash user (seen in header fields of shared documents)'); cardSort?: STRt = new StrInfo('way cards are sorted in deck view'); - cardSort_customField?: STRt = new StrInfo('field key used for sorting cards'); - cardSort_visibleSortGroups?: List<number>; // which sorting values are being filtered (shown) + cardSort_isDesc?: BOOLt = new BoolInfo('whether the cards are sorted ascending or descending'); } export const DocOptions = new DocumentOptions(); + export namespace Docs { export namespace Prototypes { type LayoutSource = { LayoutString: (key: string) => string }; @@ -506,7 +515,6 @@ export namespace Docs { view: LayoutSource; dataField: string; }; - data?: any; options?: Partial<DocumentOptions>; }; type TemplateMap = Map<DocumentType, PrototypeTemplate>; @@ -568,7 +576,7 @@ export namespace Docs { const actualProtos = await DocServer.GetRefFields(prototypeIds); // update this object to include any default values: DocumentOptions for all prototypes prototypeIds.forEach(id => { - const existing = actualProtos[id] as Doc; + const existing = actualProtos.get(id); const type = id.replace(suffix, '') as DocumentType; // get or create prototype of the specified type... const target = buildPrototype(type, id, existing); @@ -641,16 +649,15 @@ export namespace Docs { acl_Guest: SharingPermissions.View, ...(template.options || {}), layout: layout.view?.LayoutString(layout.dataField), - data: template.data, }; Object.entries(options) .filter(pair => typeof pair[1] === 'string' && pair[1].startsWith('@')) .forEach(pair => { if (!existing || ScriptCast(existing[pair[0]])?.script.originalScript !== pair[1].substring(1)) { - (options as any)[pair[0]] = ComputedField.MakeFunction(pair[1].substring(1)); + (options as { [key: string]: unknown })[pair[0]] = ComputedField.MakeFunction(pair[1].substring(1)); } }); - return Doc.assign(existing ?? new Doc(prototypeId, true), OmitKeys(options, Object.keys(existing ?? {})).omit, undefined, true); + return Doc.assign(existing ?? new Doc(prototypeId, true), OmitKeys(options, Object.keys(existing ?? {})).omit as { [key: string]: FieldType }, undefined, true); } } @@ -658,6 +665,7 @@ export namespace Docs { * Encapsulates the factory used to create new document instances * delegated from top-level prototypes */ + export namespace Create { /** * This function receives the relevant document prototype and uses @@ -681,10 +689,10 @@ export namespace Docs { function InstanceFromProto(proto: Doc, data: FieldType | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = 'data', protoId?: string, placeholderDocIn?: Doc, noView?: boolean) { const placeholderDoc = placeholderDocIn; const viewKeys = ['x', 'y', 'isSystem']; // keys that should be addded to the view document even though they don't begin with an "_" - const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, '^_'); + const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, '^_') as { omit: { [key: string]: FieldType | undefined }; extract: { [key: string]: FieldType | undefined } }; // dataProps.acl_Override = SharingPermissions.Unset; - dataProps.acl_Guest = options.acl_Guest ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View); + dataProps.acl_Guest = options.acl_Guest?.toString() ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View); dataProps.isSystem = viewProps.isSystem; dataProps.isDataDoc = true; dataProps.author = ClientUtils.CurrentUserEmail(); @@ -707,7 +715,7 @@ export namespace Docs { } if (!noView) { - const viewFirstProps: { [id: string]: any } = { author: ClientUtils.CurrentUserEmail() }; + const viewFirstProps: { [id: string]: FieldType } = { author: ClientUtils.CurrentUserEmail() }; viewFirstProps.acl_Guest = options._acl_Guest ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View); let viewDoc: Doc; // determines whether viewDoc should be created using placeholder Doc or default @@ -724,7 +732,7 @@ export namespace Docs { viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewFirstProps, true, true); } Doc.assign(viewDoc, viewProps, true, true); - if (![DocumentType.LINK, DocumentType.CONFIG, DocumentType.LABEL].includes(viewDoc.type as any)) { + if (![DocumentType.LINK, DocumentType.CONFIG, DocumentType.LABEL].includes(viewDoc.type as DocumentType)) { CreateLinkToActiveAudio(() => viewDoc); } updateCachedAcls(dataDoc); @@ -798,6 +806,18 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.SEARCH), new List<Doc>([]), options); } + export function ImageGrouperDocument(options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.IMAGEGROUPER), undefined, options); + } + + export function FaceCollectionDocument(options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.FACECOLLECTION), undefined, options); + } + + export function UniqeFaceDocument(options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.UFACE), undefined, options); + } + export function LoadingDocument(file: File | string, options: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.LOADING), undefined, { _height: 150, _width: 200, title: typeof file === 'string' ? file : file.name, ...options }, undefined, ''); } @@ -908,7 +928,15 @@ export namespace Docs { } export function CalendarDocument(options: DocumentOptions, documents: Array<Doc>) { - return InstanceFromProto(Prototypes.get(DocumentType.CALENDAR), new List(documents), { ...options }); + const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { + _layout_nativeDimEditable: true, + _layout_reflowHorizontal: true, + _layout_reflowVertical: true, + ...options, + _type_collection: CollectionViewType.Calendar, + }); + documents.forEach(d => Doc.SetContainer(d, inst)); + return inst; } // shouldn't ever need to create a KVP document-- instead set the LayoutTemplateString to be a KeyValueBox for the DocumentView (see addDocTab in TabDocView) @@ -923,7 +951,7 @@ export namespace Docs { } export function ConfigDocument(options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id, '', undefined, undefined, true); + return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), undefined, options, id, '', undefined, undefined, true); } export function PileDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) { @@ -965,12 +993,8 @@ export namespace Docs { return doc; } - export function CalendarCollectionDocument(documents: Array<Doc>, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Calendar }); - } - export function StackingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Stacking }, id, undefined, protoId); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _layout_dontCenter: 'y', ...options, _type_collection: CollectionViewType.Stacking }, id, undefined, protoId); } export function NoteTakingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) { |
