aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/DashboardView.tsx
diff options
context:
space:
mode:
authormehekj <mehek.jethani@gmail.com>2022-10-12 13:21:07 -0400
committermehekj <mehek.jethani@gmail.com>2022-10-12 13:21:07 -0400
commit0b3a83acd4f75b7f6ff4b9bb7daf4377dede51a1 (patch)
tree438789f7e7f50e5eb9829e1f301b4d043d8d4906 /src/client/views/DashboardView.tsx
parent69ca9baca6ff1da272a5191187542351bd242ccc (diff)
parenteb5f75785fd28acb50f1b30434e89223fff00185 (diff)
Merge branch 'master' into schema-mehek
Diffstat (limited to 'src/client/views/DashboardView.tsx')
-rw-r--r--src/client/views/DashboardView.tsx252
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');