aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts52
-rw-r--r--src/client/util/CurrentUserUtils.ts93
-rw-r--r--src/client/views/ContextMenu.scss2
-rw-r--r--src/client/views/ContextMenuItem.tsx4
-rw-r--r--src/client/views/MainViewModal.scss3
-rw-r--r--src/client/views/PropertiesButtons.scss41
-rw-r--r--src/client/views/PropertiesButtons.tsx53
-rw-r--r--src/client/views/SidebarAnnos.tsx3
-rw-r--r--src/client/views/StyleProvider.tsx4
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackingView.scss24
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx119
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx95
-rw-r--r--src/client/views/collections/TabDocView.tsx3
-rw-r--r--src/client/views/collections/TreeView.tsx5
-rw-r--r--src/client/views/collections/collectionLinearView/CollectionLinearView.scss6
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx2
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx2
-rw-r--r--src/client/views/nodes/AudioBox.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
-rw-r--r--src/client/views/nodes/PDFBox.scss16
-rw-r--r--src/client/views/nodes/PDFBox.tsx13
-rw-r--r--src/client/views/nodes/WebBox.scss9
-rw-r--r--src/client/views/nodes/WebBox.tsx13
-rw-r--r--src/client/views/nodes/button/FontIconBox.scss29
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx15
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.scss21
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx16
-rw-r--r--src/client/views/search/SearchBox.tsx2
-rw-r--r--src/client/views/topbar/TopBar.scss4
-rw-r--r--src/client/views/topbar/TopBar.tsx3
31 files changed, 460 insertions, 202 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index c4a713dc6..bd247bd01 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -59,6 +59,7 @@ import { WebBox } from "../views/nodes/WebBox";
import { SearchBox } from "../views/search/SearchBox";
import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo";
import { DocumentType } from "./DocumentTypes";
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
const path = require('path');
const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace("px", ""));
@@ -272,7 +273,12 @@ export class DocumentOptions {
treeViewHideTitle?: boolean; // whether to hide the top document title of a tree view
treeViewHideHeader?: boolean; // whether to hide the header for a document in a tree view
treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items.
- treeViewShowClearButton?: boolean; // whether a clear button should be displayed
+
+ // Action Button
+ buttonMenu?: boolean; // whether a action button should be displayed
+ buttonMenuDoc?: Doc;
+ explainer?:string;
+
treeViewOpenIsTransient?: boolean; // ignores the treeViewOpen Doc flag, allowing a treeViewItem's expand/collapse state to be independent of other views of the same document in the same or any other tree view
_treeViewOpen?: boolean; // whether this document is expanded in a tree view (note: need _ and regular versions since this can be specified for both proto and layout docs)
treeViewOpen?: boolean; // whether this document is expanded in a tree view
@@ -1165,7 +1171,7 @@ export namespace DocUtils {
export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false): void {
!simpleMenu && ContextMenu.Instance.addItem({
- description: "Add Note ...",
+ description: "Quick Notes",
subitems: DocListCast((Doc.UserDoc()["template-notes"] as Doc).data).map((note, i) => ({
description: ":" + StrCast(note.title),
event: undoBatch((args: { x: number, y: number }) => {
@@ -1178,12 +1184,12 @@ export namespace DocUtils {
textDoc[textDoc.layoutKey] = note;
docTextAdder(textDoc);
}),
- icon: "eye"
+ icon: StrCast(note.icon) as IconProp
})) as ContextMenuProps[],
- icon: "eye"
+ icon: "sticky-note"
});
- ContextMenu.Instance.addItem({
- description: ":=math", event: () => {
+ const math:ContextMenuProps = ({
+ description: ":Math", event: () => {
const created = Docs.Create.EquationDocument();
if (created) {
created.author = Doc.CurrentUserEmail;
@@ -1194,25 +1200,27 @@ export namespace DocUtils {
EquationBox.SelectOnLoad = created[Id];
docAdder?.(created);
}
- }, icon: "compress-arrows-alt"
+ }, icon: "calculator"
});
+ const documentList:ContextMenuProps[] = DocListCast(Cast(Doc.UserDoc().myItemCreators, Doc, null)?.data).filter(btnDoc => !btnDoc.hidden).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc && doc !== Doc.UserDoc().emptyPresentation).map((dragDoc, i) => ({
+ description: ":" + StrCast(dragDoc.title),
+ event: undoBatch((args: { x: number, y: number }) => {
+ const newDoc = Doc.copyDragFactory(dragDoc);
+ if (newDoc) {
+ newDoc.author = Doc.CurrentUserEmail;
+ newDoc.x = x;
+ newDoc.y = y;
+ if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id];
+ docAdder?.(newDoc);
+ }
+ }),
+ icon: Doc.toIcon(dragDoc),
+ })) as ContextMenuProps[];
+ documentList.push(math)
ContextMenu.Instance.addItem({
description: "Create document",
- subitems: DocListCast(Cast(Doc.UserDoc().myItemCreators, Doc, null)?.data).filter(btnDoc => !btnDoc.hidden).map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null)).filter(doc => doc && doc !== Doc.UserDoc().emptyPresentation).map((dragDoc, i) => ({
- description: ":" + StrCast(dragDoc.title),
- event: undoBatch((args: { x: number, y: number }) => {
- const newDoc = Doc.copyDragFactory(dragDoc);
- if (newDoc) {
- newDoc.author = Doc.CurrentUserEmail;
- newDoc.x = x;
- newDoc.y = y;
- if (newDoc.type === DocumentType.RTF) FormattedTextBox.SelectOnLoad = newDoc[Id];
- docAdder?.(newDoc);
- }
- }),
- icon: Doc.toIcon(dragDoc),
- })) as ContextMenuProps[],
- icon: "eye"
+ subitems: documentList,
+ icon: "file"
});
}// applies a custom template to a document. the template is identified by it's short name (e.g, slideView not layout_slideView)
export function makeCustomViewClicked(doc: Doc, creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, templateSignature: string = "custom", docLayoutTemplate?: Doc) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index f12ac02f3..f6ec74482 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -84,7 +84,7 @@ export class CurrentUserUtils {
title: "NEW MOBILE BUTTON",
onClick: undefined,
},
- [this.ficon({
+ [this.createToolButton({
ignoreClick: true,
icon: "mobile",
btnType: ButtonType.ToolButton,
@@ -92,7 +92,7 @@ export class CurrentUserUtils {
}),
this.mobileTextContainer({},
[this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]);
- doc["template-mobile-button"] = CurrentUserUtils.ficon({
+ doc["template-mobile-button"] = CurrentUserUtils.createToolButton({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
dragFactory: new PrefetchProxy(queryTemplate) as any as Doc, title: "mobile button", icon: "mobile", btnType: ButtonType.ToolButton,
});
@@ -107,7 +107,7 @@ export class CurrentUserUtils {
{ _width: 400, _height: 300, title: "slideView", _xMargin: 3, _yMargin: 3, system: true }
);
slideTemplate.isTemplateDoc = makeTemplate(slideTemplate);
- doc["template-button-slides"] = CurrentUserUtils.ficon({
+ doc["template-button-slides"] = CurrentUserUtils.createToolButton({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
dragFactory: new PrefetchProxy(slideTemplate) as any as Doc, title: "presentation slide", icon: "address-card",
btnType: ButtonType.ToolButton
@@ -154,7 +154,7 @@ export class CurrentUserUtils {
};
linkTemplate.header = new RichTextField(JSON.stringify(rtf2), "");
- doc["template-button-link"] = CurrentUserUtils.ficon({
+ doc["template-button-link"] = CurrentUserUtils.createToolButton({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
dragFactory: new PrefetchProxy(linkTemplate) as any as Doc, title: "link view", icon: "window-maximize", system: true,
btnType: ButtonType.ToolButton
@@ -186,7 +186,7 @@ export class CurrentUserUtils {
const box = MulticolumnDocument([/*no, */ yes, name], { title: "value", _width: 120, _height: 35, system: true });
box.isTemplateDoc = makeTemplate(box, true, "switch");
- doc["template-button-switch"] = CurrentUserUtils.ficon({
+ doc["template-button-switch"] = CurrentUserUtils.createToolButton({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
dragFactory: new PrefetchProxy(box) as any as Doc, title: "data switch", icon: "toggle-on", system: true,
btnType: ButtonType.ToolButton
@@ -236,7 +236,7 @@ export class CurrentUserUtils {
short.title = "A Short Description";
long.title = "Long Description";
- doc["template-button-detail"] = CurrentUserUtils.ficon({
+ doc["template-button-detail"] = CurrentUserUtils.createToolButton({
onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
dragFactory: new PrefetchProxy(detailView) as any as Doc,
title: "detailView",
@@ -275,7 +275,7 @@ export class CurrentUserUtils {
static setupNoteTemplates(doc: Doc) {
if (doc["template-note-Note"] === undefined) {
const noteView = Docs.Create.TextDocument("", {
- title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true,
+ title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true, icon: "sticky-note",
_fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
});
noteView.isTemplateDoc = makeTemplate(noteView, true, "Note");
@@ -283,7 +283,7 @@ export class CurrentUserUtils {
}
if (doc["template-note-Idea"] === undefined) {
const noteView = Docs.Create.TextDocument("", {
- title: "text", backgroundColor: "pink", system: true,
+ title: "text", backgroundColor: "pink", system: true, icon: "lightbulb",
_fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
});
noteView.isTemplateDoc = makeTemplate(noteView, true, "Idea");
@@ -291,7 +291,7 @@ export class CurrentUserUtils {
}
if (doc["template-note-Topic"] === undefined) {
const noteView = Docs.Create.TextDocument("", {
- title: "text", backgroundColor: "lightblue", system: true,
+ title: "text", backgroundColor: "lightblue", system: true, icon: "book-open",
_fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
});
noteView.isTemplateDoc = makeTemplate(noteView, true, "Topic");
@@ -467,7 +467,7 @@ export class CurrentUserUtils {
((doc.emptyHeader as Doc).proto as Doc)["dragFactory-count"] = 0;
}
if (doc.emptyComparison === undefined) {
- doc.emptyComparison = Docs.Create.ComparisonDocument({ title: "compare", _width: 300, _height: 300, system: true, cloneFieldFilter: new List<string>(["system"]) });
+ doc.emptyComparison = Docs.Create.ComparisonDocument({ title: "comparison box", _width: 300, _height: 300, system: true, cloneFieldFilter: new List<string>(["system"]) });
}
if (doc.emptyScript === undefined) {
doc.emptyScript = Docs.Create.ScriptingDocument(undefined, { _width: 200, _height: 250, title: "script", system: true, cloneFieldFilter: new List<string>(["system"]) });
@@ -512,7 +512,7 @@ export class CurrentUserUtils {
{ toolTip: "Tap to create a progressive slide", title: "Slide", icon: "file", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptySlide as Doc },
{ toolTip: "Tap to create a cat image in a new pane, drag for a cat image", title: "Image", icon: "cat", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyImage as Doc },
{ toolTip: "Tap to create a comparison box in a new pane, drag for a comparison box", title: "Compare", icon: "columns", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyComparison as Doc, noviceMode: true },
- { toolTip: "Tap to create a screen grabber in a new pane, drag for a screen grabber", title: "Grab", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScreenshot as Doc, noviceMode: true },
+ { toolTip: "Tap to create a screen grabber in a new pane, drag for a screen grabber", title: "Grab", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScreenshot as Doc },
{ toolTip: "Tap to create a videoWall", title: "Wall", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyWall as Doc },
{ toolTip: "Tap to create an audio recorder in a new pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true },
{ toolTip: "Tap to create a button in a new pane, drag for a button", title: "Button", icon: "bolt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyButton as Doc },
@@ -561,7 +561,7 @@ export class CurrentUserUtils {
if (dragCreatorSet === undefined) {
doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, {
title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, _chromeHidden: true,
- _forceActive: true, _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true,
+ _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 40, ignoreClick: true, _lockedPosition: true,
dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true
}));
} else {
@@ -574,29 +574,31 @@ export class CurrentUserUtils {
return [
{ title: "Dashboards", target: Cast(doc.myDashboards, Doc, null), icon: "desktop", click: 'selectMainMenu(self)' },
{ title: "Search", target: Cast(doc.mySearchPanel, Doc, null), icon: "search", click: 'selectMainMenu(self)' },
- { title: "My Files", target: Cast(doc.myFilesystem, Doc, null), icon: "file", click: 'selectMainMenu(self)' },
- { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' },
- { title: "Import", target: Cast(doc.myImportDocs, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
+ { title: "File Manager", target: Cast(doc.myFilesystem, Doc, null), icon: "folder-open", click: 'selectMainMenu(self)' },
+ { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" },
+ { title: "Uploads", target: Cast(doc.myUploadDocs, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
{ title: "Recently Closed", target: Cast(doc.myRecentlyClosedDocs, Doc, null), icon: "archive", click: 'selectMainMenu(self)' },
{ title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc },
{ title: "Trails", target: Cast(doc.myTrails, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' },
- { title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)' },
+ { title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)', hidden: "IsNoviceMode()" },
];
}
static async setupMenuPanel(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) {
if (doc.menuStack === undefined) {
await this.setupSharingSidebar(doc, sharingDocumentId, linkDatabaseId); // sets up the right sidebar collection for mobile upload documents and sharing
- const menuBtns = (await CurrentUserUtils.menuBtnDescriptions(doc)).map(({ title, target, icon, click, watchedDocuments }) =>
+ const menuBtns = (await CurrentUserUtils.menuBtnDescriptions(doc)).map(({ title, target, icon, click, watchedDocuments, hidden }) =>
Docs.Create.FontIconDocument({
icon,
btnType: ButtonType.MenuButton,
_stayInCollection: true,
_hideContextMenu: true,
+ _chromeHidden: true,
system: true,
dontUndo: true,
title,
target,
+ hidden: hidden ? ComputedField.MakeFunction("IsNoviceMode()") as any : undefined,
_dropAction: "alias",
_removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
_width: 60,
@@ -611,8 +613,6 @@ export class CurrentUserUtils {
this.searchBtn = menuBtn;
}
});
- // hack -- last button is assumed to be the userDoc
- menuBtns[menuBtns.length - 1].hidden = ComputedField.MakeFunction("IsNoviceMode()");
menuBtns.forEach(menuBtn => {
if (menuBtn.title === "Search") {
@@ -684,7 +684,7 @@ export class CurrentUserUtils {
onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
backgroundColor: data.backgroundColor, system: true
},
- [this.ficon({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true, btnType: ButtonType.ClickButton, }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
+ [this.createToolButton({ ignoreClick: true, icon: data.icon, backgroundColor: "rgba(0,0,0,0)", system: true, btnType: ButtonType.ClickButton, }), this.mobileTextContainer({}, [this.mobileButtonText({}, data.title), this.mobileButtonInfo({}, data.info)])])
);
}
@@ -820,6 +820,7 @@ export class CurrentUserUtils {
const removeDashboard = ScriptField.MakeScript('removeDashboard(self)');
(doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, shareDashboard!, removeDashboard!]);
(doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Share Dashboard", "Remove Dashboard"]);
+ (doc.myDashboards as any as Doc).childContextMenuIcons = new List<string>(["plus", "share", "times"]);
// (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, toggleTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]);
// (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]);
}
@@ -860,18 +861,21 @@ export class CurrentUserUtils {
}
static setupRecentlyClosedDocs(doc: Doc) {
- // setup Recently Closed library item
if (doc.myRecentlyClosedDocs === undefined) {
- const clearDocs = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript(`getProto(self).data = new List([])`), toolTip: "Empty", _stayInCollection: true, _hideContextMenu: true, title: "Empty", btnType: ButtonType.TextButton, _width: 200, buttonText: "Empty Recently Closed", icon: "trash", system: true });
- doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([clearDocs], {
- title: "My Recently Closed", _showTitle: "title", treeViewShowClearButton: true, childHideLinkButton: true,
+ const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`);
+ const clearDocsButton:Doc = Docs.Create.FontIconDocument({ onClick: clearAll, _forceActive: true, toolTip: "Empty recently closed", _stayInCollection: true, _hideContextMenu: true, title: "Empty", btnType: ButtonType.ClickButton, _width: 30, _height: 30, buttonText: "Empty", icon: "trash", system: true });
+ doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([], {
+ title: "My Recently Closed", _showTitle: "title", buttonMenu: true, buttonMenuDoc: clearDocsButton, childHideLinkButton: true,
treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
treeViewTruncateTitleWidth: 150, ignoreClick: true,
- _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true
+ _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true,
+ explainer: "Documents that you close will appear here so you can easily access them again. You can choose to clear this menu in which case you might lose these documents."
+
}));
- const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`);
(doc.myRecentlyClosedDocs as any as Doc).contextMenuScripts = new List<ScriptField>([clearAll!]);
- (doc.myRecentlyClosedDocs as any as Doc).contextMenuLabels = new List<string>(["Clear All"]);
+ (doc.myRecentlyClosedDocs as any as Doc).contextMenuLabels = new List<string>(["Empty recently closed"]);
+ (doc.myRecentlyClosedDocs as any as Doc).contextMenuIcons = new List<string>(["trash"]);
+
}
}
@@ -916,7 +920,7 @@ export class CurrentUserUtils {
static async setupSidebarButtons(doc: Doc) {
CurrentUserUtils.setupSidebarContainer(doc);
await CurrentUserUtils.setupToolsBtnPanel(doc);
- CurrentUserUtils.setupImportSidebar(doc);
+ CurrentUserUtils.setupUploadSidebar(doc);
CurrentUserUtils.setupDashboards(doc);
CurrentUserUtils.setupPresentations(doc);
CurrentUserUtils.setupFilesystem(doc);
@@ -930,17 +934,17 @@ export class CurrentUserUtils {
_lockedPosition: true, system: true, flexDirection: "row"
})) as any as Doc
- static ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({
- ...opts, _dropAction: "alias", _removeDropProperties: new List<string>(["_dropAction", "stayInCollection"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true
+ static createToolButton = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({
+ ...opts, btnType: ButtonType.ToolButton, _forceActive: true, _dropAction: "alias", _removeDropProperties: new List<string>(["_dropAction", "stayInCollection"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40, system: true
})) as any as Doc
/// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
static setupDockedButtons(doc: Doc) {
if (doc["dockedBtn-undo"] === undefined) {
- doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to undo", title: "undo", icon: "undo-alt", system: true });
+ doc["dockedBtn-undo"] = CurrentUserUtils.createToolButton({ onClick: ScriptField.MakeScript("undo()"), _width: 30, _height: 30, dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to undo", title: "undo", icon: "undo-alt", system: true });
}
if (doc["dockedBtn-redo"] === undefined) {
- doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to redo", title: "redo", icon: "redo-alt", system: true });
+ doc["dockedBtn-redo"] = CurrentUserUtils.createToolButton({ onClick: ScriptField.MakeScript("redo()"), _width: 30, _height: 30, dontUndo: true, _stayInCollection: true, btnType: ButtonType.ToolButton, _dropAction: "alias", _hideContextMenu: true, _removeDropProperties: new List<string>(["dropAction", "_hideContextMenu", "stayInCollection"]), toolTip: "Click to redo", title: "redo", icon: "redo-alt", system: true });
}
if (doc.dockedBtns === undefined) {
doc.dockedBtns = CurrentUserUtils.linearButtonList({ title: "docked buttons", _height: 40, flexGap: 0, linearViewFloating: true, linearViewIsExpanded: true, linearViewExpandable: true, ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc]);
@@ -1039,7 +1043,7 @@ export class CurrentUserUtils {
// { title: "Alias", btnType: ButtonType.ClickButton, icon: "copy", hidden: 'selectedDocumentType()' }, // Only when a document is selected
{ title: "Text", type: "textTools", subMenu: true, expanded: 'selectedDocumentType("rtf")' }, // Always available
{ title: "Ink", type: "inkTools", subMenu: true, expanded: 'selectedDocumentType("ink")' }, // Always available
- // { title: "Web", type: "webTools", subMenu: true, hidden: 'selectedDocumentType("web")' }, // Only when Web is selected
+ { title: "Web", type: "webTools", subMenu: true, hidden: 'selectedDocumentType("web")' }, // Only when Web is selected
{ title: "Schema", type: "schemaTools", subMenu: true, hidden: 'selectedDocumentType(undefined, "schema")' } // Only when Schema is selected
];
}
@@ -1172,13 +1176,15 @@ export class CurrentUserUtils {
}
doc.myLinkDatabase = new PrefetchProxy(linkDocs);
}
+ // TODO:glr NOTE: treeViewHideTitle & _showTitle may be confusing, treeViewHideTitle is for the editable title (just for tree view), _showTitle is to show the Document title for any document
if (doc.mySharedDocs === undefined) {
let sharedDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(sharingDocumentId + "outer");
if (!sharedDocs) {
sharedDocs = Docs.Create.TreeDocument([], {
title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 50, _gridGap: 15,
- _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment,
+ _showTitle: "title", treeViewHideTitle: true, ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment,
_chromeHidden: true, boxShadow: "0 0",
+ explainer: "All of the documents that you receive will appear here. They must be shared by other users. If you receive a Dashboard you can add it to your Dashboards by right clicking and clicking 'Add to Dashboards'"
}, sharingDocumentId + "outer", sharingDocumentId);
(sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Augment;
}
@@ -1189,18 +1195,21 @@ export class CurrentUserUtils {
sharedDocs.childContextMenuFilters = new List<ScriptField>([dashboardFilter!,]);
sharedDocs.childContextMenuScripts = new List<ScriptField>([addToDashboards!,]);
sharedDocs.childContextMenuLabels = new List<string>(["Add to Dashboards",]);
+ sharedDocs.childContextMenuIcons = new List<string>(["user-plus",]);
+
}
doc.mySharedDocs = new PrefetchProxy(sharedDocs);
}
}
// Import sidebar is where shared documents are contained
- static setupImportSidebar(doc: Doc) {
- if (doc.myImportDocs === undefined) {
- const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Upload from computer", _width: 100, _stayInCollection: true, _hideContextMenu: true, title: "Upload", btnType: ButtonType.TextButton, buttonText: "Upload from computer", icon: "upload", system: true });
- doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([newUpload], {
- title: "My Uploads", _forceActive: true, ignoreClick: true, _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
- childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true,
+ static setupUploadSidebar(doc: Doc) {
+ if (doc.myUploadDocs === undefined) {
+ const newUploadButton:Doc = Docs.Create.FontIconDocument({ onClick: ScriptField.MakeScript("importDocument()"), _forceActive: true, toolTip: "Upload from computer", _width: 30, _height: 30, _stayInCollection: true, _hideContextMenu: true, title: "Upload", btnType: ButtonType.ClickButton, buttonText: "Upload", icon: "upload", system: true });
+ doc.myUploadDocs = new PrefetchProxy(Docs.Create.StackingDocument([], {
+ title: "My Uploads", _forceActive: true, buttonMenu: true, buttonMenuDoc: newUploadButton, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
+ childDropAction: "copy", _autoHeight: true, _yMargin: 50, _gridGap: 15, boxShadow: "0 0", _lockedPosition: true, system: true, _chromeHidden: true,
+ explainer: "All of the documents that are imported into Dash will go here and stay here unless they are explicitly removed."
}));
}
}
@@ -1303,7 +1312,7 @@ export class CurrentUserUtils {
doc.filterDocCount = 0;
this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon
this.setupDocTemplates(doc); // sets up the template menu of templates
- this.setupImportSidebar(doc); // sets up the import sidebar
+ this.setupUploadSidebar(doc); // sets up the import sidebar
this.setupSearchSidebar(doc); // sets up the search sidebar
this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
this.setupOverlays(doc); // documents in overlay layer
@@ -1430,7 +1439,7 @@ export class CurrentUserUtils {
}
}
} else if (input.files && input.files.length !== 0) {
- const importDocs = Cast(Doc.UserDoc().myImportDocs, Doc, null);
+ const importDocs = Cast(Doc.UserDoc().myUploadDocs, Doc, null);
const disposer = OverlayView.ShowSpinner();
DocListCastAsync(importDocs.data).then(async list => {
const results = await DocUtils.uploadFilesToDocs(Array.from(input.files || []), {});
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index 41a6dc569..47ae0424b 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -130,7 +130,7 @@
}
.contextMenu-inlineMenu {
- border-top: solid 1px;
+ // border-top: solid 1px; //TODO:glr clean
}
.contextMenu-item:hover {
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 168fcb888..c3921d846 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -116,12 +116,12 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
style={{ alignItems: where, borderTop: this.props.addDivider ? "solid 1px" : undefined }}
onMouseLeave={this.onPointerLeave} onMouseEnter={this.onPointerEnter}>
{this.props.icon ? (
- <span className="icon-background" onMouseEnter={this.onPointerLeave} style={{ alignItems: "center" }}>
+ <span className="icon-background" onMouseEnter={this.onPointerLeave} style={{ alignItems: "center", alignSelf: "center" }}>
<FontAwesomeIcon icon={this.props.icon} size="sm" />
</span>
) : null}
<div className="contextMenu-description" onMouseEnter={this.onPointerEnter}
- style={{ alignItems: "center" }} >
+ style={{ alignItems: "center", alignSelf: "center" }} >
{this.props.description}
<FontAwesomeIcon icon={"angle-right"} size="lg" style={{ position: "absolute", right: "10px" }} />
</div>
diff --git a/src/client/views/MainViewModal.scss b/src/client/views/MainViewModal.scss
index 03cb5cc84..0648e31c5 100644
--- a/src/client/views/MainViewModal.scss
+++ b/src/client/views/MainViewModal.scss
@@ -6,6 +6,7 @@
height: 100%;
.dialogue-box {
+ padding: 10px;
position: absolute;
z-index: 1000;
text-align: center;
@@ -13,7 +14,7 @@
align-self: center;
align-content: center;
background: white;
- border-radius: 10px;
+ // border-radius: 10px;
box-shadow: #00000044 5px 5px 10px;
transform: translate(-50%, -50%);
top: 50%;
diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
index 484522bc7..77686a710 100644
--- a/src/client/views/PropertiesButtons.scss
+++ b/src/client/views/PropertiesButtons.scss
@@ -67,10 +67,12 @@ $linkGap : 3px;
}
.onClickFlyout-editScript {
+ cursor: pointer;
text-align: center;
- border: 0.5px solid grey;
+ margin-top: 5px;
+ border: 0.5px solid $medium-gray;
background-color: rgb(230, 230, 230);
- border-radius: 9px;
+ border-radius: 5px;
padding: 4px;
}
@@ -84,9 +86,32 @@ $linkGap : 3px;
margin-bottom: 8px;
}
+.propertiesButton-dropdownList {
+ width: 100%;
+ height: fit-content;
+ top: 100%;
+ z-index: 21;
+
+ .list-item {
+ cursor: pointer;
+ color: $black;
+ width: 100%;
+ height: 25px;
+ font-weight: 400;
+ display: flex;
+ justify-content: left;
+ align-items: center;
+ padding-left: 5px;
+ }
+
+ .list-item:hover {
+ background-color: lightgrey;
+ }
+}
+
.propertiesButtons-title {
- background: #121721;
- color: white;
+ background: $dark-gray;
+ color: $white;
font-size: 6px;
width: 37px;
padding: 3px;
@@ -111,17 +136,11 @@ $linkGap : 3px;
margin-left: 4px;
&:hover {
- background: $medium-gray;
- transform: scale(1.05);
+ filter:brightness(0.85);
cursor: pointer;
}
}
-.propertiesButtons-linker:hover {
- cursor: pointer;
- transform: scale(1.05);
-}
-
@-moz-keyframes spin {
100% {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index dcab9bc1e..4fde1124f 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -15,6 +15,7 @@ import { InkingStroke } from './InkingStroke';
import { DocumentView } from './nodes/DocumentView';
import './PropertiesButtons.scss';
import React = require("react");
+import { Colors } from "./global/globalEnums";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -128,11 +129,11 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@undoBatch
@action
- handleOptionChange = (e: any) => {
- this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value);
+ handleOptionChange = (onClick: string) => {
+ this.selectedDoc && (this.selectedDoc.onClickBehavior = onClick);
SelectionManager.Views().filter(dv => dv.docView).map(dv => dv.docView!).forEach(docView => {
docView.noOnClick();
- switch (e.target.value) {
+ switch (onClick) {
case "enterPortal": docView.makeIntoPortal(); break;
case "toggleDetail": docView.setToggleDetail(); break;
case "linkInPlace": docView.toggleFollowLink("inPlace", true, false); break;
@@ -149,20 +150,34 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@computed
get onClickFlyout() {
- const makeLabel = (value: string, label: string) => <div className="radio">
- <label>
- <input type="radio" value={value} checked={(this.selectedDoc?.onClickBehavior ?? "nothing") === value} onChange={this.handleOptionChange} />
- {label}
- </label>
- </div>;
+ const buttonList = [
+ ["nothing", "Select Document"],
+ ["enterPortal", "Enter Portal"],
+ ["toggleDetail", "Toggle Detail"],
+ ["linkInPlace", "Follow Link"],
+ ["linkOnRight", "Open Link on Right"]
+ ]
+ const currentSelection = this.selectedDoc.onClickBehavior;
+ // Get items to place into the list
+
+ const list = buttonList.map((value) => {
+ const click = () => {
+ this.handleOptionChange(value[0]);
+ };
+ return <div className="list-item" key={`${value}`}
+ style={{
+ backgroundColor: value[0] === currentSelection ? Colors.LIGHT_BLUE : undefined
+ }}
+ onClick={click}>
+ {value[1]}
+ </div>;
+ });
return <div>
- <form>
- {makeLabel("nothing", "Select Document")}
- {makeLabel("enterPortal", "Enter Portal")}
- {makeLabel("toggleDetail", "Toggle Detail")}
- {makeLabel("linkInPlace", "Follow Link")}
- {makeLabel("linkOnRight", "Open Link on Right")}
- </form>
+ <div>
+ <div className="propertiesButton-dropdownList">
+ {list}
+ </div>
+ </div>
{Doc.UserDoc().noviceMode ? (null) : <div onPointerDown={this.editOnClickScript} className="onClickFlyout-editScript"> Edit onClick Script</div>}
</div>;
}
@@ -190,7 +205,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
const isFreeForm = this.selectedDoc?._viewType === CollectionViewType.Freeform;
const isTree = this.selectedDoc?._viewType === CollectionViewType.Tree;
const toggle = (ele: JSX.Element | null, style?: React.CSSProperties) => <div className="propertiesButtons-button" style={style}> {ele} </div>;
-
+ const isNovice = Doc.UserDoc().noviceMode;
return !this.selectedDoc ? (null) :
<div className="propertiesButtons">
{toggle(this.titleButton)}
@@ -198,7 +213,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{toggle(this.lockButton)}
{toggle(this.dictationButton)}
{toggle(this.onClickButton)}
- {toggle(this.fitWidthButton)}
+ {toggle(this.fitWidthButton, { display: isNovice ? "none" : "" })}
{toggle(this.fitContentButton, { display: !isFreeForm ? "none" : "" })}
{toggle(this.autoHeightButton, { display: !isText && !isStacking && !isTree ? "none" : "" })}
{toggle(this.maskButton, { display: !isInk ? "none" : "" })}
@@ -207,7 +222,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{toggle(this.snapButton, { display: isCollection ? "" : "none" })}
{toggle(this.clustersButton, { display: !isFreeForm ? "none" : "" })}
{toggle(this.panButton, { display: !isFreeForm ? "none" : "" })}
- {toggle(this.perspectiveButton, { display: !isCollection ? "none" : "" })}
+ {toggle(this.perspectiveButton, { display: !isCollection || isNovice ? "none" : "" })}
</div>;
}
} \ No newline at end of file
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
index 0e3663f65..01b79ffd2 100644
--- a/src/client/views/SidebarAnnos.tsx
+++ b/src/client/views/SidebarAnnos.tsx
@@ -106,9 +106,10 @@ export class SidebarAnnos extends React.Component<FieldViewProps & ExtraProps> {
{user}
</div>;
};
+ // TODO: Calculation of the topbar is hardcoded and different for text nodes - it should all be the same and all be part of SidebarAnnos
return !this.props.showSidebar ? (null) :
<div style={{
- position: "absolute", pointerEvents: this.props.isContentActive() ? "all" : undefined, top: 0, right: 0,
+ position: "absolute", pointerEvents: this.props.isContentActive() ? "all" : undefined, top: this.props.rootDoc.type !== DocumentType.RTF && StrCast(this.props.rootDoc._showTitle) === "title" ? 15 : 0, right: 0,
background: this.props.styleProvider?.(this.props.rootDoc, this.props, StyleProp.WidgetColor),
width: `${this.panelWidth()}px`,
height: "100%"
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index fa35081bc..e528e84e3 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -89,7 +89,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
switch (property.split(":")[0]) {
case StyleProp.TreeViewIcon: return Doc.toIcon(doc, isOpen);
case StyleProp.DocContents: return undefined;
- case StyleProp.WidgetColor: return isAnnotated ? "lightBlue" : darkScheme() ? "lightgrey" : "dimgrey";
+ case StyleProp.WidgetColor: return isAnnotated ? Colors.LIGHT_BLUE : darkScheme() ? "lightgrey" : "dimgrey";
case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null));
case StyleProp.HideLinkButton: return props?.hideLinkButton || (!selected && (doc?.isLinkButton || doc?.hideLinkButton));
case StyleProp.FontSize: return StrCast(doc?.[fieldKey + "fontSize"]);
@@ -108,7 +108,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
case StyleProp.TitleHeight: return 15;
case StyleProp.BorderPath: return comicStyle() && props?.renderDepth ? { path: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0), fill: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0, .08), width: 3 } : { path: undefined, width: 0 };
case StyleProp.JitterRotation: return comicStyle() ? random(-1, 1, NumCast(doc?.x), NumCast(doc?.y)) * ((props?.PanelWidth() || 0) > (props?.PanelHeight() || 0) ? 5 : 10) : 0;
- case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) ||
+ case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) ||
doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0;
case StyleProp.BackgroundColor: {
if (MainView.Instance.LastButton === doc) return Colors.LIGHT_GRAY;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 6bdeaf722..6a22acae8 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -338,7 +338,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
{this.renderColors(this._col)}
<div className="collectionSchema-headerMenu-group">
<button onClick={() => { this.deleteColumn(this._col.heading); }}
- >Delete Column</button>
+ >Hide Column</button>
</div>
</div>;
}
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 4b123c8b6..2f002736d 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -14,6 +14,30 @@
width: 100%;
}
+// TODO:glr Turn this into a seperate class
+.documentButtonMenu {
+ position: relative;
+ height: fit-content;
+ border-bottom: $standard-border;
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ align-items: center;
+ align-content: center;
+ padding: 5px 0 5px 0;
+
+ .documentExplanation {
+ width: 90%;
+ margin: 5px;
+ font-size: 11px;
+ background-color: $light-blue;
+ color: $medium-blue;
+ padding: 10px;
+ border-radius: 10px;
+ border: solid 2px $medium-blue;
+ }
+}
+
.collectionStackingView,
.collectionMasonryView {
height: 100%;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 4fedda1bd..3c9084f64 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -3,7 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { CursorProperty } from "csstype";
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { DataSym, Doc, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { DataSym, Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../fields/Doc";
import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { List } from "../../../fields/List";
@@ -11,7 +11,7 @@ import { listSpec, makeInterface } from "../../../fields/Schema";
import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils";
+import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents, smoothScroll, Utils, returnTrue, returnEmptyDoclist, returnEmptyFilter } from "../../../Utils";
import { DocUtils, Docs } from "../../documents/Documents";
import { DragManager, dropActionType } from "../../util/DragManager";
import { SnappingManager } from "../../util/SnappingManager";
@@ -23,12 +23,14 @@ import { EditableView } from "../EditableView";
import { LightboxView } from "../LightboxView";
import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from "../nodes/DocumentView";
-import { StyleProp } from "../StyleProvider";
+import { StyleProp, DefaultStyleProvider } from "../StyleProvider";
import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
import "./CollectionStackingView.scss";
import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn";
import { CollectionSubView } from "./CollectionSubView";
import { CollectionViewType } from "./CollectionView";
+import { FontIconBox } from "../nodes/button/FontIconBox";
+import { CurrentUserUtils } from "../../util/CurrentUserUtils";
const _global = (window /* browser */ || global /* node */) as any;
type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>;
@@ -514,6 +516,47 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
return sections.map((section, i) => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1], i === 0));
}
+ @computed get buttonMenu() {
+ const menuDoc:Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null);
+ // TODO:glr Allow support for multiple buttons
+ if (menuDoc){
+ const width: number = NumCast(menuDoc._width, 30);
+ const height: number = NumCast(menuDoc._height, 30);
+ console.log(menuDoc.title, width, height);
+ return (<div className="buttonMenu-docBtn"
+ style = {{width: width, height: height}}>
+ <DocumentView
+ Document={menuDoc}
+ DataDoc={menuDoc}
+ isContentActive={this.props.isContentActive}
+ isDocumentActive={returnTrue}
+ addDocument={this.props.addDocument}
+ moveDocument={this.props.moveDocument}
+ addDocTab={this.props.addDocTab}
+ pinToPres={emptyFunction}
+ rootSelected={this.props.isSelected}
+ removeDocument={this.props.removeDocument}
+ ScreenToLocalTransform={Transform.Identity}
+ PanelWidth={() => 35}
+ PanelHeight={() => 35}
+ renderDepth={this.props.renderDepth}
+ focus={emptyFunction}
+ styleProvider={this.props.styleProvider}
+ layerProvider={this.props.layerProvider}
+ docViewPath={returnEmptyDoclist}
+ whenChildContentsActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ docFilters={this.props.docFilters}
+ docRangeFilters={this.props.docRangeFilters}
+ searchFilterDocs={this.props.searchFilterDocs}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ />
+ </div>
+ );
+ }
+ }
+
@computed get nativeWidth() { return this.props.NativeWidth?.() ?? Doc.NativeWidth(this.layoutDoc); }
@computed get nativeHeight() { return this.props.NativeHeight?.() ?? Doc.NativeHeight(this.layoutDoc); }
@@ -529,34 +572,50 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
SetValue: this.addGroup,
contents: "+ ADD A GROUP"
};
+ const buttonMenu = this.rootDoc.buttonMenu;
+ const noviceExplainer = this.rootDoc.explainer;
+ console.log(noviceExplainer);
return (
- <div className="collectionStackingMasonry-cont" >
- <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
- ref={this.createRef}
- style={{
- overflowY: this.props.isContentActive() ? "auto" : "hidden",
- background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor),
- pointerEvents: this.backgroundEvents ? "all" : undefined
- }}
- onScroll={action(e => this._scroll = e.currentTarget.scrollTop)}
- onDrop={this.onExternalDrop.bind(this)}
- onContextMenu={this.onContextMenu}
- onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} >
- {this.renderedSections}
- {!this.showAddAGroup ? (null) :
- <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
- style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
- <EditableView {...editableViewProps} />
- </div>}
- {/* {this.chromeHidden || !this.props.isSelected() ? (null) :
- <Switch
- onChange={this.onToggle}
- onClick={this.onToggle}
- defaultChecked={true}
- checkedChildren="edit"
- unCheckedChildren="view"
- />} */}
- </div> </div>
+ <>
+ {buttonMenu || noviceExplainer ? <div className="documentButtonMenu">
+ {buttonMenu ? this.buttonMenu : null}
+ {Doc.UserDoc().isNovice && noviceExplainer ?
+ <div className="documentExplanation">
+ {noviceExplainer}
+ </div>
+ : null
+ }
+ </div> : null}
+ <div className="collectionStackingMasonry-cont" >
+ <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
+ ref={this.createRef}
+ style={{
+ overflowY: this.props.isContentActive() ? "auto" : "hidden",
+ background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor),
+ pointerEvents: this.backgroundEvents ? "all" : undefined
+ }}
+ onScroll={action(e => this._scroll = e.currentTarget.scrollTop)}
+ onDrop={this.onExternalDrop.bind(this)}
+ onContextMenu={this.onContextMenu}
+ onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} >
+ {this.renderedSections}
+ {!this.showAddAGroup ? (null) :
+ <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
+ style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
+ <EditableView {...editableViewProps} />
+ </div>}
+ {/* {this.chromeHidden || !this.props.isSelected() ? (null) :
+ <Switch
+ onChange={this.onToggle}
+ onClick={this.onToggle}
+ defaultChecked={true}
+ checkedChildren="edit"
+ unCheckedChildren="view"
+ />} */}
+ </div>
+ </div>
+ </>
+
);
}
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 89d42439e..4d62a1af4 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -8,7 +8,7 @@ import { Document, listSpec } from '../../../fields/Schema';
import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
+import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, emptyFunction } from '../../../Utils';
import { DocUtils } from '../../documents/Documents';
import { CurrentUserUtils } from '../../util/CurrentUserUtils';
import { DocumentManager } from '../../util/DocumentManager';
@@ -26,6 +26,7 @@ import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import { TreeView } from "./TreeView";
import React = require("react");
+import { Transform } from '../../util/Transform';
const _global = (window /* browser */ || global /* node */) as any;
export type collectionTreeViewProps = {
@@ -221,8 +222,9 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
}
childContextMenuItems = () => {
const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []);
- const filterScripts = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []);
- return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: filterScripts[i], label }));
+ const customFilters = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []);
+ const icons = StrListCast(this.doc.childContextMenuIcons);
+ return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label }));
}
@computed get treeViewElements() {
TraceMobx();
@@ -265,13 +267,48 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
return hideTitle ? (null) : (this.outlineMode ? this.documentTitle : this.editableTitle)(this.treeChildren);
}
- @computed get renderClearButton() {
- return !this.doc.treeViewShowClearButton ? (null) : <div key="toolbar">
- <button className="toolbar-button round-button" title="Empty" onClick={undoBatch(action(() => Doc.GetProto(this.doc)[this.props.fieldKey] = undefined))}>
- <FontAwesomeIcon icon={"trash"} size="sm" />
- </button>
- </div >;
+ @computed get buttonMenu() {
+ const menuDoc:Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null);
+ // To create a multibutton menu add a CollectionLinearView
+ if (menuDoc){
+
+ const width: number = NumCast(menuDoc._width, 30);
+ const height: number = NumCast(menuDoc._height, 30);
+ console.log(menuDoc.title, width, height);
+ return (<div className="buttonMenu-docBtn"
+ style = {{width: width, height: height}}>
+ <DocumentView
+ Document={menuDoc}
+ DataDoc={menuDoc}
+ isContentActive={this.props.isContentActive}
+ isDocumentActive={returnTrue}
+ addDocument={this.props.addDocument}
+ moveDocument={this.props.moveDocument}
+ addDocTab={this.props.addDocTab}
+ pinToPres={emptyFunction}
+ rootSelected={this.props.isSelected}
+ removeDocument={this.props.removeDocument}
+ ScreenToLocalTransform={Transform.Identity}
+ PanelWidth={() => 35}
+ PanelHeight={() => 35}
+ renderDepth={this.props.renderDepth + 1}
+ focus={emptyFunction}
+ styleProvider={this.props.styleProvider}
+ layerProvider={this.props.layerProvider}
+ docViewPath={returnEmptyDoclist}
+ whenChildContentsActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ docFilters={this.props.docFilters}
+ docRangeFilters={this.props.docRangeFilters}
+ searchFilterDocs={this.props.searchFilterDocs}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ />
+ </div>);
+ }
}
+
+
@computed get nativeWidth() { return Doc.NativeWidth(this.Document, undefined, true); }
@computed get nativeHeight() { return Doc.NativeHeight(this.Document, undefined, true); }
@@ -295,22 +332,34 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
TraceMobx();
const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor);
const pointerEvents = () => !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined;
+ const buttonMenu = this.rootDoc.buttonMenu;
+ const noviceExplainer = this.rootDoc.explainer;
return !(this.doc instanceof Doc) || !this.treeChildren ? (null) :
- <div className="collectionTreeView-container"
- style={this.outlineMode ? { transform: `scale(${this.contentScaling})`, width: `calc(${100 / this.contentScaling}%)` } : {}}
- onContextMenu={this.onContextMenu}>
- <div className="collectionTreeView-dropTarget"
- style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingBottom: `${this.paddingBot()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }}
- onWheel={e => e.stopPropagation()}
- onDrop={this.onTreeDrop}
- ref={this.createTreeDropTarget}>
+ <>
{this.titleBar}
- {this.renderClearButton}
- <ul className={`no-indent${this.outlineMode ? "-outline" : ""}`} >
- {this.treeViewElements}
- </ul>
- </div >
- </div>;
+ <div className="collectionTreeView-container"
+ style={this.outlineMode ? { transform: `scale(${this.contentScaling})`, width: `calc(${100 / this.contentScaling}%)` } : {}}
+ onContextMenu={this.onContextMenu}>
+ {buttonMenu || noviceExplainer ? <div className="documentButtonMenu">
+ {buttonMenu ? this.buttonMenu : null}
+ {Doc.UserDoc().noviceMode && noviceExplainer ?
+ <div className="documentExplanation">
+ {noviceExplainer}
+ </div>
+ : null
+ }
+ </div> : null}
+ <div className="collectionTreeView-dropTarget"
+ style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingBottom: `${this.paddingBot()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }}
+ onWheel={e => e.stopPropagation()}
+ onDrop={this.onTreeDrop}
+ ref={this.createTreeDropTarget}>
+ <ul className={`no-indent${this.outlineMode ? "-outline" : ""}`} >
+ {this.treeViewElements}
+ </ul>
+ </div >
+ </div>
+ </>;
}
} \ No newline at end of file
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 889db1ef6..34cb6ec55 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -387,9 +387,10 @@ export class TabDocView extends React.Component<TabDocViewProps> {
background={this.miniMapColor}
document={this._document}
tabView={this.tabView} />
- <Tooltip style={{ display: this.disableMinimap() ? "none" : undefined }} key="ttip" title={<div className="dash-tooltip">{this._document.hideMinimap ? "Open minimap" : "Close minimap"}</div>}>
+ <Tooltip key="ttip" title={<div className="dash-tooltip">{this._document.hideMinimap ? "Open minimap" : "Close minimap"}</div>}>
<div className="miniMap-hidden"
style={{
+ display: this.disableMinimap() || this._document._viewType !== "freeform" ? "none" : undefined,
color: this._document.hideMinimap ? Colors.BLACK : Colors.WHITE,
backgroundColor: this._document.hideMinimap ? Colors.LIGHT_GRAY : Colors.MEDIUM_BLUE,
boxShadow: this._document.hideMinimap ? Shadows.STANDARD_SHADOW : undefined
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index b9487054b..8cf34ddcc 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -525,7 +525,8 @@ export class TreeView extends React.Component<TreeViewProps> {
childContextMenuItems = () => {
const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []);
const customFilters = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []);
- return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], label }));
+ const icons = StrListCast(this.doc.childContextMenuIcons);
+ return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], icon: icons[i], label }));
}
onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
@@ -835,7 +836,7 @@ export class TreeView extends React.Component<TreeViewProps> {
dontRegisterView: boolean | undefined,
observerHeight: (ref: any) => void,
unobserveHeight: (ref: any) => void,
- contextMenuItems: ({ script: ScriptField, filter: ScriptField, label: string }[])
+ contextMenuItems: ({ script: ScriptField, filter: ScriptField, label: string, icon: string }[])
) {
const viewSpecScript = Cast(conainerCollection.viewSpecScript, ScriptField);
if (viewSpecScript) {
diff --git a/src/client/views/collections/collectionLinearView/CollectionLinearView.scss b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss
index f249eb1f5..8fe804466 100644
--- a/src/client/views/collections/collectionLinearView/CollectionLinearView.scss
+++ b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss
@@ -98,7 +98,11 @@
transition: transform 0.2s;
align-items: center;
justify-content: center;
- transition: 0.15s;
+ transition: 0.2s;
+
+ &:hover{
+ filter: brightness(0.85);
+ }
}
>input {
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
index b28c32e0e..a25f962df 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
@@ -191,7 +191,7 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
{this.renderSorting()}
{this.renderColors()}
<div className="collectionSchema-headerMenu-group">
- <button onClick={() => this.props.deleteColumn(this.props.columnField.heading)}>Delete Column</button>
+ <button onClick={() => this.props.deleteColumn(this.props.columnField.heading)}>Hide Column</button>
</div>
</>
}
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index fed64b620..dfe99ffc8 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -338,7 +338,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
{this.renderColors(this._col)}
<div className="collectionSchema-headerMenu-group">
<button onClick={() => { this.deleteColumn(this._col.heading); }}
- >Delete Column</button>
+ >Hide Column</button>
</div>
</div>;
}
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index f5a7e61aa..8962d29f0 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -638,12 +638,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
</div>
</div>
) : (
- <button
+ <div
className={`audiobox-record${interactive}`}
style={{ backgroundColor: Colors.DARK_GRAY }}
>
RECORD
- </button>
+ </div>
)}
</div>
) : (
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7463e192f..98ae279db 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -635,7 +635,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
makeIntoPortal = async () => {
const portalLink = this.allLinks.find(d => d.anchor1 === this.props.Document);
if (!portalLink) {
- const portal = Docs.Create.FreeformDocument([], { _width: NumCast(this.layoutDoc._width) + 10, _height: NumCast(this.layoutDoc._height), _fitWidth: true, title: StrCast(this.props.Document.title) + ".portal" });
+ const portal = Docs.Create.FreeformDocument([], { _width: NumCast(this.layoutDoc._width) + 10, _height: NumCast(this.layoutDoc._height), _fitWidth: true, title: StrCast(this.props.Document.title) + " [Portal]" });
DocUtils.MakeLink({ doc: this.props.Document }, { doc: portal }, "portal to");
}
this.Document.followLinkLocation = "inPlace";
@@ -679,7 +679,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
const appearance = cm.findByDescription("UI Controls...");
const appearanceItems: ContextMenuProps[] = appearance && "subitems" in appearance ? appearance.subitems : [];
!Doc.UserDoc().noviceMode && templateDoc && appearanceItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "add:right"), icon: "eye" });
- appearanceItems.push({
+ !Doc.UserDoc().noviceMode && appearanceItems.push({
description: "Add a Field", event: () => {
const alias = Doc.MakeAlias(this.rootDoc);
alias.layout = FormattedTextBox.LayoutString("newfield");
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 72dec6e4c..f44355929 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -1,3 +1,5 @@
+@import "../global/globalCssVariables.scss";
+
.pdfBox,
.pdfBox-interactive {
display: inline-block;
@@ -18,12 +20,13 @@
top: 0;
left: 0;
+ // glr: This should really be the same component as text and PDFs
.pdfBox-sidebarBtn {
- background: #121721;
+ background: $black;
height: 25px;
width: 25px;
- right: 0;
- color: white;
+ right: 5px;
+ color: $white;
display: flex;
position: absolute;
align-items: center;
@@ -31,6 +34,13 @@
border-radius: 3px;
pointer-events: all;
z-index: 1; // so it appears on top of the document's title, if shown
+
+ box-shadow: $standard-box-shadow;
+ transition: 0.2s;
+
+ &:hover{
+ filter: brightness(0.85);
+ }
}
.pdfBox-pageNums {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 5e07229c1..3a399bfdb 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -24,6 +24,7 @@ import { pageSchema } from "./ImageBox";
import "./PDFBox.scss";
import React = require("react");
import { AnchorMenu } from '../pdf/AnchorMenu';
+import { Colors } from '../global/globalEnums';
type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>;
const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema);
@@ -208,11 +209,15 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
onClick={action(() => this._pageControls = !this._pageControls)} />
{this._pageControls ? pageBtns : (null)}
</div>
- <button className="pdfBox-sidebarBtn" title="Toggle Sidebar"
- style={{ display: !this.props.isContentActive() ? "none" : undefined }}
+ <div className="pdfBox-sidebarBtn" key="sidebar" title="Toggle Sidebar"
+ style={{
+ display: !this.props.isContentActive() ? "none" : undefined,
+ top: StrCast(this.rootDoc._showTitle) === "title" ? 20 : 5,
+ backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK
+ }}
onPointerDown={this.sidebarBtnDown} >
- <FontAwesomeIcon icon={"chevron-left"} size="sm" />
- </button>
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={"comment-alt"} size="sm" />
+ </div>
</div>;
}
sidebarWidth = () => !this.SidebarShown ? 0 :
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index 19b69ff5a..417a17d96 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -10,7 +10,7 @@
background: #121721;
height: 25px;
width: 25px;
- right: 0;
+ right: 5px;
display: flex;
position: absolute;
align-items: center;
@@ -18,6 +18,13 @@
border-radius: 3px;
pointer-events: all;
z-index: 1; // so it appears on top of the document's title, if shown
+
+ box-shadow: $standard-box-shadow;
+ transition: 0.2s;
+
+ &:hover{
+ filter: brightness(0.85);
+ }
}
.pdfViewerDash-dragAnnotationBox {
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 719e5a796..1f85219d6 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -33,6 +33,7 @@ import { FieldView, FieldViewProps } from './FieldView';
import { LinkDocPreview } from "./LinkDocPreview";
import "./WebBox.scss";
import React = require("react");
+import { Colors } from "../global/globalEnums";
const _global = (window /* browser */ || global /* node */) as any;
const htmlToText = require("html-to-text");
@@ -590,11 +591,15 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
moveDocument={this.moveDocument}
removeDocument={this.removeDocument}
/>
- <button className="webBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar"
- style={{ display: !this.props.isContentActive() ? "none" : undefined }}
+ <div className="webBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar"
+ style={{
+ display: !this.props.isContentActive() ? "none" : undefined,
+ top: StrCast(this.rootDoc._showTitle) === "title" ? 20 : 5,
+ backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK
+ }}
onPointerDown={this.sidebarBtnDown} >
- <FontAwesomeIcon style={{ color: "white" }} icon={"chevron-left"} size="sm" />
- </button>
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={"comment-alt"} size="sm" />
+ </div>
</div>);
}
}
diff --git a/src/client/views/nodes/button/FontIconBox.scss b/src/client/views/nodes/button/FontIconBox.scss
index 48fb2c8dc..a2da35fe1 100644
--- a/src/client/views/nodes/button/FontIconBox.scss
+++ b/src/client/views/nodes/button/FontIconBox.scss
@@ -7,6 +7,7 @@
align-items: center;
font-size: 80%;
border-radius: $standard-border-radius;
+ transition: 0.15s;
.menuButton-wrap {
grid-column: 1;
@@ -29,6 +30,9 @@
font-family: 'ROBOTO';
text-transform: uppercase;
font-weight: bold;
+ transition: 0.15s;
+
+
}
.fontIconBox-icon {
@@ -50,7 +54,18 @@
}
&.textBtn {
+ display: grid;
+ /* grid-row: auto; */
+ grid-auto-flow: column;
+ cursor: pointer;
width: 100%;
+ justify-content: center;
+ align-items: center;
+ justify-items: center;
+
+ &:hover {
+ filter:brightness(0.85) !important;
+ }
}
&.tglBtn {
@@ -127,13 +142,13 @@
}
&:hover {
- background-color: rgba(0, 0, 0, 0.3) !important;
+ background-color: rgba(0, 0, 0, 0.3);
}
}
&.toolBtn {
cursor: pointer;
- width: 40px;
+ width: 100%;
border-radius: 100%;
svg {
@@ -143,7 +158,7 @@
}
&.menuBtn {
- cursor: pointer;
+ cursor: pointer !important;
border-radius: 0px;
flex-direction: column;
@@ -151,6 +166,10 @@
width: 45% !important;
height: 45%;
}
+
+ &:hover{
+ filter: brightness(0.85);
+ }
}
@@ -163,8 +182,8 @@
.colorButton-color {
margin-top: 3px;
- width: 90%;
- height: 6px;
+ width: 80%;
+ height: 3px;
}
.menuButton-dropdownBox {
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index bccf733f0..1b27d562a 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -253,11 +253,12 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
} else if (selected) {
dropdown = false;
text = StrCast(selected.Document.type);
+ if (text === DocumentType.RTF) text = "Text";
icon = Doc.toIcon(selected.Document);
} else {
dropdown = false;
- noneSelected = true;
- text = "None selected";
+ icon = "globe-asia";
+ text = "User Default";
}
noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
} else if (script === 'setFont') {
@@ -302,7 +303,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
<div className={`menuButton ${this.type} ${active}`}
style={{ backgroundColor: this.rootDoc.dropDownOpen ? Colors.MEDIUM_BLUE : backgroundColor, color: color, display: dropdown ? undefined : "flex" }}
onClick={dropdown ? () => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen : undefined}>
- {dropdown || noneSelected ? (null) : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
+ {dropdown || noneSelected ? (null) : <FontAwesomeIcon style={{marginLeft: 5}} className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
<div className="menuButton-dropdown-header">
{text && text[0].toUpperCase() + text.slice(1)}
</div>
@@ -487,7 +488,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
</div>;
const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) :
- <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}>
+ <div className="fontIconBox-label" style={{ color: color, backgroundColor: "transparent" }}>
{this.label}
</div>;
@@ -508,7 +509,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
switch (this.type) {
case ButtonType.TextButton:
button = (
- <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor, opacity: 1 }}>
+ <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor, opacity: 1, gridAutoColumns: `${NumCast(this.rootDoc._height)} auto` }}>
<FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
{buttonText ?
<div className="button-text">
@@ -558,7 +559,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
break;
case ButtonType.MenuButton:
const trailsIcon = <img src={`/assets/${"presTrails.png"}`}
- style={{ width: 20, height: 20, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})` }} />;
+ style={{ width: 30, height: 30, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})` }} />;
button = (
<div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor }}>
{this.icon === "pres-trail" ? trailsIcon : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />}
@@ -605,7 +606,7 @@ Scripting.addGlobal(function setBackgroundColor(color?: string, checkResult?: bo
Scripting.addGlobal(function toggleOverlay(checkResult?: boolean) {
const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
if (checkResult && selected) {
- if (NumCast(selected.Document.z) === 1) return Colors.MEDIUM_BLUE;
+ if (NumCast(selected.Document.z) >= 1) return Colors.MEDIUM_BLUE;
else return "transparent";
}
selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed");
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 3cedab1a4..56f5c5631 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -66,14 +66,25 @@ audiotag:hover {
.formattedTextBox-sidebar-handle {
position: absolute;
- top: 0;
+ top: 5px;
//top: calc(50% - 17.5px); // use this to center vertically -- make sure it looks okay for slide views
- width: 10px;
+ width: 25px;
height: 100%;
- max-height: 35px;
- background: lightgray;
- border-radius: 20px;
+ max-height: 25px;
+ color: white;
+ background: $medium-gray;
+ border-radius: 5px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
cursor:grabbing;
+ box-shadow: $standard-box-shadow;
+ // transition: 0.2s;
+
+ &:hover{
+ filter: brightness(0.85);
+ }
+
}
.formattedTextBox-sidebar,
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index f45b9de7a..468edf6cc 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -63,6 +63,8 @@ import { SummaryView } from "./SummaryView";
import applyDevTools = require("prosemirror-dev-tools");
import React = require("react");
import { SidebarAnnos } from '../../SidebarAnnos';
+import { Colors } from '../../global/globalEnums';
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
const translateGoogleApi = require("translate-google-api");
export interface FormattedTextBoxProps {
@@ -574,11 +576,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
changeItems.push({ description: "plain", event: undoBatch(() => Doc.setNativeView(this.rootDoc)), icon: "eye" });
const noteTypesDoc = Cast(Doc.UserDoc()["template-notes"], Doc, null);
DocListCast(noteTypesDoc?.data).forEach(note => {
+ const icon: IconProp = StrCast(note.icon) as IconProp;
changeItems.push({
description: StrCast(note.title), event: undoBatch(() => {
Doc.setNativeView(this.rootDoc);
DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.TreeDocument, StrCast(note.title), note);
- }), icon: "eye"
+ }), icon: icon
});
});
!Doc.UserDoc().noviceMode && changeItems.push({ description: "FreeForm", event: () => DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.FreeformDocument, "freeform"), icon: "eye" });
@@ -1481,11 +1484,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@computed get sidebarHandle() {
TraceMobx();
const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
+ const color = !annotated ? Colors.WHITE : Colors.BLACK;
+ const backgroundColor = !annotated ? this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK : this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : ""));
return (!annotated && !this.props.isContentActive()) ? (null) : <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
style={{
- left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${this.sidebarWidth() ? "- 5px" : "- 10px"}))`,
- background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : ""))
- }} />;
+ left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${"- 30px"}))`,
+ backgroundColor: backgroundColor,
+ color: color
+ }} >
+ <FontAwesomeIcon icon={"comment-alt"}/>
+ </div>;
}
@computed get sidebarCollection() {
const renderComponent = (tag: string) => {
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 260ddfc90..e70b2bc19 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -114,7 +114,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
const linkFrom = this.props.linkFrom();
if (linkFrom) {
console.log(linkFrom.title);
- DocUtils.MakeLink({ doc: linkFrom }, { doc: linkTo });
+ DocUtils.MakeLink({ doc: linkFrom }, { doc: linkTo }, "Link");
}
}
});
diff --git a/src/client/views/topbar/TopBar.scss b/src/client/views/topbar/TopBar.scss
index 05aeb177c..923f1892e 100644
--- a/src/client/views/topbar/TopBar.scss
+++ b/src/client/views/topbar/TopBar.scss
@@ -33,12 +33,12 @@
align-self: center;
border-radius: $standard-border-radius;
padding: 5px;
- transition: linear 0.1s;
+ transition: linear 0.2s;
color: $black;
background-color: $light-gray;
&:hover {
- background-color: $light-blue;
+ background-color: darken($color: $light-gray, $amount: 20);
}
}
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 4dbd5e22c..d5254e315 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -51,7 +51,8 @@ export class TopBar extends React.Component {
</div>
</div>
<div className="topbar-right" >
- <div className="topbar-icon">
+ <div className="topbar-icon" onClick={() => window.open(
+ "https://brown-dash.github.io/Dash-Documentation/", "_blank")}>
{"Help"}<FontAwesomeIcon icon="question-circle"></FontAwesomeIcon>
</div>
<div className="topbar-icon" onClick={() => SettingsManager.Instance.open()}>