diff options
author | IEatChili <nanunguyen99@gmail.com> | 2024-06-10 11:06:02 -0400 |
---|---|---|
committer | IEatChili <nanunguyen99@gmail.com> | 2024-06-10 11:06:02 -0400 |
commit | 56568bbb0db34c0129b6a3c8770ce3f889dcbd31 (patch) | |
tree | 54b97fa16043fc41477d0f02db3f31f26a78dd9e | |
parent | b440901843a930c6c87ec23c59f90f1349c25b50 (diff) |
feat: ui changes
6 files changed, 86 insertions, 15 deletions
diff --git a/package-lock.json b/package-lock.json index 9b3904ff7..6cd2ab605 100644 --- a/package-lock.json +++ b/package-lock.json @@ -136,6 +136,7 @@ "js-datepicker": "^5.18.2", "jsonschema": "^1.4.1", "jszip": "^3.10.1", + "ldrs": "^1.0.2", "lodash": "^4.17.21", "mapbox-gl": "^3.0.1", "markdown-it": "^14.1.0", @@ -23613,6 +23614,11 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/ldrs": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ldrs/-/ldrs-1.0.2.tgz", + "integrity": "sha512-sYJmivdkIiHrUEqTrEWccBoLdaENpzbzkABI5rk8rRxTXrg9i2xVuDvUUuhOhJY3RmQyaoxs046pM1DCRdcIpg==" + }, "node_modules/leac": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", diff --git a/package.json b/package.json index ed05c4f45..bbd2a4c46 100644 --- a/package.json +++ b/package.json @@ -221,6 +221,7 @@ "js-datepicker": "^5.18.2", "jsonschema": "^1.4.1", "jszip": "^3.10.1", + "ldrs": "^1.0.2", "lodash": "^4.17.21", "mapbox-gl": "^3.0.1", "markdown-it": "^14.1.0", diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss index d0c12814c..5f2ce4e14 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss @@ -1,3 +1,18 @@ +.image-box-container { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + font-size: 10px; + line-height: 1; + background: none; + z-index: 1000; + padding: 0px; + overflow: auto; + cursor: default; +} + .image-label-list { display: flex; flex-direction: column; @@ -16,6 +31,7 @@ text-align: center; // Centers the text of the paragraph font-size: large; vertical-align: middle; + margin-left: 10px; } .IconButton { @@ -24,3 +40,10 @@ } } } + +.image-information { + display: flex; + flex-direction: column; + //align-items: center; + width: 100%; +} diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index 1c0035f0d..83ae69cfb 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -12,6 +12,11 @@ import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './ImageLabelBox.scss'; import { MainView } from '../../MainView'; import { MarqueeView } from './MarqueeView'; +import 'ldrs/ring'; +import { ring } from 'ldrs'; +import { SnappingManager } from '../../../util/SnappingManager'; +import { ImageCast } from '../../../../fields/Types'; +import { DocData } from '../../../../fields/DocSymbols'; @observer export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() { @@ -24,12 +29,14 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() { @observable _loading: boolean = true; @observable _currentLabel: string = ''; @observable _labelGroups: string[] = []; + @observable _selectedImages: Doc[] = []; + @observable _displayImageInformation: boolean = false; constructor(props: any) { super(props); makeObservable(this); ImageLabelBox.Instance = this; - + ring.register(); console.log('Image Box Has Been Initialized'); } @@ -77,14 +84,32 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() { this._loading = false; }; + @action + setSelectedImages = (selected: Doc[]) => { + this._selectedImages = selected; + }; + render() { if (this._loading) { - return <div className="searchBox-container">Loading...</div>; + return ( + <div className="image-box-container" style={{ pointerEvents: 'all', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}> + <l-ring size="60" color="white" /> + </div> + ); } return ( - <div className="searchBox-container"> - <div className="searchBox-bar"> + <div className="searchBox-container" style={{ pointerEvents: 'all', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}> + <div className="searchBox-bar" style={{ pointerEvents: 'all', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}> + <IconButton + tooltip={'See image information'} + onPointerDown={() => { + this._displayImageInformation = !this._displayImageInformation; + }} + icon={this._displayImageInformation ? <FontAwesomeIcon icon="caret-up" /> : <FontAwesomeIcon icon="caret-down" />} + color={MarqueeOptionsMenu.Instance.userColor} + style={{ width: '19px' }} + /> <input defaultValue="" autoComplete="off" @@ -93,7 +118,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() { // e.stopPropagation(); // }} type="text" - placeholder="Input a group to put images into..." + placeholder="Input labels for image groupings..." aria-label="label-input" id="new-label" className="searchBox-input" @@ -101,7 +126,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() { ref={this._inputRef} /> <IconButton - tooltip={'Add group'} + tooltip={'Add a label'} onPointerDown={() => { const input = document.getElementById('new-label') as HTMLInputElement; const newLabel = input.value; @@ -113,11 +138,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() { color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} /> - {this._labelGroups.length > 0 ? ( - <IconButton tooltip={'Group Images'} onPointerDown={this.groupImages} icon={<FontAwesomeIcon icon="object-group" />} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} /> - ) : ( - <div></div> - )} + {this._labelGroups.length > 0 ? <IconButton tooltip={'Group Images'} onPointerDown={this.groupImages} icon={<FontAwesomeIcon icon="object-group" />} color={Colors.MEDIUM_BLUE} style={{ width: '19px' }} /> : <div></div>} </div> <div> <div className="image-label-list"> @@ -139,6 +160,23 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() { })} </div> </div> + {this._displayImageInformation ? ( + <div className="image-information"> + {this._selectedImages.map(doc => { + const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.'); + return ( + <div> + <img src={`${name}_o.${type}`}></img> + {(doc[DocData].data_labels as string).split('\n').map(label => { + return <div className="image-label">{label}</div>; + })} + </div> + ); + })} + </div> + ) : ( + <div></div> + )} </div> ); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index f02cd9d45..b94a22d04 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -39,7 +39,7 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> { <IconButton tooltip="Summarize Documents" onPointerDown={this.summarize} icon={<FontAwesomeIcon icon="compress-arrows-alt" />} color={this.userColor} /> <IconButton tooltip="Delete Documents" onPointerDown={this.delete} icon={<FontAwesomeIcon icon="trash-alt" />} color={this.userColor} /> <IconButton tooltip="Pin selected region" onPointerDown={this.pinWithView} icon={<FontAwesomeIcon icon="map-pin" />} color={this.userColor} /> - <IconButton tooltip="Classify Images" onPointerDown={this.classifyImages} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} /> + <IconButton tooltip="Classify and Sort Images" onPointerDown={this.classifyImages} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} /> </> ); return this.getElement(buttons); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index bb5a2a66e..f98883bff 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -456,6 +456,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps } this._selectedDocs = this.marqueeSelect(false, DocumentType.IMG); // Get the selected documents from the marquee select. + ImageLabelBox.Instance!.setSelectedImages(this._selectedDocs); const imageInfos = this._selectedDocs.map(async doc => { if (!doc[DocData].data_labels) { @@ -478,7 +479,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps }); // Add the labels as fields to each image. ImageLabelBox.Instance!.endLoading(); - console.log('Complete!'); + console.log(this._selectedDocs); }); /** @@ -502,8 +503,10 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps { label: '', similarityScore: 0, }); // prettier-ignore doc[DocData].data_label = mostSimilarLabelCollect; // The label most similar to the image's contents. }); - this._props.Document._type_collection = CollectionViewType.Time; // Change the collection view to a Time view. - this._props.Document.pivotField = 'data_label'; // Sets the pivot to be the 'data_label'. + if (this._selectedDocs) { + this._props.Document._type_collection = CollectionViewType.Time; // Change the collection view to a Time view. + this._props.Document.pivotField = 'data_label'; // Sets the pivot to be the 'data_label'. + } }); @undoBatch |