diff options
author | Sophie Zhang <sophie_zhang@brown.edu> | 2024-01-25 11:35:26 -0500 |
---|---|---|
committer | Sophie Zhang <sophie_zhang@brown.edu> | 2024-01-25 11:35:26 -0500 |
commit | f3dab2a56db5e4a6a3dca58185d94e1ff7d1dc32 (patch) | |
tree | a7bc895266b53bb620dbd2dd71bad2e83b555446 /src/client/util/Import & Export/DirectoryImportBox.tsx | |
parent | b5c5410b4af5d2c68d2107d3f064f6e3ec4ac3f2 (diff) | |
parent | 136f3d9f349d54e8bdd73b6380ea47c19e5edebf (diff) |
Merge branch 'master' into sophie-ai-images
Diffstat (limited to 'src/client/util/Import & Export/DirectoryImportBox.tsx')
-rw-r--r-- | src/client/util/Import & Export/DirectoryImportBox.tsx | 819 |
1 files changed, 409 insertions, 410 deletions
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index 1a4c2450e..398ba3c04 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -1,440 +1,439 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { BatchedArray } from 'array-batcher'; -import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; -import { observer } from 'mobx-react'; -import { extname } from 'path'; -import Measure, { ContentRect } from 'react-measure'; -import { Doc, DocListCast, DocListCastAsync, Opt } from '../../../fields/Doc'; -import { Id } from '../../../fields/FieldSymbols'; -import { List } from '../../../fields/List'; -import { listSpec } from '../../../fields/Schema'; -import { SchemaHeaderField } from '../../../fields/SchemaHeaderField'; -import { BoolCast, Cast, NumCast } from '../../../fields/Types'; -import { AcceptableMedia, Upload } from '../../../server/SharedMediaTypes'; -import { Utils } from '../../../Utils'; -import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; -import { Docs, DocumentOptions, DocUtils } from '../../documents/Documents'; -import { DocumentType } from '../../documents/DocumentTypes'; -import { Networking } from '../../Network'; -import { FieldView, FieldViewProps } from '../../views/nodes/FieldView'; -import { DocumentManager } from '../DocumentManager'; -import './DirectoryImportBox.scss'; -import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from './ImportMetadataEntry'; -import React = require('react'); -import _ = require('lodash'); +// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +// import { BatchedArray } from 'array-batcher'; +// import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +// import { observer } from 'mobx-react'; +// import { extname } from 'path'; +// import Measure, { ContentRect } from 'react-measure'; +// import { Doc, DocListCast, DocListCastAsync, Opt } from '../../../fields/Doc'; +// import { Id } from '../../../fields/FieldSymbols'; +// import { List } from '../../../fields/List'; +// import { listSpec } from '../../../fields/Schema'; +// import { SchemaHeaderField } from '../../../fields/SchemaHeaderField'; +// import { BoolCast, Cast, NumCast } from '../../../fields/Types'; +// import { AcceptableMedia, Upload } from '../../../server/SharedMediaTypes'; +// import { Utils } from '../../../Utils'; +// import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; +// import { Docs, DocumentOptions, DocUtils } from '../../documents/Documents'; +// import { DocumentType } from '../../documents/DocumentTypes'; +// import { Networking } from '../../Network'; +// import { FieldView, FieldViewProps } from '../../views/nodes/FieldView'; +// import { DocumentManager } from '../DocumentManager'; +// import './DirectoryImportBox.scss'; +// import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from './ImportMetadataEntry'; +// import * as React from 'react'; -const unsupported = ['text/html', 'text/plain']; +// const unsupported = ['text/html', 'text/plain']; -@observer -export class DirectoryImportBox extends React.Component<FieldViewProps> { - private selector = React.createRef<HTMLInputElement>(); - @observable private top = 0; - @observable private left = 0; - private dimensions = 50; - @observable private phase = ''; - private disposer: Opt<IReactionDisposer>; +// @observer +// export class DirectoryImportBox extends React.Component<FieldViewProps> { +// private selector = React.createRef<HTMLInputElement>(); +// @observable private top = 0; +// @observable private left = 0; +// private dimensions = 50; +// @observable private phase = ''; +// private disposer: Opt<IReactionDisposer>; - @observable private entries: ImportMetadataEntry[] = []; +// @observable private entries: ImportMetadataEntry[] = []; - @observable private quota = 1; - @observable private completed = 0; +// @observable private quota = 1; +// @observable private completed = 0; - @observable private uploading = false; - @observable private removeHover = false; +// @observable private uploading = false; +// @observable private removeHover = false; - public static LayoutString(fieldKey: string) { - return FieldView.LayoutString(DirectoryImportBox, fieldKey); - } +// public static LayoutString(fieldKey: string) { +// return FieldView.LayoutString(DirectoryImportBox, fieldKey); +// } - constructor(props: FieldViewProps) { - super(props); - const doc = this.props.Document; - this.editingMetadata = this.editingMetadata || false; - this.persistent = this.persistent || false; - !Cast(doc.data, listSpec(Doc)) && (doc.data = new List<Doc>()); - } +// constructor(props: FieldViewProps) { +// super(props); +// const doc = this.props.Document; +// this.editingMetadata = this.editingMetadata || false; +// this.persistent = this.persistent || false; +// !Cast(doc.data, listSpec(Doc)) && (doc.data = new List<Doc>()); +// } - @computed - private get editingMetadata() { - return BoolCast(this.props.Document.editingMetadata); - } +// @computed +// private get editingMetadata() { +// return BoolCast(this.props.Document.editingMetadata); +// } - private set editingMetadata(value: boolean) { - this.props.Document.editingMetadata = value; - } +// private set editingMetadata(value: boolean) { +// this.props.Document.editingMetadata = value; +// } - @computed - private get persistent() { - return BoolCast(this.props.Document.persistent); - } +// @computed +// private get persistent() { +// return BoolCast(this.props.Document.persistent); +// } - private set persistent(value: boolean) { - this.props.Document.persistent = value; - } +// private set persistent(value: boolean) { +// this.props.Document.persistent = value; +// } - handleSelection = async (e: React.ChangeEvent<HTMLInputElement>) => { - runInAction(() => { - this.uploading = true; - this.phase = 'Initializing download...'; - }); +// handleSelection = async (e: React.ChangeEvent<HTMLInputElement>) => { +// runInAction(() => { +// this.uploading = true; +// this.phase = 'Initializing download...'; +// }); - const docs: Doc[] = []; +// const docs: Doc[] = []; - const files = e.target.files; - if (!files || files.length === 0) return; +// const files = e.target.files; +// if (!files || files.length === 0) return; - const directory = (files.item(0) as any).webkitRelativePath.split('/', 1)[0]; +// const directory = (files.item(0) as any).webkitRelativePath.split('/', 1)[0]; - const validated: File[] = []; - for (let i = 0; i < files.length; i++) { - const file = files.item(i); - if (file && !unsupported.includes(file.type)) { - const ext = extname(file.name).toLowerCase(); - if (AcceptableMedia.imageFormats.includes(ext)) { - validated.push(file); - } - } - } +// const validated: File[] = []; +// for (let i = 0; i < files.length; i++) { +// const file = files.item(i); +// if (file && !unsupported.includes(file.type)) { +// const ext = extname(file.name).toLowerCase(); +// if (AcceptableMedia.imageFormats.includes(ext)) { +// validated.push(file); +// } +// } +// } - runInAction(() => { - this.quota = validated.length; - this.completed = 0; - }); +// runInAction(() => { +// this.quota = validated.length; +// this.completed = 0; +// }); - const sizes: number[] = []; - const modifiedDates: number[] = []; +// const sizes: number[] = []; +// const modifiedDates: number[] = []; - runInAction(() => (this.phase = `Internal: uploading ${this.quota - this.completed} files to Dash...`)); +// runInAction(() => (this.phase = `Internal: uploading ${this.quota - this.completed} files to Dash...`)); - const batched = BatchedArray.from(validated, { batchSize: 15 }); - const uploads = await batched.batchedMapAsync<Upload.FileResponse<Upload.ImageInformation>>(async (batch, collector) => { - batch.forEach(file => { - sizes.push(file.size); - modifiedDates.push(file.lastModified); - }); - collector.push(...(await Networking.UploadFilesToServer<Upload.ImageInformation>(batch.map(file =>({file}))))); - runInAction(() => (this.completed += batch.length)); - }); +// const batched = BatchedArray.from(validated, { batchSize: 15 }); +// const uploads = await batched.batchedMapAsync<Upload.FileResponse<Upload.ImageInformation>>(async (batch, collector) => { +// batch.forEach(file => { +// sizes.push(file.size); +// modifiedDates.push(file.lastModified); +// }); +// collector.push(...(await Networking.UploadFilesToServer<Upload.ImageInformation>(batch.map(file => ({ file }))))); +// runInAction(() => (this.completed += batch.length)); +// }); - await Promise.all( - uploads.map(async response => { - const { - source: { type }, - result, - } = response; - if (result instanceof Error) { - return; - } - const { accessPaths, exifData } = result; - const path = Utils.prepend(accessPaths.agnostic.client); - const document = type && (await DocUtils.DocumentFromType(type, path, { _width: 300 })); - const { data, error } = exifData; - if (document) { - Doc.GetProto(document).exif = error || Doc.Get.FromJson({ data }); - docs.push(document); - } - }) - ); +// await Promise.all( +// uploads.map(async response => { +// const { +// source: { mimetype }, +// result, +// } = response; +// if (result instanceof Error) { +// return; +// } +// const { accessPaths, exifData } = result; +// const path = Utils.prepend(accessPaths.agnostic.client); +// const document = mimetype && (await DocUtils.DocumentFromType(mimetype, path, { _width: 300 })); +// const { data, error } = exifData; +// if (document) { +// Doc.GetProto(document).exif = error || Doc.Get.FromJson({ data }); +// docs.push(document); +// } +// }) +// ); - for (let i = 0; i < docs.length; i++) { - const doc = docs[i]; - doc.size = sizes[i]; - doc.modified = modifiedDates[i]; - this.entries.forEach(entry => { - const target = entry.onDataDoc ? Doc.GetProto(doc) : doc; - target[entry.key] = entry.value; - }); - } +// for (let i = 0; i < docs.length; i++) { +// const doc = docs[i]; +// doc.size = sizes[i]; +// doc.modified = modifiedDates[i]; +// this.entries.forEach(entry => { +// const target = entry.onDataDoc ? Doc.GetProto(doc) : doc; +// target[entry.key] = entry.value; +// }); +// } - const doc = this.props.Document; - const height: number = NumCast(doc.height) || 0; - const offset: number = this.persistent ? (height === 0 ? 0 : height + 30) : 0; - const options: DocumentOptions = { - title: `Import of ${directory}`, - _width: 1105, - _height: 500, - _chromeHidden: true, - x: NumCast(doc.x), - y: NumCast(doc.y) + offset, - }; - const parent = this.props.DocumentView?.().props.docViewPath().lastElement(); - if (parent?.rootDoc.type === DocumentType.COL) { - let importContainer: Doc; - if (docs.length < 50) { - importContainer = Docs.Create.MasonryDocument(docs, options); - } else { - const headers = [new SchemaHeaderField('title'), new SchemaHeaderField('size')]; - importContainer = Docs.Create.SchemaDocument(headers, docs, options); - } - runInAction(() => (this.phase = 'External: uploading files to Google Photos...')); - await GooglePhotos.Export.CollectionToAlbum({ collection: importContainer }); - Doc.AddDocToList(Doc.GetProto(parent.props.Document), 'data', importContainer); - !this.persistent && this.props.removeDocument && this.props.removeDocument(doc); - DocumentManager.Instance.showDocument(importContainer, { willZoomCentered: true }); - } +// const doc = this.props.Document; +// const height: number = NumCast(doc.height) || 0; +// const offset: number = this.persistent ? (height === 0 ? 0 : height + 30) : 0; +// const options: DocumentOptions = { +// title: `Import of ${directory}`, +// _width: 1105, +// _height: 500, +// _chromeHidden: true, +// x: NumCast(doc.x), +// y: NumCast(doc.y) + offset, +// }; +// const parent = this.props.DocumentView?.().containerViewPath().lastElement(); +// if (parent?.Document.type === DocumentType.COL) { +// let importContainer: Doc; +// if (docs.length < 50) { +// importContainer = Docs.Create.MasonryDocument(docs, options); +// } else { +// const headers = [new SchemaHeaderField('title'), new SchemaHeaderField('size')]; +// importContainer = Docs.Create.SchemaDocument(headers, docs, options); +// } +// runInAction(() => (this.phase = 'External: uploading files to Google Photos...')); +// await GooglePhotos.Export.CollectionToAlbum({ collection: importContainer }); +// Doc.AddDocToList(Doc.GetProto(parent.props.Document), 'data', importContainer); +// !this.persistent && this.props.removeDocument && this.props.removeDocument(doc); +// DocumentManager.Instance.showDocument(importContainer, { willZoomCentered: true }); +// } - runInAction(() => { - this.uploading = false; - this.quota = 1; - this.completed = 0; - }); - }; +// runInAction(() => { +// this.uploading = false; +// this.quota = 1; +// this.completed = 0; +// }); +// }; - componentDidMount() { - this.selector.current!.setAttribute('directory', ''); - this.selector.current!.setAttribute('webkitdirectory', ''); - this.disposer = reaction( - () => this.completed, - completed => runInAction(() => (this.phase = `Internal: uploading ${this.quota - completed} files to Dash...`)) - ); - } +// componentDidMount() { +// this.selector.current!.setAttribute('directory', ''); +// this.selector.current!.setAttribute('webkitdirectory', ''); +// this.disposer = reaction( +// () => this.completed, +// completed => runInAction(() => (this.phase = `Internal: uploading ${this.quota - completed} files to Dash...`)) +// ); +// } - componentWillUnmount() { - this.disposer && this.disposer(); - } +// componentWillUnmount() { +// this.disposer && this.disposer(); +// } - @action - preserveCentering = (rect: ContentRect) => { - const bounds = rect.offset!; - if (bounds.width === 0 || bounds.height === 0) { - return; - } - const offset = this.dimensions / 2; - this.left = bounds.width / 2 - offset; - this.top = bounds.height / 2 - offset; - }; +// @action +// preserveCentering = (rect: ContentRect) => { +// const bounds = rect.offset!; +// if (bounds.width === 0 || bounds.height === 0) { +// return; +// } +// const offset = this.dimensions / 2; +// this.left = bounds.width / 2 - offset; +// this.top = bounds.height / 2 - offset; +// }; - @action - addMetadataEntry = async () => { - const entryDoc = new Doc(); - entryDoc.checked = false; - entryDoc.key = keyPlaceholder; - entryDoc.value = valuePlaceholder; - Doc.AddDocToList(this.props.Document, 'data', entryDoc); - }; +// @action +// addMetadataEntry = async () => { +// const entryDoc = new Doc(); +// entryDoc.checked = false; +// entryDoc.key = keyPlaceholder; +// entryDoc.value = valuePlaceholder; +// Doc.AddDocToList(this.props.Document, 'data', entryDoc); +// }; - @action - remove = async (entry: ImportMetadataEntry) => { - const metadata = await DocListCastAsync(this.props.Document.data); - if (metadata) { - let index = this.entries.indexOf(entry); - if (index !== -1) { - runInAction(() => this.entries.splice(index, 1)); - index = metadata.indexOf(entry.props.Document); - if (index !== -1) { - metadata.splice(index, 1); - } - } - } - }; +// @action +// remove = async (entry: ImportMetadataEntry) => { +// const metadata = await DocListCastAsync(this.props.Document.data); +// if (metadata) { +// let index = this.entries.indexOf(entry); +// if (index !== -1) { +// runInAction(() => this.entries.splice(index, 1)); +// index = metadata.indexOf(entry.props.Document); +// if (index !== -1) { +// metadata.splice(index, 1); +// } +// } +// } +// }; - render() { - const dimensions = 50; - const entries = DocListCast(this.props.Document.data); - const isEditing = this.editingMetadata; - const completed = this.completed; - const quota = this.quota; - const uploading = this.uploading; - const showRemoveLabel = this.removeHover; - const persistent = this.persistent; - let percent = `${(completed / quota) * 100}`; - percent = percent.split('.')[0]; - percent = percent.startsWith('100') ? '99' : percent; - const marginOffset = (percent.length === 1 ? 5 : 0) - 1.6; - const message = <span className={'phase'}>{this.phase}</span>; - const centerPiece = this.phase.includes('Google Photos') ? ( - <img - src={'/assets/google_photos.png'} - style={{ - transition: '0.4s opacity ease', - width: 30, - height: 30, - opacity: uploading ? 1 : 0, - pointerEvents: 'none', - position: 'absolute', - left: 12, - top: this.top + 10, - fontSize: 18, - color: 'white', - marginLeft: this.left + marginOffset, - }} - /> - ) : ( - <div - style={{ - transition: '0.4s opacity ease', - opacity: uploading ? 1 : 0, - pointerEvents: 'none', - position: 'absolute', - left: 10, - top: this.top + 12.3, - fontSize: 18, - color: 'white', - marginLeft: this.left + marginOffset, - }}> - {percent}% - </div> - ); - return ( - <Measure offset onResize={this.preserveCentering}> - {({ measureRef }) => ( - <div ref={measureRef} style={{ width: '100%', height: '100%', pointerEvents: 'all' }}> - {message} - <input - id={'selector'} - ref={this.selector} - onChange={this.handleSelection} - type="file" - style={{ - position: 'absolute', - display: 'none', - }} - /> - <label - htmlFor={'selector'} - style={{ - opacity: isEditing ? 0 : 1, - pointerEvents: isEditing ? 'none' : 'all', - transition: '0.4s ease opacity', - }}> - <div - style={{ - width: dimensions, - height: dimensions, - borderRadius: '50%', - background: 'black', - position: 'absolute', - left: this.left, - top: this.top, - }} - /> - <div - style={{ - position: 'absolute', - left: this.left + 8, - top: this.top + 10, - opacity: uploading ? 0 : 1, - transition: '0.4s opacity ease', - }}> - <FontAwesomeIcon icon={'cloud-upload-alt'} color="#FFFFFF" size={'2x'} /> - </div> - <img - style={{ - width: 80, - height: 80, - transition: '0.4s opacity ease', - opacity: uploading ? 0.7 : 0, - position: 'absolute', - top: this.top - 15, - left: this.left - 15, - }} - src={'/assets/loading.gif'}></img> - </label> - <input - type={'checkbox'} - onChange={e => runInAction(() => (this.persistent = e.target.checked))} - style={{ - margin: 0, - position: 'absolute', - left: 10, - bottom: 10, - opacity: isEditing || uploading ? 0 : 1, - transition: '0.4s opacity ease', - pointerEvents: isEditing || uploading ? 'none' : 'all', - }} - checked={this.persistent} - onPointerEnter={action(() => (this.removeHover = true))} - onPointerLeave={action(() => (this.removeHover = false))} - /> - <p - style={{ - position: 'absolute', - left: 27, - bottom: 8.4, - fontSize: 12, - opacity: showRemoveLabel ? 1 : 0, - transition: '0.4s opacity ease', - }}> - Template will be <span style={{ textDecoration: 'underline', textDecorationColor: persistent ? 'green' : 'red', color: persistent ? 'green' : 'red' }}>{persistent ? 'kept' : 'removed'}</span> after upload - </p> - {centerPiece} - <div - style={{ - position: 'absolute', - top: 10, - right: 10, - borderRadius: '50%', - width: 25, - height: 25, - background: 'black', - pointerEvents: uploading ? 'none' : 'all', - opacity: uploading ? 0 : 1, - transition: '0.4s opacity ease', - }} - title={isEditing ? 'Back to Upload' : 'Add Metadata'} - onClick={action(() => (this.editingMetadata = !this.editingMetadata))} - /> - <FontAwesomeIcon - style={{ - pointerEvents: 'none', - position: 'absolute', - right: isEditing ? 14 : 15, - top: isEditing ? 15.4 : 16, - opacity: uploading ? 0 : 1, - transition: '0.4s opacity ease', - }} - icon={isEditing ? 'cloud-upload-alt' : 'tag'} - color="#FFFFFF" - size={'1x'} - /> - <div - style={{ - transition: '0.4s ease opacity', - width: '100%', - height: '100%', - pointerEvents: isEditing ? 'all' : 'none', - opacity: isEditing ? 1 : 0, - overflowY: 'scroll', - }}> - <div - style={{ - borderRadius: '50%', - width: 25, - height: 25, - marginLeft: 10, - position: 'absolute', - right: 41, - top: 10, - }} - title={'Add Metadata Entry'} - onClick={this.addMetadataEntry}> - <FontAwesomeIcon - style={{ - pointerEvents: 'none', - marginLeft: 6.4, - marginTop: 5.2, - }} - icon={'plus'} - size={'1x'} - /> - </div> - <p style={{ paddingLeft: 10, paddingTop: 8, paddingBottom: 7 }}>Add metadata to your import...</p> - <hr style={{ margin: '6px 10px 12px 10px' }} /> - {entries.map(doc => ( - <ImportMetadataEntry - Document={doc} - key={doc[Id]} - remove={this.remove} - ref={el => { - if (el) this.entries.push(el); - }} - next={this.addMetadataEntry} - /> - ))} - </div> - </div> - )} - </Measure> - ); - } -} +// render() { +// const dimensions = 50; +// const entries = DocListCast(this.props.Document.data); +// const isEditing = this.editingMetadata; +// const completed = this.completed; +// const quota = this.quota; +// const uploading = this.uploading; +// const showRemoveLabel = this.removeHover; +// const persistent = this.persistent; +// let percent = `${(completed / quota) * 100}`; +// percent = percent.split('.')[0]; +// percent = percent.startsWith('100') ? '99' : percent; +// const marginOffset = (percent.length === 1 ? 5 : 0) - 1.6; +// const message = <span className={'phase'}>{this.phase}</span>; +// const centerPiece = this.phase.includes('Google Photos') ? ( +// <img +// src={'/assets/google_photos.png'} +// style={{ +// transition: '0.4s opacity ease', +// width: 30, +// height: 30, +// opacity: uploading ? 1 : 0, +// pointerEvents: 'none', +// position: 'absolute', +// left: 12, +// top: this.top + 10, +// fontSize: 18, +// color: 'white', +// marginLeft: this.left + marginOffset, +// }} +// /> +// ) : ( +// <div +// style={{ +// transition: '0.4s opacity ease', +// opacity: uploading ? 1 : 0, +// pointerEvents: 'none', +// position: 'absolute', +// left: 10, +// top: this.top + 12.3, +// fontSize: 18, +// color: 'white', +// marginLeft: this.left + marginOffset, +// }}> +// {percent}% +// </div> +// ); +// return ( +// <Measure offset onResize={this.preserveCentering}> +// {({ measureRef }) => ( +// <div ref={measureRef} style={{ width: '100%', height: '100%', pointerEvents: 'all' }}> +// {message} +// <input +// id={'selector'} +// ref={this.selector} +// onChange={this.handleSelection} +// type="file" +// style={{ +// position: 'absolute', +// display: 'none', +// }} +// /> +// <label +// htmlFor={'selector'} +// style={{ +// opacity: isEditing ? 0 : 1, +// pointerEvents: isEditing ? 'none' : 'all', +// transition: '0.4s ease opacity', +// }}> +// <div +// style={{ +// width: dimensions, +// height: dimensions, +// borderRadius: '50%', +// background: 'black', +// position: 'absolute', +// left: this.left, +// top: this.top, +// }} +// /> +// <div +// style={{ +// position: 'absolute', +// left: this.left + 8, +// top: this.top + 10, +// opacity: uploading ? 0 : 1, +// transition: '0.4s opacity ease', +// }}> +// <FontAwesomeIcon icon={'cloud-upload-alt'} color="#FFFFFF" size={'2x'} /> +// </div> +// <img +// style={{ +// width: 80, +// height: 80, +// transition: '0.4s opacity ease', +// opacity: uploading ? 0.7 : 0, +// position: 'absolute', +// top: this.top - 15, +// left: this.left - 15, +// }} +// src={'/assets/loading.gif'}></img> +// </label> +// <input +// type={'checkbox'} +// onChange={e => runInAction(() => (this.persistent = e.target.checked))} +// style={{ +// margin: 0, +// position: 'absolute', +// left: 10, +// bottom: 10, +// opacity: isEditing || uploading ? 0 : 1, +// transition: '0.4s opacity ease', +// pointerEvents: isEditing || uploading ? 'none' : 'all', +// }} +// checked={this.persistent} +// onPointerEnter={action(() => (this.removeHover = true))} +// onPointerLeave={action(() => (this.removeHover = false))} +// /> +// <p +// style={{ +// position: 'absolute', +// left: 27, +// bottom: 8.4, +// fontSize: 12, +// opacity: showRemoveLabel ? 1 : 0, +// transition: '0.4s opacity ease', +// }}> +// Template will be <span style={{ textDecoration: 'underline', textDecorationColor: persistent ? 'green' : 'red', color: persistent ? 'green' : 'red' }}>{persistent ? 'kept' : 'removed'}</span> after upload +// </p> +// {centerPiece} +// <div +// style={{ +// position: 'absolute', +// top: 10, +// right: 10, +// borderRadius: '50%', +// width: 25, +// height: 25, +// background: 'black', +// pointerEvents: uploading ? 'none' : 'all', +// opacity: uploading ? 0 : 1, +// transition: '0.4s opacity ease', +// }} +// title={isEditing ? 'Back to Upload' : 'Add Metadata'} +// onClick={action(() => (this.editingMetadata = !this.editingMetadata))} +// /> +// <FontAwesomeIcon +// style={{ +// pointerEvents: 'none', +// position: 'absolute', +// right: isEditing ? 14 : 15, +// top: isEditing ? 15.4 : 16, +// opacity: uploading ? 0 : 1, +// transition: '0.4s opacity ease', +// }} +// icon={isEditing ? 'cloud-upload-alt' : 'tag'} +// color="#FFFFFF" +// size={'1x'} +// /> +// <div +// style={{ +// transition: '0.4s ease opacity', +// width: '100%', +// height: '100%', +// pointerEvents: isEditing ? 'all' : 'none', +// opacity: isEditing ? 1 : 0, +// overflowY: 'scroll', +// }}> +// <div +// style={{ +// borderRadius: '50%', +// width: 25, +// height: 25, +// marginLeft: 10, +// position: 'absolute', +// right: 41, +// top: 10, +// }} +// title={'Add Metadata Entry'} +// onClick={this.addMetadataEntry}> +// <FontAwesomeIcon +// style={{ +// pointerEvents: 'none', +// marginLeft: 6.4, +// marginTop: 5.2, +// }} +// icon={'plus'} +// size={'1x'} +// /> +// </div> +// <p style={{ paddingLeft: 10, paddingTop: 8, paddingBottom: 7 }}>Add metadata to your import...</p> +// <hr style={{ margin: '6px 10px 12px 10px' }} /> +// {entries.map(doc => ( +// <ImportMetadataEntry +// Document={doc} +// key={doc[Id]} +// remove={this.remove} +// ref={el => { +// if (el) this.entries.push(el); +// }} +// next={this.addMetadataEntry} +// /> +// ))} +// </div> +// </div> +// )} +// </Measure> +// ); +// } +// } |