aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/DashboardView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/DashboardView.tsx')
-rw-r--r--src/client/views/DashboardView.tsx152
1 files changed, 92 insertions, 60 deletions
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 50cf2226e..3e4827c83 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -1,16 +1,17 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, ColorPicker, FontSize, IconButton, Size } from 'browndash-components';
+import { Button, ColorPicker, EditableText, FontSize, IconButton, Size, Type } from 'browndash-components';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
+import { FaPlus } from 'react-icons/fa';
import { Doc, DocListCast, DocListCastAsync } from '../../fields/Doc';
-import { DocData } from '../../fields/DocSymbols';
+import { AclPrivate, DocAcl } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
import { PrefetchProxy } from '../../fields/Proxy';
import { listSpec } from '../../fields/Schema';
import { ScriptField } from '../../fields/ScriptField';
-import { Cast, DocCast, ImageCast, StrCast } from '../../fields/Types';
+import { Cast, ImageCast, StrCast } from '../../fields/Types';
import { DocServer } from '../DocServer';
import { Docs, DocumentOptions, DocUtils } from '../documents/Documents';
import { CollectionViewType } from '../documents/DocumentTypes';
@@ -24,8 +25,7 @@ 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';
+import { ButtonType } from './nodes/FontIconBox/FontIconBox';
enum DashboardGroup {
MyDashboards,
@@ -43,13 +43,16 @@ export class DashboardView extends React.Component {
@observable private selectedDashboardGroup = DashboardGroup.MyDashboards;
@observable private newDashboardName: string | undefined = undefined;
- @observable private newDashboardColor: string | undefined = undefined;
+ @observable private newDashboardColor: string | undefined = '#AFAFAF';
@action abortCreateNewDashboard = () => {
this.newDashboardName = undefined;
};
@action setNewDashboardName(name: string) {
this.newDashboardName = name;
}
+ @action setNewDashboardColor(color: string) {
+ this.newDashboardColor = color;
+ }
@action
selectDashboardGroup = (group: DashboardGroup) => {
@@ -57,28 +60,30 @@ export class DashboardView extends React.Component {
};
clickDashboard = (e: React.MouseEvent, dashboard: Doc) => {
- Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard);
- Doc.ActiveDashboard = dashboard;
+ if (this.selectedDashboardGroup === DashboardGroup.SharedDashboards) {
+ DashboardView.openSharedDashboard(dashboard);
+ } else {
+ Doc.ActiveDashboard = dashboard;
+ }
Doc.ActivePage = 'dashboard';
};
- getDashboards = () => {
+ getDashboards = (whichGroup: DashboardGroup) => {
const allDashboards = DocListCast(Doc.MyDashboards.data);
- if (this.selectedDashboardGroup === DashboardGroup.MyDashboards) {
+ if (whichGroup === DashboardGroup.MyDashboards) {
return allDashboards.filter(dashboard => Doc.GetProto(dashboard).author === Doc.CurrentUserEmail);
- } else {
- const sharedDashboards = DocListCast(Doc.MySharedDocs.data).filter(doc => doc._type_collection === CollectionViewType.Docking);
- return sharedDashboards;
}
+ const sharedDashboards = DocListCast(Doc.MySharedDocs.data_dashboards).filter(doc => doc.dockingConfig);
+ return sharedDashboards;
};
isUnviewedSharedDashboard = (dashboard: Doc): boolean => {
- // const sharedDashboards = DocListCast(Doc.MySharedDocs.data).filter(doc => doc._type_collection === CollectionViewType.Docking);
+ // const sharedDashboards = DocListCast(Doc.MySharedDocs.data_dashboards).filter(doc => doc._type_collection === CollectionViewType.Docking);
return !DocListCast(Doc.MySharedDocs.viewed).includes(dashboard);
};
getSharedDashboards = () => {
- const sharedDashs = DocListCast(Doc.MySharedDocs.data).filter(doc => doc._type_collection === CollectionViewType.Docking);
+ const sharedDashs = DocListCast(Doc.MySharedDocs.data_dashboards).filter(doc => doc._type_collection === CollectionViewType.Docking);
return sharedDashs.filter(dashboard => !DocListCast(Doc.MySharedDocs.viewed).includes(dashboard));
};
@@ -95,23 +100,25 @@ export class DashboardView extends React.Component {
const dashboardCount = DocListCast(Doc.MyDashboards.data).length + 1;
const placeholder = `Dashboard ${dashboardCount}`;
return (
- <div className="new-dashboard">
+ <div
+ className="new-dashboard"
+ style={{
+ background: StrCast(Doc.UserDoc().userBackgroundColor),
+ color: StrCast(Doc.UserDoc().userColor),
+ }}>
<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>
+ <EditableText formLabel="Title" placeholder={placeholder} type={Type.SEC} color={StrCast(Doc.UserDoc().userColor)} setVal={val => this.setNewDashboardName(val as string)} fillWidth />
+ <ColorPicker
+ formLabel="Background" //
+ colorPickerType="github"
+ type={Type.TERT}
+ selectedColor={this.newDashboardColor}
+ setFinalColor={this.setNewDashboardColor}
+ setSelectedColor={this.setNewDashboardColor}
+ />
<div className="button-bar">
- <Button text="Cancel" onClick={this.abortCreateNewDashboard} />
- <Button text="Create" onClick={() => this.createNewDashboard(this.newDashboardName!, this.newDashboardColor)} />
+ <Button text="Cancel" color={StrCast(Doc.UserDoc().userColor)} onClick={this.abortCreateNewDashboard} />
+ <Button type={Type.TERT} text="Create" color={StrCast(Doc.UserDoc().userVariantColor)} onClick={() => this.createNewDashboard(this.newDashboardName!, this.newDashboardColor)} />
</div>
</div>
);
@@ -150,32 +157,43 @@ export class DashboardView extends React.Component {
};
render() {
+ const color = StrCast(Doc.UserDoc().userColor);
+ const variant = StrCast(Doc.UserDoc().userVariantColor);
return (
<>
<div className="dashboard-view">
<div className="left-menu">
- <div className="new-dashboard-button">
- <Button icon={<FaPlus />} size={Size.MEDIUM} text="New" onClick={() => this.setNewDashboardName('')} />
- </div>
- <div className={`text-button ${this.selectedDashboardGroup === DashboardGroup.MyDashboards && 'selected'}`} onClick={() => this.selectDashboardGroup(DashboardGroup.MyDashboards)}>
- My Dashboards
- </div>
- <div className={`text-button ${this.selectedDashboardGroup === DashboardGroup.SharedDashboards && 'selected'}`} onClick={() => this.selectDashboardGroup(DashboardGroup.SharedDashboards)}>
- Shared Dashboards
- </div>
+ <Button text={'My Dashboards'} active={this.selectedDashboardGroup === DashboardGroup.MyDashboards} color={color} align={'flex-start'} onClick={() => this.selectDashboardGroup(DashboardGroup.MyDashboards)} fillWidth />
+ <Button
+ text={'Shared Dashboards' + ' (' + this.getDashboards(DashboardGroup.SharedDashboards).length + ')'}
+ active={this.selectedDashboardGroup === DashboardGroup.SharedDashboards}
+ color={this.getDashboards(DashboardGroup.SharedDashboards).some(dash => !DocListCast(Doc.MySharedDocs.viewed).includes(dash)) ? 'green' : color}
+ align={'flex-start'}
+ onClick={() => this.selectDashboardGroup(DashboardGroup.SharedDashboards)}
+ fillWidth
+ />
+ <Button icon={<FaPlus />} color={variant} iconPlacement="left" text="New Dashboard" type={Type.TERT} onClick={() => this.setNewDashboardName('')} />
</div>
<div className="all-dashboards">
- {this.getDashboards().map(dashboard => {
+ {this.getDashboards(this.selectedDashboardGroup).map(dashboard => {
const href = ImageCast(dashboard.thumb)?.url.href;
+ const shared = Object.keys(dashboard[DocAcl])
+ .filter(key => key !== `acl-${Doc.CurrentUserEmailNormalized}` && !['acl-Me', 'acl-Guest'].includes(key))
+ .some(key => dashboard[DocAcl][key] !== AclPrivate);
return (
- <div className="dashboard-container" key={dashboard[Id]} onContextMenu={e => this.onContextMenu(dashboard, e)} onClick={e => this.clickDashboard(e, dashboard)}>
+ <div
+ className="dashboard-container"
+ key={dashboard[Id]}
+ style={{ background: this.isUnviewedSharedDashboard(dashboard) && this.selectedDashboardGroup === DashboardGroup.SharedDashboards ? '#6CB982' : shared ? variant : '' }}
+ onContextMenu={e => this.onContextMenu(dashboard, e)}
+ onClick={e => this.clickDashboard(e, dashboard)}>
<img
src={
href ?? 'https://media.istockphoto.com/photos/hot-air-balloons-flying-over-the-botan-canyon-in-turkey-picture-id1297349747?b=1&k=20&m=1297349747&s=170667a&w=0&h=oH31fJty_4xWl_JQ4OIQWZKP8C6ji9Mz7L4XmEnbqRU='
}
/>
<div className="info">
- <input style={{ border: 'unset' }} className="input" onClick={e => e.stopPropagation()} defaultValue={StrCast(dashboard.title)} onChange={e => (Doc.GetProto(dashboard).title = (e.target as any).value)} />
+ <EditableText type={Type.PRIM} color={color} val={StrCast(dashboard.title)} setVal={val => (Doc.GetProto(dashboard).title = val)} />
{this.selectedDashboardGroup === DashboardGroup.SharedDashboards && this.isUnviewedSharedDashboard(dashboard) ? <div>unviewed</div> : <div></div>}
<div
className="more"
@@ -188,9 +206,17 @@ export class DashboardView extends React.Component {
e.stopPropagation();
this.onContextMenu(dashboard, e);
}}>
- <Button size={Size.SMALL} icon={<FontAwesomeIcon color="black" size="lg" icon="bars" />} />
+ <Button size={Size.SMALL} color={color} icon={<FontAwesomeIcon color={color} icon="bars" />} />
</div>
</div>
+ <div
+ className={`background`}
+ style={{
+ background: StrCast(Doc.UserDoc().userColor),
+ filter: 'opacity(0.2)',
+ }}
+ />
+ <div className={'dashboard-status' + (shared ? '-shared' : '')}>{shared ? 'shared' : ''}</div>
</div>
);
})}
@@ -200,6 +226,13 @@ export class DashboardView extends React.Component {
this.setNewDashboardName('');
}}>
+
+ <div
+ className={`background`}
+ style={{
+ background: StrCast(Doc.UserDoc().userColor),
+ filter: 'opacity(0.2)',
+ }}
+ />
</div>
</div>
</div>
@@ -221,6 +254,11 @@ export class DashboardView extends React.Component {
return CollectionDockingView.TakeSnapshot(Doc.ActiveDashboard);
}
+ public static openSharedDashboard = (dashboard: Doc) => {
+ Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard);
+ DashboardView.openDashboard(Doc.BestEmbedding(dashboard));
+ };
+
/// opens a dashboard as the ActiveDashboard (and adds the dashboard to the users list of dashboards if it's not already there).
/// this also sets the readonly state of the dashboard based on the current mode of dash (from its url)
public static openDashboard = (doc: Doc | undefined, fromHistory = false) => {
@@ -347,13 +385,13 @@ export class DashboardView extends React.Component {
},
],
};
- Doc.SetInPlace(dashboard, 'dockingConfig', JSON.stringify(reset), true);
+ if (dashboard.dockingConfig && dashboard.dockingConfig !== Doc.GetProto(dashboard).dockingConfig) dashboard.dockingConfig = JSON.stringify(reset);
+ else 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 dashboardCount = DocListCast(Doc.MyDashboards.data).length + 1;
const freeformOptions: DocumentOptions = {
x: 0,
y: 400,
@@ -368,12 +406,9 @@ export class DashboardView extends React.Component {
const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row');
- // switching the tabs from the datadoc to the regular doc
- const dashboardTabs = DocListCast(dashboardDoc[DocData].data);
- dashboardDoc.data = new List<Doc>(dashboardTabs);
dashboardDoc['pane-count'] = 1;
- Doc.AddDocToList(dashboards, 'data', dashboardDoc);
+ Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc);
DashboardView.SetupDashboardTrails(dashboardDoc);
@@ -389,10 +424,11 @@ export class DashboardView extends React.Component {
_forceActive: true,
_width: 30,
_height: 30,
- _stayInCollection: true,
+ _dragOnlyWithinContainer: true,
_layout_hideContextMenu: true,
title: 'New trail',
toolTip: 'Create new trail',
+ color: Colors.BLACK,
btnType: ButtonType.ClickButton,
buttonText: 'New trail',
icon: 'plus',
@@ -408,12 +444,12 @@ export class DashboardView extends React.Component {
title: 'My Trails',
_layout_showTitle: 'title',
_height: 100,
- treeViewHideTitle: true,
+ treeView_HideTitle: true,
_layout_fitWidth: true,
_gridGap: 5,
_forceActive: true,
- childDropAction: 'embed',
- treeViewTruncateTitleWidth: 150,
+ childDragAction: 'embed',
+ treeView_TruncateTitleWidth: 150,
ignoreClick: true,
layout_headerButton: myTrailsBtn,
contextMenuIcons: new List<string>(['plus']),
@@ -421,11 +457,11 @@ export class DashboardView extends React.Component {
_lockedPosition: true,
layout_boxShadow: '0 0',
childDontRegisterViews: true,
- targetDropAction: 'same',
+ dropAction: 'same',
isSystem: true,
layout_explainer: 'All of the trails that you have created will appear here.',
};
- const myTrails = DocUtils.AssignScripts(Docs.Create.TreeDocument([], reqdOpts), { treeViewChildDoubleClick: 'openPresentation(documentView.rootDoc)' });
+ const myTrails = DocUtils.AssignScripts(Docs.Create.TreeDocument([], reqdOpts), { treeView_ChildDoubleClick: 'openPresentation(documentView.rootDoc)' });
dashboardDoc.myTrails = new PrefetchProxy(myTrails);
const contextMenuScripts = [reqdBtnScript.onClick];
@@ -435,10 +471,6 @@ export class DashboardView extends React.Component {
}
}
-export function AddToList(MySharedDocs: Doc, arg1: string, dash: any) {
- throw new Error('Function not implemented.');
-}
-
ScriptingGlobals.add(function createNewDashboard() {
return DashboardView.createNewDashboard();
}, 'creates a new dashboard when called');