diff options
Diffstat (limited to 'src/client/views/newlightbox/components')
16 files changed, 545 insertions, 0 deletions
diff --git a/src/client/views/newlightbox/components/EditableText/EditableText.scss b/src/client/views/newlightbox/components/EditableText/EditableText.scss new file mode 100644 index 000000000..7828538ab --- /dev/null +++ b/src/client/views/newlightbox/components/EditableText/EditableText.scss @@ -0,0 +1,34 @@ +@import '../../NewLightboxStyles.scss'; + +.lb-editableText, +.lb-displayText { + padding: 4px 7px !important; + border: $standard-border !important; + border-color: $gray-l2 !important; +} + +.lb-editableText { + -webkit-appearance: none; + overflow: hidden; + font-size: inherit; + border: none; + outline: none; + width: 100%; + margin: 0px; + padding: 0px; + box-shadow: none !important; + background: none; + + &:focus { + outline: none; + background-color: $blue-l1; + } +} + +.lb-displayText { + cursor: text !important; + width: 100%; + display: flex; + align-items: center; + font-size: inherit; +}
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/EditableText/EditableText.tsx b/src/client/views/newlightbox/components/EditableText/EditableText.tsx new file mode 100644 index 000000000..e9e7ca264 --- /dev/null +++ b/src/client/views/newlightbox/components/EditableText/EditableText.tsx @@ -0,0 +1,65 @@ +import * as React from 'react' +import './EditableText.scss' +import { Size } from 'browndash-components' + +export interface IEditableTextProps { + text: string + placeholder?: string + editing: boolean + onEdit: (newText: string) => void + setEditing: (editing: boolean) => void + backgroundColor?: string + size?: Size + height?: number +} + +/** + * Editable Text is used for inline renaming of some text. + * It appears as normal UI text but transforms into a text input field when the user clicks on or focuses it. + * @param props + * @returns + */ +export const EditableText = (props: IEditableTextProps) => { + const { + editing, + height, + size, + text, + onEdit, + setEditing, + backgroundColor, + placeholder, + } = props + + const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => { + onEdit(event.target.value) + } + + return editing ? ( + <input + style={{ background: backgroundColor, height: height }} + placeholder={placeholder} + size={1} + className="lb-editableText" + autoFocus + onChange={handleOnChange} + onBlur={() => setEditing(false)} + defaultValue={text} + ></input> + ) : ( + <input + style={{ background: backgroundColor, height: height }} + placeholder={placeholder} + size={1} + className="lb-editableText" + autoFocus + onChange={handleOnChange} + onBlur={() => setEditing(false)} + defaultValue={text} + ></input> + // <div className="lb-displayText" onClick={(e) => { + // e.stopPropagation() + // setEditing(true) + // }}>{text}</div> + ) +} diff --git a/src/client/views/newlightbox/components/EditableText/index.ts b/src/client/views/newlightbox/components/EditableText/index.ts new file mode 100644 index 000000000..e3367b175 --- /dev/null +++ b/src/client/views/newlightbox/components/EditableText/index.ts @@ -0,0 +1 @@ +export * from './EditableText' diff --git a/src/client/views/newlightbox/components/Recommendation/Recommendation.scss b/src/client/views/newlightbox/components/Recommendation/Recommendation.scss new file mode 100644 index 000000000..c86c63ba0 --- /dev/null +++ b/src/client/views/newlightbox/components/Recommendation/Recommendation.scss @@ -0,0 +1,176 @@ +@import '../../NewLightboxStyles.scss'; + +.recommendation-container { + width: 100%; + height: fit-content; + min-height: 180px; + border-radius: 20px; + display: grid; + grid-template-columns: 0% 100%; + grid-template-rows: auto auto auto auto auto; + gap: 5px 0px; + padding: 10px; + cursor: pointer; + transition: 0.2s ease; + border: $standard-border; + border-color: $gray-l2; + background: white; + + &:hover { + // background: white !important; + transform: scale(1.02); + z-index: 0; + + .title { + text-decoration: underline; + } + } + + &.previewUrl { + grid-template-columns: calc(30% - 10px) 70%; + grid-template-rows: auto auto auto auto auto; + gap: 5px 10px; + } + + &.loading { + animation: skeleton-loading-l2 1s linear infinite alternate; + border: none; + grid-template-columns: calc(30% - 10px) 70%; + grid-template-rows: auto auto auto auto auto; + gap: 5px 10px; + + .image-container, + .title, + .info, + .source, + .explainer, + .hide-rec { + animation: skeleton-loading-l3 1s linear infinite alternate; + } + + .title { + border-radius: 20px; + } + } + + .distance-container, + .type-container, + .source-container { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + gap: 5px; + } + + .image-container { + grid-row: 2/5; + grid-column: 1; + border-radius: 20px; + overflow: hidden; + + .image { + width: 100%; + height: 100%; + object-fit: cover; + } + } + + .title { + grid-row: 1; + grid-column: 1/3; + border-radius: 20px; + font-size: $h2-size; + font-weight: $h2-weight; + overflow: hidden; + border-radius: 0px; + min-height: 30px; + } + + .info { + grid-row: 2; + grid-column: 2; + border-radius: 20px; + display: flex; + flex-direction: row; + gap: 5px; + font-size: $body-size; + + .lb-type { + padding: 2px 7px !important; + background: $gray-l2; + } + } + + .lb-label { + color: $gray-l3; + font-weight: $h1-weight; + font-size: $body-size; + } + + .source { + grid-row: 3; + grid-column: 2; + border-radius: 20px; + font-size: $body-size; + display: flex; + justify-content: flex-start; + align-items: center; + + .lb-source { + padding: 2px 7px !important; + background: $gray-l2; + border-radius: 10px; + white-space: nowrap; + max-width: 130px; + text-overflow: ellipsis; + overflow: hidden; + } + } + + .explainer { + grid-row: 4; + grid-column: 2; + border-radius: 20px; + font-size: 10px; + width: 100%; + background: $blue-l1; + border-radius: 0; + padding: 10px; + + .concepts-container { + display: flex; + flex-flow: row wrap; + margin-top: 3px; + gap: 3px; + .concept { + padding: 2px 7px !important; + background: $gray-l2; + } + } + } + + .hide-rec { + grid-row: 5; + grid-column: 2; + border-radius: 20px; + font-size: $body-size; + display: flex; + align-items: center; + margin-top: 5px; + gap: 5px; + justify-content: flex-end; + text-transform: underline; + } + + &.dark { + background: $black; + border-color: $white; + } + + &.light, + &.default { + background: $white; + border-color: $white; + } +}
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx new file mode 100644 index 000000000..96846673b --- /dev/null +++ b/src/client/views/newlightbox/components/Recommendation/Recommendation.tsx @@ -0,0 +1,102 @@ +import * as React from 'react'; +import { IRecommendation } from './utils'; +import './Recommendation.scss'; +import { getType } from '../../utils'; +import { FaEyeSlash } from 'react-icons/fa'; +import { NewLightboxView } from '../../NewLightboxView'; +import { DocumentManager } from '../../../../util/DocumentManager'; +import { Doc } from '../../../../../fields/Doc'; +import { Docs } from '../../../../documents/Documents'; + +export const Recommendation = (props: IRecommendation) => { + const { title, data, type, text, transcript, loading, source, previewUrl, related_concepts, distance, docId } = props; + + return ( + <div + className={`recommendation-container ${loading && 'loading'} ${previewUrl && 'previewUrl'}`} + onClick={() => { + let doc: Doc | null = null; + if (source == 'Dash' && docId) { + const docView = DocumentManager.Instance.getDocumentViewsById(docId).lastElement(); + if (docView) { + doc = docView.rootDoc; + } + } else if (data) { + switch (type) { + case 'YouTube': + console.log('create ', type, 'document'); + doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript }); + break; + case 'Video': + console.log('create ', type, 'document'); + doc = Docs.Create.VideoDocument(data, { title: title, _width: 400, _height: 315, transcript }); + break; + case 'Webpage': + console.log('create ', type, 'document'); + doc = Docs.Create.WebDocument(data, { title: title, text: text }); + break; + case 'HTML': + console.log('create ', type, 'document'); + doc = Docs.Create.WebDocument(data, { title: title, text: text }); + break; + case 'Text': + console.log('create ', type, 'document'); + doc = Docs.Create.TextDocument(data, { title: title, text: text }); + break; + case 'PDF': + console.log('create ', type, 'document'); + doc = Docs.Create.PdfDocument(data, { title: title, text: text }); + break; + } + } + if (doc !== null) NewLightboxView.SetNewLightboxDoc(doc); + }}> + {loading ? <div className={`image-container`}></div> : previewUrl ? <div className={`image-container`}>{<img className={`image`} src={previewUrl}></img>}</div> : null} + <div className={`title`}>{title}</div> + <div className={`info`}> + {!loading && ( + <div className={`type-container`}> + <div className={`lb-label`}>Type</div> + <div className={`lb-type`}>{getType(type!)}</div> + </div> + )} + {!loading && ( + <div className={`distance-container`}> + <div className={`lb-label`}>Distance</div> + <div className={`lb-distance`}>{distance}</div> + </div> + )} + </div> + <div className={`source`}> + {!loading && ( + <div className={`source-container`}> + <div className={`lb-label`}>Source</div> + <div className={`lb-source`}>{source}</div> + </div> + )} + </div> + <div className={`explainer`}> + {!loading && ( + <div> + You are seeing this recommendation because this document also explores + <div className={`concepts-container`}> + {related_concepts?.map(val => { + return <div className={'concept'}>{val}</div>; + })} + </div> + </div> + )} + </div> + <div className={`hide-rec`}> + {!loading && ( + <> + <div>Hide Recommendation</div> + <div style={{ fontSize: 15, paddingRight: 5 }}> + <FaEyeSlash /> + </div> + </> + )} + </div> + </div> + ); +}; diff --git a/src/client/views/newlightbox/components/Recommendation/index.ts b/src/client/views/newlightbox/components/Recommendation/index.ts new file mode 100644 index 000000000..12ebf9d6e --- /dev/null +++ b/src/client/views/newlightbox/components/Recommendation/index.ts @@ -0,0 +1,2 @@ +export * from './utils' +export * from './Recommendation'
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/Recommendation/utils.ts b/src/client/views/newlightbox/components/Recommendation/utils.ts new file mode 100644 index 000000000..796ce0eb0 --- /dev/null +++ b/src/client/views/newlightbox/components/Recommendation/utils.ts @@ -0,0 +1,23 @@ +import { DocumentType } from "../../../../documents/DocumentTypes" + +export interface IRecommendation { + loading?: boolean + type?: DocumentType | string, + data?: string, + title?: string, + text?: string, + source?: string, + previewUrl?: string, + transcript?: { + text: string, + start: number, + duration: number + }[], + embedding?: { + x: number, + y: number + }, + distance?: number, + related_concepts?: string[], + docId?: string +}
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/SkeletonDoc/SkeletonDoc.scss b/src/client/views/newlightbox/components/SkeletonDoc/SkeletonDoc.scss new file mode 100644 index 000000000..e541e3f3c --- /dev/null +++ b/src/client/views/newlightbox/components/SkeletonDoc/SkeletonDoc.scss @@ -0,0 +1,82 @@ +@import '../../NewLightboxStyles.scss'; + +.skeletonDoc-container { + display: flex; + flex-direction: column; + height: calc(100% - 40px); + margin: 20px; + gap: 20px; + + .header { + width: calc(100% - 20px); + height: 80px; + background: $gray-l2; + animation: skeleton-loading-l2 1s linear infinite alternate; + display: grid; + grid-template-rows: 60% 40%; + padding: 10px; + grid-template-columns: auto auto auto auto; + border-radius: 20px; + + .title { + grid-row: 1; + grid-column: 1 / 5; + display: flex; + width: fit-content; + height: 100%; + min-width: 500px; + font-size: $title-size; + animation: skeleton-loading-l3 1s linear infinite alternate; + border-radius: 20px; + } + + .type { + display: flex; + padding: 3px 7px; + width: fit-content; + height: fit-content; + margin-top: 8px; + min-height: 15px; + min-width: 60px; + grid-row: 2; + grid-column: 1; + animation: skeleton-loading-l3 1s linear infinite alternate; + border-radius: 20px; + } + + .buttons-container { + grid-row: 1 / 3; + grid-column: 5; + display: flex; + justify-content: flex-end; + align-items: center; + gap: 10px; + + .button { + width: 50px; + height: 50px; + border-radius: 100%; + animation: skeleton-loading-l3 1s linear infinite alternate; + } + } + + } + + .content { + width: 100%; + flex: 1; + -webkit-flex: 1; /* Chrome */ + background: $gray-l2; + animation: skeleton-loading-l2 1s linear infinite alternate; + border-radius: 20px; + } + + // &.dark { + // background: $black; + // } + + // &.light, + // &.default { + // background: $white; + // } +}
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/SkeletonDoc/SkeletonDoc.tsx b/src/client/views/newlightbox/components/SkeletonDoc/SkeletonDoc.tsx new file mode 100644 index 000000000..50cee893f --- /dev/null +++ b/src/client/views/newlightbox/components/SkeletonDoc/SkeletonDoc.tsx @@ -0,0 +1,22 @@ +import './SkeletonDoc.scss'; +import { ISkeletonDoc } from "./utils"; +import * as React from 'react'; + +export const SkeletonDoc = (props: ISkeletonDoc) => { + const { type, data } = props + + return <div className={`skeletonDoc-container`}> + <div className={`header`}> + <div className={`title`}></div> + <div className={`type`}></div> + <div className={`tags`}></div> + <div className={`buttons-container`}> + <div className={`button`}></div> + <div className={`button`}></div> + </div> + </div> + <div className={`content`}> + {data} + </div> + </div> +}
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/SkeletonDoc/index.ts b/src/client/views/newlightbox/components/SkeletonDoc/index.ts new file mode 100644 index 000000000..396b7272b --- /dev/null +++ b/src/client/views/newlightbox/components/SkeletonDoc/index.ts @@ -0,0 +1 @@ +export * from './SkeletonDoc'
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/SkeletonDoc/utils.ts b/src/client/views/newlightbox/components/SkeletonDoc/utils.ts new file mode 100644 index 000000000..81c32c328 --- /dev/null +++ b/src/client/views/newlightbox/components/SkeletonDoc/utils.ts @@ -0,0 +1,5 @@ +import { IRecommendation } from "../Recommendation"; + +export interface ISkeletonDoc extends IRecommendation { + +}
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/Template/Template.scss b/src/client/views/newlightbox/components/Template/Template.scss new file mode 100644 index 000000000..5b72ddaf9 --- /dev/null +++ b/src/client/views/newlightbox/components/Template/Template.scss @@ -0,0 +1,15 @@ +@import '../../NewLightboxStyles.scss'; + +.template-container { + width: 100vw; + height: 100vh; + + &.dark { + background: $black; + } + + &.light, + &.default { + background: $white; + } +}
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/Template/Template.tsx b/src/client/views/newlightbox/components/Template/Template.tsx new file mode 100644 index 000000000..9c6f0f59c --- /dev/null +++ b/src/client/views/newlightbox/components/Template/Template.tsx @@ -0,0 +1,10 @@ +import './Template.scss'; +import * as React from 'react'; +import { ITemplate } from "./utils"; + +export const Template = (props: ITemplate) => { + + return <div className={`template-container`}> + + </div> +}
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/Template/index.ts b/src/client/views/newlightbox/components/Template/index.ts new file mode 100644 index 000000000..36b5f3f46 --- /dev/null +++ b/src/client/views/newlightbox/components/Template/index.ts @@ -0,0 +1 @@ +export * from './Template'
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/Template/utils.ts b/src/client/views/newlightbox/components/Template/utils.ts new file mode 100644 index 000000000..965e653ec --- /dev/null +++ b/src/client/views/newlightbox/components/Template/utils.ts @@ -0,0 +1,3 @@ +export interface ITemplate { + +}
\ No newline at end of file diff --git a/src/client/views/newlightbox/components/index.ts b/src/client/views/newlightbox/components/index.ts new file mode 100644 index 000000000..3f9128690 --- /dev/null +++ b/src/client/views/newlightbox/components/index.ts @@ -0,0 +1,3 @@ +export * from './Template' +export * from './Recommendation' +export * from './SkeletonDoc'
\ No newline at end of file |