import { Doc, DocListCast } from '../../fields/Doc'; import { List } from '../../fields/List'; import { StrCast } from '../../fields/Types'; import { AudioField, ImageField, PdfField, VideoField } from '../../fields/URLField'; import { Docs, DocumentOptions } from './Documents'; /** * Changes the field key in the doc's layout string to be the specified field */ export function ResetLayoutFieldKey(doc: Doc, fieldKey: string) { doc.layout = StrCast(doc.layout).replace(/={'.*'}/, `={'${fieldKey}'}`); return doc; } /** * Creates a new document based on the type of (and containing the) data in the specified field of an existing document. * If the field contains a list, then it may be useful to specify a classProto to indicate the type of * collection Doc that gets created. * @param target document to retrive field from * @param fieldKey field key to retrieve * @param classProto optionally a class proto to set on the new document * @param options metadata configuration for new document * @returns */ export function DocumentFromField(target: Doc, fieldKey: string, classProto?: Doc, options?: DocumentOptions): Doc | undefined { const field = target[fieldKey]; const resolved = options ?? {}; const nonDocFieldToDoc = () => { if (field instanceof ImageField) return Docs.Create.ImageDocument(field.url.href, resolved); if (field instanceof VideoField) return Docs.Create.VideoDocument(field.url.href, resolved); if (field instanceof PdfField) return Docs.Create.PdfDocument(field.url.href, resolved); if (field instanceof AudioField) return Docs.Create.AudioDocument(field.url.href, resolved); if (field instanceof List && field[0] instanceof Doc) return Docs.Create.StackingDocument(DocListCast(field), resolved); return Docs.Create.TextDocument('', { ...{ _width: 200, _height: 25, _layout_autoHeight: true }, ...resolved }); }; const created = field instanceof Doc ? field : ResetLayoutFieldKey(nonDocFieldToDoc(), fieldKey); created.title = fieldKey; classProto && created.proto && (created.proto = classProto); return created; }