diff options
| author | mehekj <mehek.jethani@gmail.com> | 2022-10-12 13:21:07 -0400 |
|---|---|---|
| committer | mehekj <mehek.jethani@gmail.com> | 2022-10-12 13:21:07 -0400 |
| commit | 0b3a83acd4f75b7f6ff4b9bb7daf4377dede51a1 (patch) | |
| tree | 438789f7e7f50e5eb9829e1f301b4d043d8d4906 /src/client/views/DashboardView.tsx | |
| parent | 69ca9baca6ff1da272a5191187542351bd242ccc (diff) | |
| parent | eb5f75785fd28acb50f1b30434e89223fff00185 (diff) | |
Merge branch 'master' into schema-mehek
Diffstat (limited to 'src/client/views/DashboardView.tsx')
| -rw-r--r-- | src/client/views/DashboardView.tsx | 252 |
1 files changed, 216 insertions, 36 deletions
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 84b1017b4..192e55431 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -1,13 +1,17 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Button, ColorPicker, FontSize, IconButton, Size } from 'browndash-components'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { DataSym, Doc, DocListCast, DocListCastAsync } from '../../fields/Doc'; import { Id } from '../../fields/FieldSymbols'; import { List } from '../../fields/List'; -import { Cast, ImageCast, StrCast } from '../../fields/Types'; +import { PrefetchProxy } from '../../fields/Proxy'; +import { listSpec } from '../../fields/Schema'; +import { ScriptField } from '../../fields/ScriptField'; +import { Cast, DocCast, ImageCast, StrCast } from '../../fields/Types'; import { DocServer } from '../DocServer'; -import { Docs, DocumentOptions } from '../documents/Documents'; +import { Docs, DocumentOptions, DocUtils } from '../documents/Documents'; import { CollectionViewType } from '../documents/DocumentTypes'; import { HistoryUtil } from '../util/History'; import { ScriptingGlobals } from '../util/ScriptingGlobals'; @@ -17,7 +21,10 @@ import { CollectionDockingView } from './collections/CollectionDockingView'; import { CollectionView } from './collections/CollectionView'; import { ContextMenu } from './ContextMenu'; import './DashboardView.scss'; +import { Colors } from './global/globalEnums'; import { MainViewModal } from './MainViewModal'; +import { ButtonType } from './nodes/button/FontIconBox'; +import { FaPlus } from 'react-icons/fa'; enum DashboardGroup { MyDashboards, @@ -35,6 +42,7 @@ export class DashboardView extends React.Component { @observable private selectedDashboardGroup = DashboardGroup.MyDashboards; @observable private newDashboardName: string | undefined = undefined; + @observable private newDashboardColor: string | undefined = undefined; @action abortCreateNewDashboard = () => { this.newDashboardName = undefined; }; @@ -47,12 +55,10 @@ export class DashboardView extends React.Component { this.selectedDashboardGroup = group; }; - clickDashboard = async (e: React.MouseEvent, dashboard: Doc) => { - if (e.detail === 2) { - Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard); - Doc.ActiveDashboard = dashboard; - Doc.ActivePage = 'dashboard'; - } + clickDashboard = (e: React.MouseEvent, dashboard: Doc) => { + Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard); + Doc.ActiveDashboard = dashboard; + Doc.ActivePage = 'dashboard'; }; getDashboards = () => { @@ -76,26 +82,45 @@ export class DashboardView extends React.Component { }; @undoBatch - createNewDashboard = async (name: string) => { - DashboardView.createNewDashboard(undefined, name); - this.abortCreateNewDashboard(); + createNewDashboard = async (name: string, background?: string) => { + setTimeout(() => { + this.abortCreateNewDashboard(); + }, 100); + DashboardView.createNewDashboard(undefined, name, background); }; @computed get namingInterface() { + const dashboardCount = DocListCast(Doc.MyDashboards.data).length + 1; + const placeholder = `Dashboard ${dashboardCount}`; return ( - <div> - <input className="password-inputs" placeholder="Untitled Dashboard" onChange={e => this.setNewDashboardName((e.target as any).value)} /> - <button className="password-submit" onClick={this.abortCreateNewDashboard}> - Cancel - </button> - <button - className="password-submit" - onClick={() => { - this.createNewDashboard(this.newDashboardName!); - }}> - Create - </button> + <div className="new-dashboard"> + <div className="header">Create New Dashboard</div> + <div className="title-input"> + Title + <input className="input" placeholder={placeholder} onChange={e => this.setNewDashboardName((e.target as any).value)} /> + </div> + <div className="color-picker"> + Background + <ColorPicker + onChange={color => { + this.newDashboardColor = color; + }} + /> + </div> + <div className="button-bar"> + <Button text="Cancel" borderRadius={10} hoverStyle={'gray'} fontSize={FontSize.SECONDARY} onClick={this.abortCreateNewDashboard} /> + <Button + text="Create" + borderRadius={10} + backgroundColor={Colors.LIGHT_BLUE} + hoverStyle={'darken'} + fontSize={FontSize.SECONDARY} + onClick={() => { + this.createNewDashboard(this.newDashboardName!, this.newDashboardColor); + }} + /> + </div> </div> ); } @@ -137,12 +162,19 @@ export class DashboardView extends React.Component { <> <div className="dashboard-view"> <div className="left-menu"> - <div - className="text-button" - onClick={() => { - this.setNewDashboardName(''); - }}> - New + <div className="new-dashboard-button"> + <Button + icon={<FaPlus />} + hoverStyle="darken" + backgroundColor={Colors.LIGHT_BLUE} + size={Size.MEDIUM} + fontSize={FontSize.HEADER} + text="New" + onClick={() => { + this.setNewDashboardName(''); + }} + borderRadius={50} + /> </div> <div className={`text-button ${this.selectedDashboardGroup === DashboardGroup.MyDashboards && 'selected'}`} onClick={() => this.selectDashboardGroup(DashboardGroup.MyDashboards)}> My Dashboards @@ -153,7 +185,7 @@ export class DashboardView extends React.Component { </div> <div className="all-dashboards"> {this.getDashboards().map(dashboard => { - const href = ImageCast((dashboard.thumb as Doc)?.data)?.url.href; + const href = ImageCast(dashboard.thumb)?.url.href; return ( <div className="dashboard-container" @@ -176,14 +208,23 @@ export class DashboardView extends React.Component { this._downY = e.clientY; }} onClick={e => { + e.preventDefault(); + e.stopPropagation(); this.onContextMenu(dashboard, e); }}> - <FontAwesomeIcon color="black" size="lg" icon="bars" /> + <IconButton isCircle={true} size={Size.SMALL} hoverStyle="gray" icon={<FontAwesomeIcon color="black" size="lg" icon="bars" />} /> </div> </div> </div> ); })} + <div + className="dashboard-container-new" + onClick={() => { + this.setNewDashboardName(''); + }}> + + + </div> </div> </div> <MainViewModal @@ -191,7 +232,7 @@ export class DashboardView extends React.Component { isDisplayed={this.newDashboardName !== undefined} interactive={true} closeOnExternalClick={this.abortCreateNewDashboard} - dialogueBoxStyle={{ width: '500px', height: '300px', background: Cast(Doc.SharingDoc().userColor, 'string', null) }} + dialogueBoxStyle={{ width: '400px', height: '180px', color: Colors.LIGHT_GRAY }} /> </> ); @@ -253,8 +294,89 @@ export class DashboardView extends React.Component { } }; - public static createNewDashboard = (id?: string, name?: string) => { - const presentation = Doc.MakeCopy(Doc.UserDoc().emptyPresentation as Doc, true); + public static resetDashboard = (dashboard: Doc) => { + const config = StrCast(dashboard.dockingConfig); + const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g); + const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) ?? []; + + const components = + docids.map(docid => ({ + type: 'component', + component: 'DocumentFrameRenderer', + title: 'Untitled Tab 1', + width: 600, + props: { + documentId: docid, + }, + componentName: 'lm-react-component', + isClosable: true, + reorderEnabled: true, + componentState: null, + })) ?? []; + const reset = { + isClosable: true, + reorderEnabled: true, + title: '', + openPopouts: [], + maximisedItemId: null, + settings: { + hasHeaders: true, + constrainDragToContainer: true, + reorderEnabled: true, + selectionEnabled: false, + popoutWholeStack: false, + blockedPopoutsThrowError: true, + closePopoutsOnUnload: true, + showPopoutIcon: true, + showMaximiseIcon: true, + showCloseIcon: true, + responsiveMode: 'onload', + tabOverlapAllowance: 0, + reorderOnTabMenuClick: false, + tabControlOffset: 10, + }, + dimensions: { + borderWidth: 3, + borderGrabWidth: 5, + minItemHeight: 10, + minItemWidth: 20, + headerHeight: 27, + dragProxyWidth: 300, + dragProxyHeight: 200, + }, + labels: { + close: 'close', + maximise: 'maximise', + minimise: 'minimise', + popout: 'new tab', + popin: 'pop in', + tabDropdown: 'additional tabs', + }, + content: [ + { + type: 'row', + isClosable: true, + reorderEnabled: true, + title: '', + content: [ + { + type: 'stack', + width: 100, + isClosable: true, + reorderEnabled: true, + title: '', + activeItemIndex: 0, + content: components, + }, + ], + }, + ], + }; + Doc.SetInPlace(dashboard, 'dockingConfig', JSON.stringify(reset), true); + return reset; + }; + + public static createNewDashboard = (id?: string, name?: string, background?: string) => { const dashboards = Doc.MyDashboards; const dashboardCount = DocListCast(dashboards.data).length + 1; const freeformOptions: DocumentOptions = { @@ -264,6 +386,7 @@ export class DashboardView extends React.Component { _height: 1000, _fitWidth: true, _backgroundGridShow: true, + backgroundColor: background, title: `Untitled Tab 1`, }; const title = name ? name : `Dashboard ${dashboardCount}`; @@ -276,13 +399,67 @@ export class DashboardView extends React.Component { dashboardDoc.data = new List<Doc>(dashboardTabs); dashboardDoc['pane-count'] = 1; - Doc.ActivePresentation = presentation; - Doc.AddDocToList(dashboards, 'data', dashboardDoc); + + DashboardView.SetupDashboardTrails(dashboardDoc); + // open this new dashboard Doc.ActiveDashboard = dashboardDoc; Doc.ActivePage = 'dashboard'; + Doc.ActivePresentation = undefined; }; + + public static SetupDashboardTrails(dashboardDoc: Doc) { + // this section is creating the button document itself === myTrails = new Button + const reqdBtnOpts: DocumentOptions = { + _forceActive: true, + _width: 30, + _height: 30, + _stayInCollection: true, + _hideContextMenu: true, + title: 'New trail', + toolTip: 'Create new trail', + btnType: ButtonType.ClickButton, + buttonText: 'New trail', + icon: 'plus', + system: true, + }; + const reqdBtnScript = { onClick: `createNewPresentation()` }; + const myTrailsBtn = DocUtils.AssignScripts(Docs.Create.FontIconDocument(reqdBtnOpts), reqdBtnScript); + + // createa a list of presentations (as a tree view collection) and store it on the new dashboard + // instead of assigning Doc.UserDoc().myrails we want to assign Doc.AxtiveDashboard.myTrails + // but we don't want to create the list of trails here-- but rather in createDashboard + const reqdOpts: DocumentOptions = { + title: 'My Trails', + _showTitle: 'title', + _height: 100, + treeViewHideTitle: true, + _fitWidth: true, + _gridGap: 5, + _forceActive: true, + childDropAction: 'alias', + treeViewTruncateTitleWidth: 150, + ignoreClick: true, + buttonMenu: true, + buttonMenuDoc: myTrailsBtn, + contextMenuIcons: new List<string>(['plus']), + contextMenuLabels: new List<string>(['Create New Trail']), + _lockedPosition: true, + boxShadow: '0 0', + childDontRegisterViews: true, + targetDropAction: 'same', + system: true, + explainer: 'All of the trails that you have created will appear here.', + }; + const myTrails = DocUtils.AssignScripts(Docs.Create.TreeDocument([], reqdOpts), { treeViewChildDoubleClick: 'openPresentation(documentView.rootDoc)' }); + dashboardDoc.myTrails = new PrefetchProxy(myTrails); + + const contextMenuScripts = [reqdBtnScript.onClick]; + if (Cast(myTrails.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) { + myTrails.contextMenuScripts = new List<ScriptField>(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!)); + } + } } export function AddToList(MySharedDocs: Doc, arg1: string, dash: any) { @@ -298,6 +475,9 @@ ScriptingGlobals.add(function shareDashboard(dashboard: Doc) { ScriptingGlobals.add(function removeDashboard(dashboard: Doc) { DashboardView.removeDashboard(dashboard); }, 'Remove Dashboard from Dashboards'); +ScriptingGlobals.add(function resetDashboard(dashboard: Doc) { + DashboardView.resetDashboard(dashboard); +}, 'move all dashboard tabs to single stack'); ScriptingGlobals.add(function addToDashboards(dashboard: Doc) { DashboardView.openDashboard(Doc.MakeAlias(dashboard)); }, 'adds Dashboard to set of Dashboards'); |
