aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>2023-07-17 23:11:35 -0400
committerGeireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>2023-07-17 23:11:35 -0400
commit54308259a8cd3ac98aaee550ea01ad97f17172e6 (patch)
treed3bd71ed669ac12eb6173a8a0632e5b276578d3b
parent241332557f10fa97718200821374755b68e4fe10 (diff)
so many updates
-rw-r--r--deploy/index.html7
-rw-r--r--deploy/loader.css5
-rw-r--r--package-lock.json232
-rw-r--r--package.json2
-rw-r--r--src/client/documents/Documents.ts6
-rw-r--r--src/client/util/CurrentUserUtils.ts63
-rw-r--r--src/client/util/DropConverter.ts2
-rw-r--r--src/client/util/ReportManager.tsx4
-rw-r--r--src/client/util/SettingsManager.scss93
-rw-r--r--src/client/util/SettingsManager.tsx186
-rw-r--r--src/client/views/AntimodeMenu.scss32
-rw-r--r--src/client/views/AntimodeMenu.tsx5
-rw-r--r--src/client/views/DashboardView.scss22
-rw-r--r--src/client/views/DashboardView.tsx98
-rw-r--r--src/client/views/EditableView.tsx75
-rw-r--r--src/client/views/GestureOverlay.tsx2
-rw-r--r--src/client/views/MainView.scss20
-rw-r--r--src/client/views/MainView.tsx13
-rw-r--r--src/client/views/MainViewModal.scss6
-rw-r--r--src/client/views/MainViewModal.tsx7
-rw-r--r--src/client/views/PropertiesButtons.scss8
-rw-r--r--src/client/views/PropertiesButtons.tsx98
-rw-r--r--src/client/views/PropertiesDocBacklinksSelector.scss2
-rw-r--r--src/client/views/PropertiesDocBacklinksSelector.tsx2
-rw-r--r--src/client/views/PropertiesDocContextSelector.tsx1
-rw-r--r--src/client/views/PropertiesSection.scss24
-rw-r--r--src/client/views/PropertiesSection.tsx51
-rw-r--r--src/client/views/PropertiesView.scss364
-rw-r--r--src/client/views/PropertiesView.tsx743
-rw-r--r--src/client/views/StyleProvider.tsx10
-rw-r--r--src/client/views/UndoStack.scss9
-rw-r--r--src/client/views/UndoStack.tsx48
-rw-r--r--src/client/views/collections/CollectionMenu.scss651
-rw-r--r--src/client/views/collections/CollectionMenu.tsx51
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx2
-rw-r--r--src/client/views/collections/TabDocView.scss17
-rw-r--r--src/client/views/collections/TabDocView.tsx103
-rw-r--r--src/client/views/collections/TreeView.scss36
-rw-r--r--src/client/views/collections/TreeView.tsx35
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx69
-rw-r--r--src/client/views/collections/collectionLinear/CollectionLinearView.tsx51
-rw-r--r--src/client/views/global/globalScripts.ts49
-rw-r--r--src/client/views/linking/LinkPopup.scss5
-rw-r--r--src/client/views/linking/LinkPopup.tsx4
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
-rw-r--r--src/client/views/nodes/FontIconBox/ButtonInterface.ts12
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBadge.scss11
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBadge.tsx37
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBox.scss (renamed from src/client/views/nodes/button/FontIconBox.scss)0
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBox.tsx (renamed from src/client/views/nodes/button/FontIconBox.tsx)77
-rw-r--r--src/client/views/pdf/AnchorMenu.tsx121
-rw-r--r--src/client/views/search/SearchBox.scss3
-rw-r--r--src/client/views/search/SearchBox.tsx7
-rw-r--r--src/client/views/selectedDoc/SelectedDocView.scss3
-rw-r--r--src/client/views/selectedDoc/SelectedDocView.tsx47
-rw-r--r--src/client/views/selectedDoc/index.ts1
-rw-r--r--src/client/views/topbar/TopBar.tsx36
58 files changed, 1481 insertions, 2193 deletions
diff --git a/deploy/index.html b/deploy/index.html
index f8003f126..c8ad2a8d4 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -5,7 +5,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
- href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&family=Lato:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Merriweather:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Roboto:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap"
+ href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&family=Lato:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Merriweather:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Roboto:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&family=Nunito:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;0,1000;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900;1,1000&family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap"
rel="stylesheet">
<link rel="shortcut icon" type="image/jpg" href="./assets/favicon.png" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
@@ -67,8 +67,9 @@
}
.dash-animation-container {
- width: 10vw;
- height: 10vw;
+ width: fit-content;
+ height: fit-content;
+ padding: 20px;
display: flex;
align-items: center;
justify-content: center;
diff --git a/deploy/loader.css b/deploy/loader.css
index 4be0cc98c..4d5e04d71 100644
--- a/deploy/loader.css
+++ b/deploy/loader.css
@@ -36,8 +36,9 @@
}
.dash-animation-container {
- width: 10vw;
- height: 10vw;
+ width: fit-content;
+ height: fit-content;
+ padding: 20px;
display: flex;
align-items: center;
justify-content: center;
diff --git a/package-lock.json b/package-lock.json
index 84c1e6219..215468914 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,36 +22,42 @@
}
},
"@babel/compat-data": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz",
- "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg=="
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
+ "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ=="
},
"@babel/core": {
- "version": "7.22.8",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.8.tgz",
- "integrity": "sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz",
+ "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==",
"requires": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.22.5",
- "@babel/generator": "^7.22.7",
- "@babel/helper-compilation-targets": "^7.22.6",
- "@babel/helper-module-transforms": "^7.22.5",
+ "@babel/generator": "^7.22.9",
+ "@babel/helper-compilation-targets": "^7.22.9",
+ "@babel/helper-module-transforms": "^7.22.9",
"@babel/helpers": "^7.22.6",
"@babel/parser": "^7.22.7",
"@babel/template": "^7.22.5",
"@babel/traverse": "^7.22.8",
"@babel/types": "^7.22.5",
- "@nicolo-ribaudo/semver-v6": "^6.3.3",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
- "json5": "^2.2.2"
+ "json5": "^2.2.2",
+ "semver": "^6.3.1"
},
"dependencies": {
- "@nicolo-ribaudo/semver-v6": {
- "version": "6.3.3",
- "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
- "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+ "@babel/generator": {
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz",
+ "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==",
+ "requires": {
+ "@babel/types": "^7.22.5",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ }
},
"debug": {
"version": "4.3.4",
@@ -70,6 +76,11 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
@@ -101,22 +112,17 @@
}
},
"@babel/helper-compilation-targets": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz",
- "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz",
+ "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==",
"requires": {
- "@babel/compat-data": "^7.22.6",
+ "@babel/compat-data": "^7.22.9",
"@babel/helper-validator-option": "^7.22.5",
- "@nicolo-ribaudo/semver-v6": "^6.3.3",
"browserslist": "^4.21.9",
- "lru-cache": "^5.1.1"
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
},
"dependencies": {
- "@nicolo-ribaudo/semver-v6": {
- "version": "6.3.3",
- "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
- "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
- },
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -125,6 +131,11 @@
"yallist": "^3.0.2"
}
},
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
+ },
"yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@@ -133,19 +144,19 @@
}
},
"@babel/helper-create-class-features-plugin": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.6.tgz",
- "integrity": "sha512-iwdzgtSiBxF6ni6mzVnZCF3xt5qE6cEA0J7nFt8QOAWZ0zjCFceEgpn3vtb2V7WFR6QzP2jmIFOHMTRo7eNJjQ==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz",
+ "integrity": "sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.22.5",
"@babel/helper-environment-visitor": "^7.22.5",
"@babel/helper-function-name": "^7.22.5",
"@babel/helper-member-expression-to-functions": "^7.22.5",
"@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.5",
+ "@babel/helper-replace-supers": "^7.22.9",
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
- "@nicolo-ribaudo/semver-v6": "^6.3.3"
+ "semver": "^6.3.1"
},
"dependencies": {
"@babel/helper-annotate-as-pure": {
@@ -156,21 +167,21 @@
"@babel/types": "^7.22.5"
}
},
- "@nicolo-ribaudo/semver-v6": {
- "version": "6.3.3",
- "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
- "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
"@babel/helper-create-regexp-features-plugin": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.6.tgz",
- "integrity": "sha512-nBookhLKxAWo/TUCmhnaEJyLz2dekjQvv5SRpE9epWQBcpedWLKt8aZdsuT9XV5ovzR3fENLjRXVT0GsSlGGhA==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz",
+ "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.22.5",
- "@nicolo-ribaudo/semver-v6": "^6.3.3",
- "regexpu-core": "^5.3.1"
+ "regexpu-core": "^5.3.1",
+ "semver": "^6.3.1"
},
"dependencies": {
"@babel/helper-annotate-as-pure": {
@@ -181,10 +192,10 @@
"@babel/types": "^7.22.5"
}
},
- "@nicolo-ribaudo/semver-v6": {
- "version": "6.3.3",
- "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
- "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
@@ -264,18 +275,15 @@
}
},
"@babel/helper-module-transforms": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz",
- "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz",
+ "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==",
"requires": {
"@babel/helper-environment-visitor": "^7.22.5",
"@babel/helper-module-imports": "^7.22.5",
"@babel/helper-simple-access": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.5",
- "@babel/template": "^7.22.5",
- "@babel/traverse": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-validator-identifier": "^7.22.5"
}
},
"@babel/helper-optimise-call-expression": {
@@ -292,14 +300,13 @@
"integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ=="
},
"@babel/helper-remap-async-to-generator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz",
- "integrity": "sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz",
+ "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.22.5",
"@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-wrap-function": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/helper-wrap-function": "^7.22.9"
},
"dependencies": {
"@babel/helper-annotate-as-pure": {
@@ -313,16 +320,13 @@
}
},
"@babel/helper-replace-supers": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz",
- "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz",
+ "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==",
"requires": {
"@babel/helper-environment-visitor": "^7.22.5",
"@babel/helper-member-expression-to-functions": "^7.22.5",
- "@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/template": "^7.22.5",
- "@babel/traverse": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/helper-optimise-call-expression": "^7.22.5"
}
},
"@babel/helper-simple-access": {
@@ -365,13 +369,12 @@
"integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw=="
},
"@babel/helper-wrap-function": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz",
- "integrity": "sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz",
+ "integrity": "sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==",
"requires": {
"@babel/helper-function-name": "^7.22.5",
"@babel/template": "^7.22.5",
- "@babel/traverse": "^7.22.5",
"@babel/types": "^7.22.5"
}
},
@@ -1472,12 +1475,12 @@
}
},
"@babel/plugin-transform-typescript": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.5.tgz",
- "integrity": "sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz",
+ "integrity": "sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-create-class-features-plugin": "^7.22.5",
+ "@babel/helper-create-class-features-plugin": "^7.22.9",
"@babel/helper-plugin-utils": "^7.22.5",
"@babel/plugin-syntax-typescript": "^7.22.5"
},
@@ -1561,12 +1564,12 @@
}
},
"@babel/preset-env": {
- "version": "7.22.7",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.7.tgz",
- "integrity": "sha512-1whfDtW+CzhETuzYXfcgZAh8/GFMeEbz0V5dVgya8YeJyCU6Y/P2Gnx4Qb3MylK68Zu9UiwUvbPMPTpFAOJ+sQ==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz",
+ "integrity": "sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==",
"requires": {
- "@babel/compat-data": "^7.22.6",
- "@babel/helper-compilation-targets": "^7.22.6",
+ "@babel/compat-data": "^7.22.9",
+ "@babel/helper-compilation-targets": "^7.22.9",
"@babel/helper-plugin-utils": "^7.22.5",
"@babel/helper-validator-option": "^7.22.5",
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5",
@@ -1640,11 +1643,11 @@
"@babel/plugin-transform-unicode-sets-regex": "^7.22.5",
"@babel/preset-modules": "^0.1.5",
"@babel/types": "^7.22.5",
- "@nicolo-ribaudo/semver-v6": "^6.3.3",
"babel-plugin-polyfill-corejs2": "^0.4.4",
"babel-plugin-polyfill-corejs3": "^0.8.2",
"babel-plugin-polyfill-regenerator": "^0.5.1",
- "core-js-compat": "^3.31.0"
+ "core-js-compat": "^3.31.0",
+ "semver": "^6.3.1"
},
"dependencies": {
"@babel/helper-plugin-utils": {
@@ -1652,10 +1655,10 @@
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
"integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
},
- "@nicolo-ribaudo/semver-v6": {
- "version": "6.3.3",
- "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
- "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
@@ -6195,9 +6198,9 @@
}
},
"browndash-components": {
- "version": "0.0.62",
- "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.62.tgz",
- "integrity": "sha512-lhIuqOylZF7y4ZQXOdTim2r8Et61AaUROl5UYaooCObHvjJb7WIGpFv9B1RQjlbg8vUJ4jeM3e3qb++Cf6ajPg==",
+ "version": "0.0.76",
+ "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.76.tgz",
+ "integrity": "sha512-2ZrDNGxbXnmqRSBifCn6+czz/LqeuyZwSsnRj73Wmo9OOKvYIneGZE17/aFkAl76rXdVmZCcfBdKKBcwEYwNHQ==",
"requires": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
@@ -6211,9 +6214,9 @@
},
"dependencies": {
"@babel/cli": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.22.6.tgz",
- "integrity": "sha512-Be3/RfEDmkMRGT1+ru5nTkfcvWz5jDOYg1V9rXqTz2u9Qt96O1ryboGvxVBp7wOnYWDB8DNHIWb6DThrpudfOw==",
+ "version": "7.22.9",
+ "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.22.9.tgz",
+ "integrity": "sha512-nb2O7AThqRo7/E53EGiuAkMaRbb7J5Qp3RvN+dmua1U+kydm0oznkhqbTEG15yk26G/C3yL6OdZjzgl+DMXVVA==",
"requires": {
"@jridgewell/trace-mapping": "^0.3.17",
"@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3",
@@ -6642,9 +6645,9 @@
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
},
"postcss": {
- "version": "8.4.25",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz",
- "integrity": "sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw==",
+ "version": "8.4.26",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz",
+ "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==",
"requires": {
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",
@@ -6676,9 +6679,9 @@
"integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A=="
},
"styled-components": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.3.tgz",
- "integrity": "sha512-qEyWvDK4CYCyDckNIruRJIcQSvcUR3dVEw/fwxu1v0LFzUMPr2uf5PhXHp17FkGK+S4TkglOS+XIealo1MssQA==",
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.4.tgz",
+ "integrity": "sha512-lRJt4vg8hKJhlVG+VKz8QEqPCXKyTryZZ59odyK0UC0HHV3u/mshWTfSay8NpkN0Xijw1iN9r0Leld3dcCcp/w==",
"requires": {
"@babel/cli": "^7.21.0",
"@babel/core": "^7.21.0",
@@ -8156,16 +8159,6 @@
"integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
"dev": true
},
- "d": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
- "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
- "dev": true,
- "requires": {
- "es5-ext": "^0.10.50",
- "type": "^1.0.1"
- }
- },
"d3": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz",
@@ -9546,28 +9539,6 @@
"is-symbol": "^1.0.2"
}
},
- "es5-ext": {
- "version": "0.10.62",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
- "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
- "dev": true,
- "requires": {
- "es6-iterator": "^2.0.3",
- "es6-symbol": "^3.1.3",
- "next-tick": "^1.1.0"
- }
- },
- "es6-iterator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
- "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
- "dev": true,
- "requires": {
- "d": "1",
- "es5-ext": "^0.10.35",
- "es6-symbol": "^3.1.1"
- }
- },
"es6-promise": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
@@ -9579,7 +9550,6 @@
"integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
"dev": true,
"requires": {
- "d": "^1.0.1",
"ext": "^1.1.2"
}
},
@@ -25311,12 +25281,6 @@
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
- "type": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
- "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
- "dev": true
- },
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
diff --git a/package.json b/package.json
index b137ddd67..e301268dd 100644
--- a/package.json
+++ b/package.json
@@ -177,7 +177,7 @@
"body-parser": "^1.19.2",
"bootstrap": "^4.6.1",
"brotli": "^1.3.3",
- "browndash-components": "0.0.62",
+ "browndash-components": "0.0.76",
"browser-assert": "^1.2.1",
"bson": "^4.6.1",
"canvas": "^2.9.3",
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 934803c16..c925cff0f 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -34,7 +34,7 @@ import { ContextMenuProps } from '../views/ContextMenuItem';
import { DFLT_IMAGE_NATIVE_DIM } from '../views/global/globalCssVariables.scss';
import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke } from '../views/InkingStroke';
import { AudioBox } from '../views/nodes/AudioBox';
-import { FontIconBox } from '../views/nodes/button/FontIconBox';
+import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
import { ColorBox } from '../views/nodes/ColorBox';
import { ComparisonBox } from '../views/nodes/ComparisonBox';
import { DataVizBox } from '../views/nodes/DataVizBox/DataVizBox';
@@ -324,8 +324,9 @@ export class DocumentOptions {
badgeValue?: ScriptField;
//LINEAR VIEW
- linearView_IsExpanded?: BOOLt = new BoolInfo('is linear view expanded');
+ linearView_IsOpen?: BOOLt = new BoolInfo('is linear view open');
linearView_Expandable?: BOOLt = new BoolInfo('can linear view be expanded');
+ linearView_Dropdown?: BOOLt = new BoolInfo('can linear view be opened as a dropdown');
linearView_SubMenu?: BOOLt = new BoolInfo('is doc a sub menu of more linear views');
flexGap?: NUMt = new NumInfo('Linear view flex gap');
flexDirection?: 'unset' | 'row' | 'column' | 'row-reverse' | 'column-reverse';
@@ -406,6 +407,7 @@ export class DocumentOptions {
clipboard?: Doc;
hoverBackgroundColor?: string; // background color of a label when hovered
+ userBackgroundColor?: STRt = new StrInfo('background color associated with a Dash user (seen in header fields of shared documents)');
userColor?: STRt = new StrInfo('color associated with a Dash user (seen in header fields of shared documents)');
}
export namespace Docs {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 32229f22f..cde3daf5a 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -12,7 +12,7 @@ import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types";
import { nullAudio } from "../../fields/URLField";
import { SetCachedGroups, SharingPermissions } from "../../fields/util";
import { GestureUtils } from "../../pen-gestures/GestureUtils";
-import { OmitKeys, Utils } from "../../Utils";
+import { OmitKeys, Utils, addStyleSheetRule } from "../../Utils";
import { DocServer } from "../DocServer";
import { Docs, DocumentOptions, DocUtils, FInfo } from "../documents/Documents";
import { CollectionViewType, DocumentType } from "../documents/DocumentTypes";
@@ -20,7 +20,7 @@ import { TreeViewType } from "../views/collections/CollectionTreeView";
import { DashboardView } from "../views/DashboardView";
import { Colors } from "../views/global/globalEnums";
import { MainView } from "../views/MainView";
-import { ButtonType } from "../views/nodes/button/FontIconBox";
+import { ButtonType } from "../views/nodes/FontIconBox/FontIconBox";
import { OpenWhere } from "../views/nodes/DocumentView";
import { OverlayView } from "../views/OverlayView";
import { DragManager, dropActionType } from "./DragManager";
@@ -28,7 +28,7 @@ import { MakeTemplate } from "./DropConverter";
import { FollowLinkScript } from "./LinkFollower";
import { LinkManager } from "./LinkManager";
import { ScriptingGlobals } from "./ScriptingGlobals";
-import { ColorScheme } from "./SettingsManager";
+import { ColorScheme, SettingsManager } from "./SettingsManager";
import { UndoManager } from "./UndoManager";
interface Button {
@@ -373,7 +373,7 @@ export class CurrentUserUtils {
});
const reqdStackOpts:DocumentOptions ={
- title: "menuItemPanel", childDragAction: "same", backgroundColor: Colors.DARK_GRAY, layout_boxShadow: "rgba(0,0,0,0)", dontRegisterView: true, ignoreClick: true,
+ title: "menuItemPanel", childDragAction: "same", layout_boxShadow: "rgba(0,0,0,0)", dontRegisterView: true, ignoreClick: true,
_chromeHidden: true, _gridGap: 0, _yMargin: 0, _yPadding: 0, _xMargin: 0, _layout_autoHeight: false, _width: 60, _columnWidth: 60, _lockedPosition: true, isSystem: true,
};
return DocUtils.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(items??[], opts), reqdStackOpts, menuBtns, { dropConverter: "convertToButtons(dragData)" });
@@ -609,7 +609,7 @@ export class CurrentUserUtils {
const btns = btnDescs.map(desc => dockBtn({_width: 30, _height: 30, defaultDoubleClick: 'ignore', undoIgnoreFields: new List<string>(['opacity']), _dragOnlyWithinContainer: true, ...desc.opts}, desc.scripts));
const dockBtnsReqdOpts:DocumentOptions = {
title: "docked buttons", _height: 40, flexGap: 0, layout_boxShadow: "standard", childDragAction: 'move',
- childDontRegisterViews: true, linearView_IsExpanded: true, linearView_Expandable: true, ignoreClick: true
+ childDontRegisterViews: true, linearView_IsOpen: true, linearView_Expandable: true, ignoreClick: true
};
reaction(() => UndoManager.redoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "Redo")!).opacity = UndoManager.CanRedo() ? 1 : 0.4, { fireImmediately: true });
reaction(() => UndoManager.undoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "Undo")!).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true });
@@ -625,12 +625,12 @@ export class CurrentUserUtils {
}
static viewTools(): Button[] {
return [
- { title: "Snap\xA0Lines", icon: "th", toolTip: "Show Snap Lines", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"snaplines", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
- { title: "Grid", icon: "border-all", toolTip: "Show Grid", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"grid", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
- { title: "View\xA0All", icon: "object-group", toolTip: "Fit all Docs to View",btnType: ButtonType.ToggleButton, expertMode: false, toolType:"viewAll", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
- { title: "Clusters", icon: "braille", toolTip: "Show Doc Clusters", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"clusters", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
- { title: "Cards", icon: "brain", toolTip: "Flashcards", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"flashcards", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
- { title: "Arrange",icon:"arrow-down-short-wide",toolTip:"Toggle Auto Arrange", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"arrange", funcs: {hidden: 'IsNoviceMode()'}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
+ { title: "Snap", icon: "th", toolTip: "Show Snap Lines", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"snaplines", funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+ { title: "Grid", icon: "border-all", toolTip: "Show Grid", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"grid", funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+ { title: "View All", icon: "object-group", toolTip: "Fit all Docs to View",btnType: ButtonType.ToggleButton, expertMode: false, toolType:"viewAll", funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+ { title: "Clusters", icon: "braille", toolTip: "Show Doc Clusters", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"clusters", funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+ { title: "Cards", icon: "brain", toolTip: "Flashcards", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"flashcards", funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+ { title: "Arrange",icon:"arrow-down-short-wide",toolTip:"Toggle Auto Arrange", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"arrange", funcs: {hidden: 'IsNoviceMode()'}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
]
}
static textTools():Button[] {
@@ -645,9 +645,13 @@ export class CurrentUserUtils {
{ title: "Under", toolTip: "Underline (Ctrl+U)", btnType: ButtonType.ToggleButton, icon: "underline", toolType:"underline", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
{ title: "Bullets", toolTip: "Bullet List", btnType: ButtonType.ToggleButton, icon: "list", toolType:"bullet", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
{ title: "#", toolTip: "Number List", btnType: ButtonType.ToggleButton, icon: "list-ol", toolType:"decimal", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
- { title: "Left", toolTip: "Left align (Cmd-[)", btnType: ButtonType.ToggleButton, icon: "align-left", toolType:"left", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}' }},
- { title: "Center", toolTip: "Center align (Cmd-\\)",btnType: ButtonType.ToggleButton, icon: "align-center",toolType:"center", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
- { title: "Right", toolTip: "Right align (Cmd-])", btnType: ButtonType.ToggleButton, icon: "align-right", toolType:"right", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
+ { title: "Alignment",toolTip: "Alignment", btnType: ButtonType.MultiToggleButton, toolType:"alignment", ignoreClick: true, scripts: {script: '{ return setFontAttr(self.toolType, value, _readOnly_);}'},
+ subMenu: [
+ { title: "Left", toolTip: "Left align (Cmd-[)", btnType: ButtonType.ToggleButton, icon: "align-left", toolType:"left", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}' }},
+ { title: "Center", toolTip: "Center align (Cmd-\\)",btnType: ButtonType.ToggleButton, icon: "align-center",toolType:"center", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
+ { title: "Right", toolTip: "Right align (Cmd-])", btnType: ButtonType.ToggleButton, icon: "align-right", toolType:"right", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
+ ]
+ },
{ title: "Dictate", toolTip: "Dictate", btnType: ButtonType.ToggleButton, icon: "microphone", toolType:"dictation", scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'}},
{ title: "NoLink", toolTip: "Auto Link", btnType: ButtonType.ToggleButton, icon: "link", toolType:"noAutoLink", expertMode:true, scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'}, funcs: {hidden: 'IsNoviceMode()'}},
// { title: "Strikethrough", tooltip: "Strikethrough", btnType: ButtonType.ToggleButton, icon: "strikethrough", scripts: {onClick:: 'toggleStrikethrough()'}},
@@ -695,17 +699,17 @@ export class CurrentUserUtils {
title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}},
{ title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}},
{ title: "Fill", icon: "fill-drip", toolTip: "Background Fill Color",btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, width: 30, scripts: { script: 'return setBackgroundColor(value, _readOnly_)'}}, // Only when a document is selected
- { title: "Header", icon: "heading", toolTip: "Header Color", btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'}},
- { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'}, scripts: { onClick: 'toggleOverlay(_readOnly_)'}}, // Only when floating document is selected in freeform
+ { title: "Header", icon: "heading", toolTip: "Header Color", btnType: ButtonType.ColorButton, expertMode: true, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'}},
+ { title: "Overlay", icon: "layer-group", toolTip: "Overlay", btnType: ButtonType.ToggleButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'}, scripts: { onClick: 'return { toggleOverlay(_readOnly_); }'}}, // Only when floating document is selected in freeform
{ title: "Back", icon: "chevron-left", toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'prevKeyFrame(_readOnly_)'}},
{ title: "Num", icon:"", toolTip: "Frame Number (click to toggle edit mode)", btnType: ButtonType.TextButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}},
{ title: "Fwd", icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton, expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30, scripts: { onClick: 'nextKeyFrame(_readOnly_)'}},
- { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
- { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: { linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
- { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
- { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
- { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected
- { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} } // Only when Schema is selected
+ { title: "Text", icon: "Text", toolTip: "Text functions", subMenu: CurrentUserUtils.textTools(), expertMode: false, toolType:DocumentType.RTF, funcs: { linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
+ { title: "Ink", icon: "Ink", toolTip: "Ink functions", subMenu: CurrentUserUtils.inkTools(), expertMode: false, toolType:DocumentType.INK, funcs: { linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
+ { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
+ { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
+ { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected
+ { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} } // Only when Schema is selected
];
}
@@ -713,7 +717,6 @@ export class CurrentUserUtils {
static setupContextMenuButton(params:Button, btnDoc?:Doc) {
const reqdOpts:DocumentOptions = {
...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit,
- backgroundColor: params.backgroundColor ??"transparent", /// a bit hacky. if an onClick is specified, then assume a toggle uses onClick to get the backgroundColor (see below). Otherwise, assume a transparent background
color: Colors.WHITE, isSystem: true,
_nativeWidth: params.width ?? 30, _width: params.width ?? 30,
_height: 30, _nativeHeight: 30, linearBtnWidth: params.linearBtnWidth,
@@ -722,21 +725,20 @@ export class CurrentUserUtils {
};
const reqdFuncs:{[key:string]:any} = {
...params.funcs,
- backgroundColor: params.btnType === ButtonType.ToggleButton ? params.scripts?.onClick:undefined /// a bit hacky. if onClick is set, then we assume it returns a color value when queried with '_readOnly_'. This will be true for toggle buttons, but not generally
}
return DocUtils.AssignScripts(DocUtils.AssignOpts(btnDoc, reqdOpts) ?? Docs.Create.FontIconDocument(reqdOpts), params.scripts, reqdFuncs);
}
/// Initializes all the default buttons for the top bar context menu
static setupContextMenuButtons(doc: Doc, field="myContextMenuBtns") {
- const reqdCtxtOpts:DocumentOptions = { title: "context menu buttons", undoIgnoreFields:new List<string>(['width', "linearView_IsExpanded"]), flexGap: 0, childDragAction: 'embed', childDontRegisterViews: true, linearView_IsExpanded: true, ignoreClick: true, linearView_Expandable: false, _height: 35 };
+ const reqdCtxtOpts:DocumentOptions = { title: "context menu buttons", undoIgnoreFields:new List<string>(['width', "linearView_IsOpen"]), flexGap: 0, childDragAction: 'embed', childDontRegisterViews: true, linearView_IsOpen: true, ignoreClick: true, linearView_Expandable: false, _height: 35 };
const ctxtMenuBtnsDoc = DocUtils.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), reqdCtxtOpts, undefined);
const ctxtMenuBtns = CurrentUserUtils.contextMenuTools().map(params => {
const menuBtnDoc = DocListCast(ctxtMenuBtnsDoc?.data).find(doc => doc.title === params.title);
- if (!params.subMenu) {
+ if (!params.subMenu) { // button does not have a sub menu
return this.setupContextMenuButton(params, menuBtnDoc);
- } else {
- const reqdSubMenuOpts = { ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, undoIgnoreFields: new List<string>(['width', "linearView_IsExpanded"]),
+ } else { // linear view
+ const reqdSubMenuOpts = { ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, undoIgnoreFields: new List<string>(['width', "linearView_IsOpen"]),
childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: params.scripts?.onClick ? false : true,
linearView_SubMenu: true, linearView_Expandable: true, };
const items = params.subMenu?.map(sub =>
@@ -847,6 +849,11 @@ export class CurrentUserUtils {
doc.fontHighlight ?? (doc.fontHighlight = "");
doc.defaultAclPrivate ?? (doc.defaultAclPrivate = false);
doc.savedFilters ?? (doc.savedFilters = new List<Doc>());
+ doc.userBackgroundColor ?? (doc.userBackgroundColor = Colors.DARK_GRAY);
+ addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${doc.userBackgroundColor} !important` });
+ doc.userVariantColor ?? (doc.userVariantColor = Colors.MEDIUM_BLUE);
+ doc.userColor ?? (doc.userColor = Colors.LIGHT_GRAY);
+ doc.userTheme ?? (doc.userTheme = ColorScheme.Dark);
doc.filterDocCount = 0;
doc.treeViewFreezeChildren = "remove|add";
this.setupLinkDocs(doc, linkDatabaseId);
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 47997cc5c..f235be192 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -9,7 +9,7 @@ import { RichTextField } from '../../fields/RichTextField';
import { ImageField } from '../../fields/URLField';
import { ScriptingGlobals } from './ScriptingGlobals';
import { listSpec } from '../../fields/Schema';
-import { ButtonType } from '../views/nodes/button/FontIconBox';
+import { ButtonType } from '../views/nodes/FontIconBox/FontIconBox';
export function MakeTemplate(doc: Doc, first: boolean = true, rename: Opt<string> = undefined, templateField: string = '') {
if (templateField) Doc.GetProto(doc).title = templateField; /// the title determines which field is being templated
diff --git a/src/client/util/ReportManager.tsx b/src/client/util/ReportManager.tsx
index 4c1020455..89c17e42f 100644
--- a/src/client/util/ReportManager.tsx
+++ b/src/client/util/ReportManager.tsx
@@ -11,7 +11,7 @@ import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager
import { DocServer } from '../DocServer';
import { Networking } from '../Network';
import { MainViewModal } from '../views/MainViewModal';
-import { FontIconBox } from '../views/nodes/button/FontIconBox';
+import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
import { DragManager } from './DragManager';
import { GroupManager } from './GroupManager';
import './SettingsManager.scss';
@@ -290,7 +290,7 @@ export class ReportManager extends React.Component<{}> {
isDisplayed={this.isOpen}
interactive={true}
closeOnExternalClick={this.close}
- dialogueBoxStyle={{ width: 'auto', height: '500px', background: Cast(Doc.SharingDoc().userColor, 'string', null) }}
+ dialogueBoxStyle={{ width: 'auto', height: '500px', background: Cast(Doc.UserDoc().userColor, 'string', null) }}
/>
);
}
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index c41adfdd7..bca649bc3 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -2,41 +2,20 @@
.settings-interface {
//background-color: whitesmoke !important;
- color: grey;
width: 450px;
-
- button {
- background: #315a96;
- outline: none;
- border-radius: 5px;
- border: 0px;
- color: #fcfbf7;
- text-transform: uppercase;
- letter-spacing: 2px;
- font-size: 75%;
- padding: 10px;
- margin: 10px;
- transition: transform 0.2s;
- margin: 2px;
- }
}
.settings-title {
font-size: 25px;
font-weight: bold;
padding-right: 10px;
- color: black;
}
.settings-username {
font-size: 12px;
padding-right: 15px;
- color: black;
margin-top: 10px;
margin-bottom: 10px;
- /* right: 135; */
- // position: absolute;
- // left: 243;
}
.settings-section {
@@ -49,7 +28,6 @@
font-size: 16;
font-weight: bold;
text-align: left;
- color: black;
width: 80;
margin-right: 50px;
}
@@ -61,45 +39,10 @@
.password-content {
display: flex;
+ width: 100%;
flex-direction: column;
align-items: flex-start;
-
- .password-content-inputs {
- display: flex;
- flex-direction: column;
- width: 100%;
- font-size: 10px;
- align-items: flex-start;
-
- .password-inputs {
- border: 1px solid rgb(160, 160, 160);
- margin-bottom: 15px;
- width: 130;
- color: $medium-gray;
- border-radius: 5px;
- padding: 7px;
- }
- }
-
- .password-content-buttons {
- display: flex;
- gap: 5px;
- justify-content: center;
- align-items: flex-start;
- flex-direction: column;
-
- .password-submit {
- //margin-left: 85px;
- margin-top: 5px;
- }
-
- .password-forgot {
- //margin-left: 65px;
- //margin-top: -20px;
- font-size: 12px;
- white-space: nowrap;
- }
- }
+ gap: 5px;
}
.accounts-content {
@@ -115,7 +58,6 @@
width: 80%;
height: 35px;
margin-right: 10px;
- color: black;
border-radius: 5px;
&:hover {
@@ -139,12 +81,6 @@
}
}
- .playground-text {
- color: black;
- margin-right: 10px;
- margin-top: 2;
- }
-
.acl-text {
color: black;
margin-top: 2;
@@ -176,7 +112,6 @@
.appearances-content {
display: flex;
- color: black;
font-size: 10px;
.preferences-color {
@@ -201,7 +136,6 @@
margin-top: 2px;
.preferences-font-text {
- color: black;
margin-top: 4;
margin-right: 4;
margin-bottom: 2px;
@@ -216,7 +150,6 @@
.font-select {
height: 35px;
- color: black;
font-size: 9;
margin-right: 6;
border-radius: 5px;
@@ -229,7 +162,6 @@
.size-select {
height: 35px;
- color: black;
font-size: 9;
border-radius: 5px;
width: 30%;
@@ -241,7 +173,6 @@
}
.preferences-check {
- color: black;
margin-right: 4;
margin-bottom: -3;
margin-left: 5;
@@ -265,7 +196,6 @@
.settings-content {
- background: #e4e4e4;
padding: 10px;
width: 500px;
flex: 1 1 auto;
@@ -296,7 +226,6 @@
}
h1 {
- color: #121721;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 19;
@@ -325,7 +254,6 @@
.padding {
padding: 0 0 0 20px;
- color: black;
}
}
}
@@ -336,16 +264,11 @@
min-height: 250px;
height: 100%;
width: 100%;
-
- .settings-content {
- background-color: $off-white;
- }
}
.settings-panel {
position: relative;
min-width: 150px;
- background-color: $light-blue;
.settings-user {
position: absolute;
@@ -370,16 +293,11 @@
.settings-tabs {
// font-size: 16px;
font-weight: 600;
- color: black;
.tab-control {
padding: 10px;
border-bottom: 1px solid #9f9e9e;
cursor: pointer;
-
- &.active {
- background-color: #fdfdfd;
- }
}
}
@@ -398,16 +316,18 @@
.tab-content {
display: flex;
+ flex-flow: row wrap;
+ gap: 10px;
+ overflow: hidden;
.tab-column {
- flex: 0 0 50%;
+ flex: 0 0 calc(50% - 10px);
flex-direction: column;
display: flex;
justify-content: flex-start;
align-items: flex-start;
.tab-column-title {
- color: $dark-gray;
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
@@ -420,6 +340,7 @@
align-items: flex-start;
flex-direction: column;
gap: 10px;
+ width: 100%;
}
}
}
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 09d6d034f..b6df5f26a 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -11,12 +11,12 @@ import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager
import { DocServer } from '../DocServer';
import { Networking } from '../Network';
import { MainViewModal } from '../views/MainViewModal';
-import { FontIconBox } from '../views/nodes/button/FontIconBox';
+import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
import { DragManager } from './DragManager';
import { GroupManager } from './GroupManager';
import './SettingsManager.scss';
import { undoBatch } from './UndoManager';
-import { Button, ColorPicker, Dropdown, DropdownType, Group, Size, Toggle, ToggleType, Type } from 'browndash-components';
+import { Button, ColorPicker, Dropdown, DropdownType, EditableText, Group, NumberDropdown, Size, Toggle, ToggleType, Type } from 'browndash-components';
import { BsGoogle } from 'react-icons/bs'
import { FaFillDrip, FaPalette } from 'react-icons/fa'
const higflyout = require('@hig/flyout');
@@ -24,9 +24,10 @@ export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
export enum ColorScheme {
- Dark = '-Dark',
- Light = '-Light',
- System = '-MatchSystem',
+ Dark = 'Dark',
+ Light = 'Light',
+ System = 'Match System',
+ Custom = 'Custom'
}
export enum freeformScrollMode {
@@ -53,8 +54,8 @@ export class SettingsManager extends React.Component<{}> {
@computed get backgroundColor() {
return Doc.UserDoc().activeCollectionBackground;
}
- @computed get colorScheme() {
- return Doc.ActiveDashboard?.colorScheme;
+ @computed get userTheme() {
+ return Doc.UserDoc().userTheme;
}
constructor(props: {}) {
@@ -76,14 +77,31 @@ export class SettingsManager extends React.Component<{}> {
}
};
+ @computed get userColor() {
+ return StrCast(Doc.UserDoc().userColor)
+ }
+
+ @computed get userVariantColor() {
+ return StrCast(Doc.UserDoc().userVariantColor)
+ }
+
+ @computed get userBackgroundColor() {
+ return StrCast(Doc.UserDoc().userBackgroundColor)
+ }
+
@undoBatch selectUserMode = action((mode: string) => (Doc.noviceMode = mode === 'Novice'));
@undoBatch changelayout_showTitle = action((e: React.ChangeEvent) => (Doc.UserDoc().layout_showTitle = (e.currentTarget as any).value ? 'title' : undefined));
@undoBatch changeFontFamily = action((font: string) => (Doc.UserDoc().fontFamily = font));
@undoBatch changeFontSize = action((val: number) => (Doc.UserDoc().fontSize = val));
- @undoBatch switchActiveBackgroundColor = action((color: string) => (Doc.UserDoc().activeCollectionBackground = color));
+ @undoBatch switchUserBackgroundColor = action((color: string) => {
+ Doc.UserDoc().userBackgroundColor = color;
+ addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${color} !important` });
+ });
@undoBatch switchUserColor = action((color: string) => {
- Doc.SharingDoc().userColor = undefined;
- Doc.GetProto(Doc.SharingDoc()).userColor = color;
+ Doc.UserDoc().userColor = color;
+ });
+ @undoBatch switchUserVariantColor = action((color: string) => {
+ Doc.UserDoc().userVariantColor = color;
});
@undoBatch playgroundModeToggle = action(() => {
this.playgroundMode = !this.playgroundMode;
@@ -96,22 +114,24 @@ export class SettingsManager extends React.Component<{}> {
@undoBatch
@action
changeColorScheme = action((scheme: string) => {
- const activeDashboard = Doc.ActiveDashboard;
- if (!activeDashboard) return;
+ Doc.UserDoc().userTheme = scheme;
switch (scheme) {
case ColorScheme.Light:
- activeDashboard.colorScheme = ColorScheme.Light
- addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: '#d3d3d3 !important' });
+ this.switchUserColor("#323232")
+ this.switchUserBackgroundColor("#DFDFDF")
+ this.switchUserVariantColor("#BDDDF5")
break;
case ColorScheme.Dark:
- activeDashboard.colorScheme = ColorScheme.Dark;
- addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: 'black !important' });
+ this.switchUserColor("#DFDFDF")
+ this.switchUserBackgroundColor("#323232")
+ this.switchUserVariantColor("#4476F7")
+ break;
+ case ColorScheme.Custom:
break;
case ColorScheme.System:
default:
- activeDashboard.colorScheme = ColorScheme.System;
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
- activeDashboard.colorScheme = e.matches ? ColorScheme.Dark : ColorScheme.Light; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
+ e.matches ? ColorScheme.Dark : ColorScheme.Light; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
});
break;
}
@@ -120,18 +140,16 @@ export class SettingsManager extends React.Component<{}> {
@computed get colorsContent() {
- const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.System];
- const schemeMap = ['Light', 'Dark', 'Match System'];
-
+ const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.Custom, ColorScheme.System];
+ const schemeMap = ['Light', 'Dark', 'Custom', 'Match System'];
+ const userTheme = StrCast(Doc.UserDoc().userTheme);
return (
- <div className="colors-content">
- <ColorPicker formLabel='Background Color' icon={<FaFillDrip/>} selectedColor={StrCast(Doc.UserDoc().activeCollectionBackground)} setSelectedColor={this.switchActiveBackgroundColor}/>
- <ColorPicker formLabel='User Color' icon={<FaPalette/>} selectedColor={StrCast(Doc.SharingDoc().userColor)} setSelectedColor={this.switchUserColor}/>
+ <div style={{width: '100%'}}>
<Dropdown
formLabel='Theme'
size={Size.SMALL}
type={Type.TERT}
- selectedVal={StrCast(Doc.ActiveDashboard?.colorScheme)}
+ selectedVal={userTheme}
setSelectedVal={(scheme) => this.changeColorScheme(scheme as string)}
items={colorSchemes.map((scheme, i) => (
{
@@ -140,8 +158,14 @@ export class SettingsManager extends React.Component<{}> {
}
))}
dropdownType={DropdownType.SELECT}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
+ fillWidth
/>
+ {userTheme === ColorScheme.Custom && <Group formLabel='Custom Theme'>
+ <ColorPicker tooltip={'User Color'} color={this.userColor} type={Type.SEC} icon={<FaFillDrip/>} selectedColor={this.userColor} setSelectedColor={this.switchUserColor}/>
+ <ColorPicker tooltip={'User Background Color'} color={this.userColor} type={Type.SEC} icon={<FaPalette/>} selectedColor={this.userBackgroundColor} setSelectedColor={this.switchUserBackgroundColor}/>
+ <ColorPicker tooltip={'User Variant Color'} color={this.userColor} type={Type.SEC} icon={<FaPalette/>} selectedColor={this.userVariantColor} setSelectedColor={this.switchUserVariantColor}/>
+ </Group>}
</div>
);
}
@@ -155,7 +179,7 @@ export class SettingsManager extends React.Component<{}> {
toggleType={ToggleType.SWITCH}
onClick={e => (Doc.UserDoc().layout_showTitle = Doc.UserDoc().layout_showTitle ? undefined : 'author_date')}
toggleStatus={Doc.UserDoc().layout_showTitle !== undefined} size={Size.XSMALL}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
/>
<Toggle
@@ -165,7 +189,7 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => (Doc.UserDoc()['documentLinksButton-fullMenu'] = !Doc.UserDoc()['documentLinksButton-fullMenu'])}
toggleStatus={BoolCast(Doc.UserDoc()['documentLinksButton-fullMenu'])}
size={Size.XSMALL}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
/>
<Toggle
@@ -175,7 +199,7 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => FontIconBox.SetShowLabels(!FontIconBox.GetShowLabels())}
toggleStatus={FontIconBox.GetShowLabels()}
size={Size.XSMALL}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
/>
<Toggle
@@ -185,7 +209,7 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => FontIconBox.SetRecognizeGestures(!FontIconBox.GetRecognizeGestures())}
toggleStatus={FontIconBox.GetRecognizeGestures()}
size={Size.XSMALL}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
/>
<Toggle
@@ -195,7 +219,7 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => (Doc.UserDoc().activeInkHideTextLabels = !Doc.UserDoc().activeInkHideTextLabels)}
toggleStatus={BoolCast(Doc.UserDoc().activeInkHideTextLabels)}
size={Size.XSMALL}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
/>
<Toggle
@@ -205,7 +229,7 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => (Doc.UserDoc().openInkInLightbox = !Doc.UserDoc().openInkInLightbox)}
toggleStatus={BoolCast(Doc.UserDoc().openInkInLightbox)}
size={Size.XSMALL}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
/>
</div>
@@ -238,6 +262,15 @@ export class SettingsManager extends React.Component<{}> {
<div className="tab-column-content">
{/* <NumberInput/> */}
<Group formLabel={'Default Font'}>
+ <NumberDropdown
+ color={this.userColor}
+ numberDropdownType={'input'}
+ min={0} max={50} step={2}
+ type={Type.TERT}
+ number={0}
+ unit={"px"}
+ setNumber={() => {}}
+ />
<Dropdown
items={fontFamilies.map((val) => {
return {
@@ -252,7 +285,8 @@ export class SettingsManager extends React.Component<{}> {
type={Type.TERT}
selectedVal={StrCast(Doc.UserDoc().fontFamily)}
setSelectedVal={(val) => {this.changeFontFamily(val as string)}}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
+ fillWidth
/>
</Group>
</div>
@@ -262,8 +296,7 @@ export class SettingsManager extends React.Component<{}> {
}
@action
- changeVal = (e: React.ChangeEvent, pass: string) => {
- const value = (e.target as any).value;
+ changeVal = (value: string, pass: string) => {
switch (pass) {
case 'curr':
this.curr_password = value;
@@ -280,16 +313,33 @@ export class SettingsManager extends React.Component<{}> {
@computed get passwordContent() {
return (
<div className="password-content">
- <div className="password-content-inputs">
- <input className="password-inputs" type="password" placeholder="current password" onChange={e => this.changeVal(e, 'curr')} />
- <input className="password-inputs" type="password" placeholder="new password" onChange={e => this.changeVal(e, 'new')} />
- <input className="password-inputs" type="password" placeholder="confirm new password" onChange={e => this.changeVal(e, 'conf')} />
- </div>
- <div className="password-content-buttons">
- {!this.passwordResultText ? null : <div className={`${this.passwordResultText.startsWith('Error') ? 'error' : 'success'}-text`}>{this.passwordResultText}</div>}
- <Button type={Type.SEC} text={'Forgot Password'} color={StrCast(Doc.SharingDoc().userColor)}/>
- <Button type={Type.TERT} text={'Submit'} onClick={this.changePassword} color={StrCast(Doc.SharingDoc().userColor)}/>
- </div>
+ <EditableText placeholder="Current password"
+ type={Type.SEC}
+ color={this.userColor}
+ val={""}
+ setVal={val => this.changeVal(val as string, 'curr')}
+ fillWidth
+ password
+ />
+ <EditableText placeholder="New password"
+ type={Type.SEC}
+ color={this.userColor}
+ val={""}
+ setVal={val => this.changeVal(val as string, 'new')}
+ fillWidth
+ password
+ />
+ <EditableText placeholder="Confirm new password"
+ type={Type.SEC}
+ color={this.userColor}
+ val={""}
+ setVal={val => this.changeVal(val as string, 'conf')}
+ fillWidth
+ password
+ />
+ {!this.passwordResultText ? null : <div className={`${this.passwordResultText.startsWith('Error') ? 'error' : 'success'}-text`}>{this.passwordResultText}</div>}
+ <Button type={Type.SEC} text={'Forgot Password'} color={this.userColor}/>
+ <Button type={Type.TERT} text={'Submit'} onClick={this.changePassword} color={this.userColor}/>
</div>
);
}
@@ -346,14 +396,15 @@ export class SettingsManager extends React.Component<{}> {
dropdownType={DropdownType.SELECT}
type={Type.TERT}
placement='bottom-start'
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
+ fillWidth
/>
<Toggle
formLabel={'Playground Mode'}
toggleType={ToggleType.SWITCH}
toggleStatus={this.playgroundMode}
onClick={this.playgroundModeToggle}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
/>
</div>
<div className="tab-column-title" style={{ marginTop: 20, marginBottom: 10 }}>
@@ -379,7 +430,7 @@ export class SettingsManager extends React.Component<{}> {
dropdownType={DropdownType.SELECT}
type={Type.TERT}
placement='bottom-start'
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
/>
</div>
</div>
@@ -390,12 +441,12 @@ export class SettingsManager extends React.Component<{}> {
text={"Manage Groups"}
type={Type.TERT}
onClick={() => GroupManager.Instance?.open()}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
/>
<Toggle
toggleType={ToggleType.SWITCH}
formLabel={"Default access private"}
- color={StrCast(Doc.SharingDoc().userColor)}
+ color={this.userColor}
toggleStatus={BoolCast(Doc.defaultAclPrivate)}
onClick={action(() => (Doc.defaultAclPrivate = !Doc.defaultAclPrivate))}/>
</div>
@@ -414,23 +465,35 @@ export class SettingsManager extends React.Component<{}> {
{ title: 'Appearance', ele: this.appearanceContent },
{ title: 'Text', ele: this.textContent },
];
-
return (
<div className="settings-interface">
- <div className="settings-panel">
+ <div className="settings-panel" style={{ background: this.userColor }}>
<div className="settings-tabs">
- {tabs.map(tab => (
- <div key={tab.title} className={'tab-control ' + (this.activeTab === tab.title ? 'active' : 'inactive')} onClick={action(() => (this.activeTab = tab.title))}>
- {tab.title}
- </div>
- ))}
+ {tabs.map(tab => {
+ const isActive = this.activeTab === tab.title
+ return (
+ <div key={tab.title}
+ style={{
+ background: isActive ? this.userBackgroundColor : this.userColor,
+ color: isActive ? this.userColor : this.userBackgroundColor,
+ }}
+ className={'tab-control ' + (isActive ? 'active' : 'inactive')}
+ onClick={action(() => (this.activeTab = tab.title))
+ }>
+ {tab.title}
+ </div>
+ )
+ })}
</div>
<div className="settings-user">
- <div className="settings-username">{Doc.CurrentUserEmail}</div>
+ <div className="settings-username"
+ style={{color: this.userBackgroundColor}}
+ >{Doc.CurrentUserEmail}</div>
<Button
text={Doc.GuestDashboard ? 'Exit' : 'Log Out'}
type={Type.TERT}
+ color={this.userVariantColor}
onClick={() => window.location.assign(Utils.prepend('/logout'))}
/>
</div>
@@ -439,12 +502,13 @@ export class SettingsManager extends React.Component<{}> {
<div className="close-button">
<Button
- icon={<FontAwesomeIcon icon={'times'} color="black" size={'lg'} />}
+ icon={<FontAwesomeIcon icon={'times'} size={'lg'} />}
onClick={this.close}
+ color={this.userColor}
/>
</div>
- <div className="settings-content">
+ <div className="settings-content" style={{color: this.userColor, background: this.userBackgroundColor}}>
{tabs.map(tab => (
<div key={tab.title} className={'tab-section ' + (this.activeTab === tab.title ? 'active' : 'inactive')}>
{tab.ele}
@@ -462,7 +526,7 @@ export class SettingsManager extends React.Component<{}> {
isDisplayed={this.isOpen}
interactive={true}
closeOnExternalClick={this.close}
- dialogueBoxStyle={{ width: 'fit-content', height: '300px', background: Cast(Doc.SharingDoc().userColor, 'string', null) }}
+ dialogueBoxStyle={{ width: 'fit-content', height: '300px', background: Cast(Doc.UserDoc().userColor, 'string', null) }}
/>
);
}
diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index 8a0e5480e..b205a0f1e 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -5,11 +5,15 @@
position: absolute;
z-index: 10001;
height: $antimodemenu-height;
- background: $dark-gray;
- border-bottom: $standard-border;
+ width: fit-content;
+ border-radius: $standard-border-radius;
+ overflow: hidden;
// box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
// border-radius: 0px 6px 6px 6px;
display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 3px;
&.with-rows {
flex-direction: column
@@ -20,30 +24,6 @@
height: 35px;
}
- .antimodeMenu-button {
- background-color: transparent;
- width: 35px;
- height: 35px;
- padding: 5;
- text-align: center;
- display: flex;
- justify-content: center;
- align-items: center;
- position: relative;
-
- .svg {
- margin: 0;
- }
-
- &.active {
- background-color: #121212;
- }
- }
-
- .antimodeMenu-button:hover {
- background-color: rgba(0, 0, 0, 0.4);
- }
-
.antimodeMenu-dragger {
height: 100%;
transition: width .2s;
diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx
index de1207ce4..c41ea7053 100644
--- a/src/client/views/AntimodeMenu.tsx
+++ b/src/client/views/AntimodeMenu.tsx
@@ -1,6 +1,8 @@
import React = require('react');
import { observable, action, runInAction } from 'mobx';
import './AntimodeMenu.scss';
+import { StrCast } from '../../fields/Types';
+import { Doc } from '../../fields/Doc';
export interface AntimodeMenuProps {}
/**
@@ -148,6 +150,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends React.Co
left: this._left,
top: this._top,
opacity: this._opacity,
+ background: StrCast(Doc.UserDoc().userBackgroundColor),
transitionProperty: this._transitionProperty,
transitionDuration: this._transitionDuration,
transitionDelay: this._transitionDelay,
@@ -173,6 +176,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends React.Co
height: 'inherit',
width: 200,
opacity: this._opacity,
+ background: StrCast(Doc.UserDoc().userBackgroundColor),
transitionProperty: this._transitionProperty,
transitionDuration: this._transitionDuration,
transitionDelay: this._transitionDelay,
@@ -195,6 +199,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends React.Co
left: this._left,
top: this._top,
opacity: this._opacity,
+ background: StrCast(Doc.UserDoc().userBackgroundColor),
transitionProperty: this._transitionProperty,
transitionDuration: this._transitionDuration,
transitionDelay: this._transitionDelay,
diff --git a/src/client/views/DashboardView.scss b/src/client/views/DashboardView.scss
index b8a6f6c05..b95312ea0 100644
--- a/src/client/views/DashboardView.scss
+++ b/src/client/views/DashboardView.scss
@@ -14,6 +14,7 @@
flex-direction: column;
width: 250px;
min-width: 250px;
+ gap: 5px;
}
.all-dashboards {
@@ -56,15 +57,26 @@
display: flex;
justify-content: center;
align-items: center;
+ position: relative;
&:hover {
color: $light-blue;
border: solid 2px $light-blue;
}
+
+ .background {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ left: 0;
+ top: 0;
+ z-index: -1;
+ }
}
.dashboard-container {
border-radius: 10px;
+ position: relative;
cursor: pointer;
width: 250px;
height: 200px;
@@ -99,10 +111,20 @@
.more {
z-index: 100;
}
+
+ .background {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ left: 0;
+ top: 0;
+ z-index: -1;
+ }
}
.new-dashboard {
color: $dark-gray;
+ padding: 10px;
display: flex;
width: 100%;
height: 100%;
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 3bd6ac61c..dd1079d88 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, ColorPicker, FontSize, IconButton, Size, Type } 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';
@@ -24,7 +24,7 @@ import { ContextMenu } from './ContextMenu';
import './DashboardView.scss';
import { Colors } from './global/globalEnums';
import { MainViewModal } from './MainViewModal';
-import { ButtonType } from './nodes/button/FontIconBox';
+import { ButtonType } from './nodes/FontIconBox/FontIconBox';
import { FaPlus } from 'react-icons/fa';
enum DashboardGroup {
@@ -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) => {
@@ -95,23 +98,33 @@ 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}
+ setSelectedColor={color => {
+ this.setNewDashboardColor(color);
+ }}
+ />
<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 +163,49 @@ 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.LARGE} text="New" type={Type.SEC} 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'}
+ active={this.selectedDashboardGroup === DashboardGroup.SharedDashboards}
+ color={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 => {
const href = ImageCast(dashboard.thumb)?.url.href;
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]}
+ 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 +218,13 @@ 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} size="lg" icon="bars" />} />
</div>
</div>
+ <div className={`background`} style={{
+ background: StrCast(Doc.UserDoc().userColor),
+ filter: 'opacity(0.2)'
+ }}/>
</div>
);
})}
@@ -200,6 +234,10 @@ export class DashboardView extends React.Component {
this.setNewDashboardName('');
}}>
+
+ <div className={`background`} style={{
+ background: StrCast(Doc.UserDoc().userColor),
+ filter: 'opacity(0.2)'
+ }}/>
</div>
</div>
</div>
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 7043edcee..4deed5ed9 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -6,6 +6,7 @@ import { ObjectField } from '../../fields/ObjectField';
import './EditableView.scss';
import { DocumentIconContainer } from './nodes/DocumentIcon';
import { OverlayView } from './OverlayView';
+import { EditableText } from 'browndash-components';
export interface EditableProps {
/**
@@ -231,39 +232,49 @@ export class EditableView extends React.Component<EditableProps> {
onChange: this.props.autosuggestProps.onChange,
}}
/>
- ) : this.props.oneLine !== false && this.props.GetValue()?.toString().indexOf('\n') === -1 ? (
- <input
- className="editableView-input"
- ref={r => (this._inputref = r)}
- style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minWidth: 20, background: this.props.background }}
- placeholder={this.props.placeholder}
- onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
- defaultValue={this.props.GetValue()}
- autoFocus={true}
- onChange={this.onChange}
- onKeyDown={this.onKeyDown}
- onKeyPress={this.stopPropagation}
- onPointerDown={this.stopPropagation}
- onClick={this.stopPropagation}
- onPointerUp={this.stopPropagation}
+ ) : <EditableText
+ // oneLine={this.props.oneLine && this.props.GetValue()?.toString().indexOf('\n') === -1}
+ editing={true}
+ onEdit={function (newText: string): void {
+ throw new Error('Function not implemented.');
+ } }
+ setEditing={function (editing: boolean): void {
+ throw new Error('Function not implemented.');
+ } }
+ // onEdit={this.onChange}
/>
- ) : (
- <textarea
- className="editableView-input"
- ref={r => (this._inputref = r)}
- style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minHeight: `min(100%, ${(this.props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, background: this.props.background }}
- placeholder={this.props.placeholder}
- onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
- defaultValue={this.props.GetValue()}
- autoFocus={true}
- onChange={this.onChange}
- onKeyDown={this.onKeyDown}
- onKeyPress={this.stopPropagation}
- onPointerDown={this.stopPropagation}
- onClick={this.stopPropagation}
- onPointerUp={this.stopPropagation}
- />
- );
+ // // <input
+ // // className="editableView-input"
+ // // ref={r => (this._inputref = r)}
+ // // style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minWidth: 20, background: this.props.background }}
+ // // placeholder={this.props.placeholder}
+ // // onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
+ // // defaultValue={this.props.GetValue()}
+ // // autoFocus={true}
+ // // onChange={this.onChange}
+ // // onKeyDown={this.onKeyDown}
+ // // onKeyPress={this.stopPropagation}
+ // // onPointerDown={this.stopPropagation}
+ // // onClick={this.stopPropagation}
+ // // onPointerUp={this.stopPropagation}
+ // // />
+ // ) : (
+ // <textarea
+ // className="editableView-input"
+ // ref={r => (this._inputref = r)}
+ // style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minHeight: `min(100%, ${(this.props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, background: this.props.background }}
+ // placeholder={this.props.placeholder}
+ // onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
+ // defaultValue={this.props.GetValue()}
+ // autoFocus={true}
+ // onChange={this.onChange}
+ // onKeyDown={this.onKeyDown}
+ // onKeyPress={this.stopPropagation}
+ // onPointerDown={this.stopPropagation}
+ // onClick={this.stopPropagation}
+ // onPointerUp={this.stopPropagation}
+ // />
+ // );
}
render() {
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 54ad519de..4e6d5c2e9 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -31,7 +31,7 @@ import {
SetActiveInkWidth,
} from './InkingStroke';
import { InkTranscription } from './InkTranscription';
-import { checkInksToGroup } from './nodes/button/FontIconBox';
+import { checkInksToGroup } from './nodes/FontIconBox/FontIconBox';
import { DocumentView } from './nodes/DocumentView';
import { RadialMenu } from './nodes/RadialMenu';
import { Touchable } from './Touchable';
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index b95ce0e99..e33054c8e 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -68,10 +68,6 @@ h1,
left: 0;
z-index: 1;
touch-action: none;
-
- .searchBox-container {
- background: $light-gray;
- }
}
.mainView-container,
@@ -118,10 +114,6 @@ h1,
background: $light-gray;
}
- .searchBox-container {
- background: $dark-gray;
- }
-
.contextMenu-cont,
.contextMenu-item {
background: $dark-gray;
@@ -193,17 +185,6 @@ h1,
background: $light-gray;
}
}
-
- .propertiesView {
- left: 0;
- position: absolute;
- z-index: 2;
- background-color: $light-gray;
-
- .editable-title {
- background-color: $light-gray;
- }
- }
}
.mainView-libraryHandle {
@@ -250,7 +231,6 @@ h1,
.mainView-leftMenuPanel {
min-width: var(--menuPanelWidth);
- background-color: $dark-gray;
border-right: $standard-border;
.collectionStackingView {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index ec8f5989f..a7164f88b 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -754,7 +754,8 @@ export class MainView extends React.Component {
@computed get leftMenuPanel() {
return (
- <div key="menu" className="mainView-leftMenuPanel" style={{ display: LightboxView.LightboxDoc ? 'none' : undefined }}>
+ <div key="menu" className="mainView-leftMenuPanel" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor),
+ display: LightboxView.LightboxDoc ? 'none' : undefined }}>
<DocumentView
Document={Doc.MyLeftSidebarMenu}
DataDoc={undefined}
@@ -809,8 +810,8 @@ export class MainView extends React.Component {
{this._hideUI ? null : this.leftMenuPanel}
<div key="inner" className={`mainView-innerContent${this.colorScheme}`}>
{this.flyout}
- <div className="mainView-libraryHandle" style={{ left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? 'none' : undefined }} onPointerDown={this.onFlyoutPointerDown}>
- <FontAwesomeIcon icon="chevron-left" color={this.colorScheme === ColorScheme.Dark ? 'white' : 'black'} style={{ opacity: '50%' }} size="sm" />
+ <div className="mainView-libraryHandle" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? 'none' : undefined }} onPointerDown={this.onFlyoutPointerDown}>
+ <FontAwesomeIcon icon="chevron-left" color={StrCast(Doc.UserDoc().userColor)} style={{ opacity: '50%' }} size="sm" />
</div>
<div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)` }}>
{this.dockingContent}
@@ -964,7 +965,11 @@ export class MainView extends React.Component {
render() {
return (
<div
- className={`mainView-container${this.colorScheme}`}
+ className={`mainView-container ${this.colorScheme}`}
+ style={{
+ color: StrCast(Doc.UserDoc().userColor),
+ background: StrCast(Doc.UserDoc().userBackgroundColor),
+ }}
onScroll={() => (ele => (ele.scrollTop = ele.scrollLeft = 0))(document.getElementById('root')!)}
ref={r => {
r &&
diff --git a/src/client/views/MainViewModal.scss b/src/client/views/MainViewModal.scss
index 0648e31c5..4bf9eb79f 100644
--- a/src/client/views/MainViewModal.scss
+++ b/src/client/views/MainViewModal.scss
@@ -4,22 +4,23 @@
z-index: 10000;
width: 100%;
height: 100%;
+ box-shadow: #00000044 5px 5px 10px;
.dialogue-box {
- padding: 10px;
position: absolute;
z-index: 1000;
text-align: center;
justify-content: center;
align-self: center;
align-content: center;
- background: white;
// border-radius: 10px;
box-shadow: #00000044 5px 5px 10px;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
transition: 0.5s all ease;
+ border-radius: 10px;
+ overflow: hidden;
}
.overlay {
@@ -28,6 +29,7 @@
position: absolute;
z-index: 999;
transition: 0.5s all ease;
+ backdrop-filter: blur(5px);
}
} \ No newline at end of file
diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index 32997a944..42df99864 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -1,6 +1,10 @@
import * as React from 'react';
import './MainViewModal.scss';
import { observer } from 'mobx-react';
+import { Doc } from '../../fields/Doc';
+import { StrCast } from '../../fields/Types';
+import { isDark } from 'browndash-components';
+import { Colors } from './global/globalEnums';
export interface MainViewOverlayProps {
isDisplayed: boolean;
@@ -41,9 +45,8 @@ export class MainViewModal extends React.Component<MainViewOverlayProps> {
className="overlay"
onClick={this.props?.closeOnExternalClick}
style={{
- backgroundColor: 'black',
+ backgroundColor: isDark(StrCast(Doc.UserDoc().userColor)) ? "#DFDFDF30" : "#32323230",
...(p.overlayStyle || {}),
- opacity: p.isDisplayed ? overlayOpacity : 0,
}}
/>
</div>
diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
index 36b2df73e..db30745fc 100644
--- a/src/client/views/PropertiesButtons.scss
+++ b/src/client/views/PropertiesButtons.scss
@@ -57,14 +57,13 @@ $linkGap : 3px;
}
.propertiesButtons {
- margin-top: 3px;
- grid-column: 1/4;
width: 100%;
height: auto;
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding-bottom: 5.5px;
+ gap: 5px;
}
.onClickFlyout-editScript {
@@ -81,10 +80,7 @@ $linkGap : 3px;
.propertiesButtons-button {
pointer-events: auto;
padding-right: 5px;
- width: 25px;
- border-radius: 5px;
- margin-right: 20px;
- margin-bottom: 8px;
+ width: 100%;
}
.propertiesButton-dropdownList {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 74dd1c2f7..3148d9ddd 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -21,6 +21,7 @@ import { DocumentView, OpenWhere } from './nodes/DocumentView';
import { pasteImageBitmap } from './nodes/WebBoxRenderer';
import './PropertiesButtons.scss';
import React = require('react');
+import { Dropdown, DropdownType, IListItemProps, Toggle, ToggleType, Type } from 'browndash-components';
const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -44,24 +45,23 @@ export class PropertiesButtons extends React.Component<{}, {}> {
propertyToggleBtn = (label: string, property: string, tooltip: (on?: any) => string, icon: (on: boolean) => string, onClick?: (dv: Opt<DocumentView>, doc: Doc, property: string) => void, useUserDoc?: boolean) => {
const targetDoc = useUserDoc ? Doc.UserDoc() : this.selectedDoc;
const onPropToggle = (dv: Opt<DocumentView>, doc: Doc, prop: string) => ((dv?.layoutDoc || doc)[prop] = (dv?.layoutDoc || doc)[prop] ? false : true);
- return !targetDoc ? null : (
- <Tooltip title={<div className={`dash-tooltip`}>{tooltip(targetDoc?.[property])} </div>} placement="top">
- <div>
- <div
- className={`propertiesButtons-linkButton-empty toggle-${StrCast(targetDoc[property]).includes(':hover') ? 'hover' : targetDoc[property] ? 'on' : 'off'}`}
- onPointerDown={e => e.stopPropagation()}
- onClick={undoable(() => {
- if (SelectionManager.Views().length > 1) {
- SelectionManager.Views().forEach(dv => (onClick ?? onPropToggle)(dv, dv.rootDoc, property));
- } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property);
- }, property)}>
- <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon={icon(BoolCast(targetDoc?.[property])) as any} />
- </div>
- <div className="propertiesButtons-title">{label}</div>
- </div>
- </Tooltip>
- );
+ return !targetDoc ? null : <Toggle
+ toggleStatus={BoolCast(targetDoc[property])}
+ text={tooltip(targetDoc?.[property])}
+ color={StrCast(Doc.UserDoc().userColor)}
+ icon={<FontAwesomeIcon className="documentdecorations-icon" size="lg" icon={icon(BoolCast(targetDoc?.[property])) as any} />}
+ iconPlacement={'left'}
+ align={'flex-start'}
+ fillWidth={true}
+ toggleType={ToggleType.BUTTON}
+ onClick={undoable(() => {
+ if (SelectionManager.Views().length > 1) {
+ SelectionManager.Views().forEach(dv => (onClick ?? onPropToggle)(dv, dv.rootDoc, property));
+ } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property);
+ }, property)}
+ />
};
+
@computed get lockButton() {
return this.propertyToggleBtn(
'No\xA0Drag',
@@ -244,21 +244,61 @@ export class PropertiesButtons extends React.Component<{}, {}> {
);
}
+ @computed get onClickVal() {
+ const linkButton = IsFollowLinkScript(this.selectedDoc.onClick);
+ const followLoc = this.selectedDoc._followLinkLocation;
+ const linkedToLightboxView = () => LinkManager.Links(this.selectedDoc).some(link => LinkManager.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
+
+ if (followLoc === OpenWhere.lightbox && !linkedToLightboxView()) return 'linkInPlace'
+ else if (linkButton && followLoc === OpenWhere.addRight) return 'linkOnRight'
+ else if (linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView()) return 'enterPortal'
+ else if (ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail')) return 'toggleDetail'
+ else return 'nothing'
+ }
+
@computed
get onClickButton() {
+ const buttonList = [
+ ['nothing', 'Select Document'],
+ ['enterPortal', 'Enter Portal'],
+ ['toggleDetail', 'Toggle Detail'],
+ ['linkInPlace', 'Open Link in Lightbox'],
+ ['linkOnRight', 'Open Link on Right'],
+ ];
+
+ const items: IListItemProps[] = buttonList.map(value => {
+ return (
+ {
+ text: value[1],
+ val: value[1],
+ }
+ );
+ });
+ console.log("click val: ", this.onClickVal)
return !this.selectedDoc ? null : (
- <Tooltip title={<div className="dash-tooltip">Choose onClick behavior</div>} placement="top">
- <div>
- <div className="propertiesButtons-linkFlyout">
- <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onClickFlyout}>
- <div className={'propertiesButtons-linkButton-empty'} onPointerDown={e => e.stopPropagation()}>
- <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" />
- </div>
- </Flyout>
- </div>
- <div className="propertiesButtons-title"> onclick </div>
- </div>
- </Tooltip>
+ <Dropdown
+ tooltip={'Choose onClick behavior'}
+ items={items}
+ selectedVal={this.onClickVal}
+ setSelectedVal={(val) => this.handleOptionChange(val as string)}
+ title={'Choose onClick behaviour'}
+ color={StrCast(Doc.UserDoc().userColor)}
+ dropdownType={DropdownType.SELECT}
+ type={Type.SEC}
+ fillWidth
+ />
+ // <Tooltip title={<div className="dash-tooltip">Choose onClick behavior</div>} placement="top">
+ // <div>
+ // <div className="propertiesButtons-linkFlyout">
+ // <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onClickFlyout}>
+ // <div className={'propertiesButtons-linkButton-empty'} onPointerDown={e => e.stopPropagation()}>
+ // <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" />
+ // </div>
+ // </Flyout>
+ // </div>
+ // <div className="propertiesButtons-title"> onclick </div>
+ // </div>
+ // </Tooltip>
);
}
@computed
diff --git a/src/client/views/PropertiesDocBacklinksSelector.scss b/src/client/views/PropertiesDocBacklinksSelector.scss
index 4d2a61c3b..5c53acf48 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.scss
+++ b/src/client/views/PropertiesDocBacklinksSelector.scss
@@ -1,4 +1,4 @@
-.propertiesView-contexts-content {
+.propertiesDocBacklinksSelector {
.linkMenu {
position: relative;
}
diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx
index 3e69bcba6..da4438481 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.tsx
+++ b/src/client/views/PropertiesDocBacklinksSelector.tsx
@@ -31,7 +31,7 @@ export class PropertiesDocBacklinksSelector extends React.Component<PropertiesDo
render() {
return !SelectionManager.Views().length ? null : (
- <div className="preroptiesDocBacklinksSelector">
+ <div className="propertiesDocBacklinksSelector">
{this.props.hideTitle ? null : <p key="contexts">Contexts:</p>}
<LinkMenu docView={SelectionManager.Views().lastElement()} clearLinkEditor={undefined} itemHandler={this.getOnClick} style={{ left: 0, top: 0 }} />
</div>
diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx
index e1279c9a7..6cac7b0fe 100644
--- a/src/client/views/PropertiesDocContextSelector.tsx
+++ b/src/client/views/PropertiesDocContextSelector.tsx
@@ -53,6 +53,7 @@ export class PropertiesDocContextSelector extends React.Component<PropertiesDocC
};
render() {
+ if (this._docs.length < 1) return undefined
return (
<div>
{this.props.hideTitle ? null : <p key="contexts">Contexts:</p>}
diff --git a/src/client/views/PropertiesSection.scss b/src/client/views/PropertiesSection.scss
new file mode 100644
index 000000000..79479a4ce
--- /dev/null
+++ b/src/client/views/PropertiesSection.scss
@@ -0,0 +1,24 @@
+@import './global/globalCssVariables.scss';
+
+.propertiesView-section {
+
+ .propertiesView-content {
+ padding: 10px;
+ }
+
+ .propertiesView-sectionTitle {
+ text-align: center;
+ display: flex;
+ padding: 10px;
+ font-size: 14px;
+ font-weight: bold;
+ justify-content: space-between;
+ align-items: center;
+
+ .propertiesView-sectionTitle-icon {
+ width: 20px;
+ height: 20px;
+ align-items: flex-end;
+ }
+ }
+}
diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx
new file mode 100644
index 000000000..b900d17ca
--- /dev/null
+++ b/src/client/views/PropertiesSection.tsx
@@ -0,0 +1,51 @@
+import React = require('react');
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
+import { action, computed } from "mobx"
+import { observer } from "mobx-react"
+import './PropertiesSection.scss'
+import { Doc } from '../../fields/Doc';
+import { StrCast } from '../../fields/Types';
+
+export interface PropertiesSectionProps {
+ title: string,
+ content?: JSX.Element | string | null,
+ isOpen: boolean,
+ setIsOpen: (bool: boolean) => any
+ inSection?: boolean,
+ setInSection?: (bool: boolean) => any
+}
+
+@observer
+export class PropertiesSection extends React.Component<PropertiesSectionProps> {
+ @computed get color() {
+ return StrCast(Doc.UserDoc().userColor);
+ }
+
+ @computed get backgroundColor() {
+ return StrCast(Doc.UserDoc().userBackgroundColor);
+ }
+
+ @computed get variantColor() {
+ return StrCast(Doc.UserDoc().userVariantColor);
+ }
+ render() {
+ console.log(this.props.title, this.props.content)
+ if (this.props.content === undefined || this.props.content === null) return null
+ else return <div className="propertiesView-section" onPointerEnter={action(() => (this.props.setInSection && this.props.setInSection(true)))} onPointerLeave={action(() => (this.props.setInSection && this.props.setInSection(false)))}>
+ <div className="propertiesView-sectionTitle" onPointerDown={action(() => (this.props.setIsOpen(!this.props.isOpen)))} style={{
+ background: this.props.isOpen ? this.variantColor : this.backgroundColor,
+ color: this.color
+ }}>
+ {this.props.title}
+ <div className="propertiesView-sectionTitle-icon">
+ <FontAwesomeIcon icon={this.props.isOpen ? 'caret-down' : 'caret-right'} size="lg" />
+ </div>
+ </div>
+ {!this.props.isOpen ? null :
+ <div className="propertiesView-content">
+ {this.props.content}
+ </div>
+ }
+ </div>
+ }
+} \ No newline at end of file
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index 897be9a32..889f5d5cf 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -6,122 +6,31 @@
font-family: 'Roboto';
font-size: 12px;
cursor: auto;
+ border-left: $standard-border;
.slider-text {
font-size: 8px;
}
- overflow-x: hidden;
- overflow-y: auto;
-
.propertiesView-title {
- text-align: center;
- padding-top: 12px;
- padding-bottom: 12px;
- display: flex;
- font-size: 18px;
+ padding: 10px;
+ font-size: 24px;
font-weight: bold;
- justify-content: center;
-
- .propertiesView-title-icon {
- width: 20px;
- height: 20px;
- padding-left: 38px;
- margin-top: -5px;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 10px;
-
- &:hover {
- color: grey;
- cursor: pointer;
- }
- }
}
- .propertiesView-name {
- border-bottom: 1px solid black;
- padding: 8.5px;
- font-size: 12.5px;
+ overflow-x: hidden;
+ overflow-y: auto;
- &:hover {
- cursor: text;
- }
+ .propertiesView-name,
+ .propertiesView-type {
+ padding: 0px 10px;
}
- .propertiesView-settings {
- //border-bottom: 1px solid black;
- //padding: 8.5px;
- font-size: 12.5px;
- font-weight: bold;
-
- .propertiesView-settings-title {
- font-weight: bold;
- font-size: 12.5px;
- padding: 4px;
- display: flex;
- color: white;
- padding-left: 8px;
- background-color: rgb(51, 51, 51);
-
- &:hover {
- cursor: pointer;
- }
-
- .propertiesView-settings-title-icon {
- float: right;
- justify-items: right;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 9px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
-
- .propertiesView-settings-content {
- margin-left: 12px;
- padding-bottom: 10px;
- padding-top: 8px;
- }
- }
.propertiesView-sharing {
//border-bottom: 1px solid black;
//padding: 8.5px;
- .propertiesView-sharing-title {
- font-weight: bold;
- font-size: 12.5px;
- padding: 4px;
- display: flex;
- color: white;
- padding-left: 8px;
- background-color: rgb(51, 51, 51);
-
- &:hover {
- cursor: pointer;
- }
-
- .propertiesView-sharing-title-icon {
- float: right;
- justify-items: right;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 9px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
-
- .propertiesView-sharing-content {
- font-size: 10px;
- padding: 10px;
- margin-left: 5px;
.propertiesView-buttonContainer {
float: right;
@@ -157,40 +66,13 @@
width: 100%;
}
}
- }
}
.propertiesView-filters {
//border-bottom: 1px solid black;
//padding: 8.5px;
- .propertiesView-filters-title {
- font-weight: bold;
- font-size: 12.5px;
- padding: 4px;
- display: flex;
- color: white;
- padding-left: 8px;
- background-color: rgb(51, 51, 51);
-
- &:hover {
- cursor: pointer;
- }
-
- .propertiesView-filters-title-icon {
- float: right;
- justify-items: right;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 9px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
-
- .propertiesView-filters-content {
+ .propertiesView-content {
font-size: 10px;
padding: 10px;
margin-left: 5px;
@@ -219,85 +101,10 @@
}
}
- .propertiesView-appearance {
- //border-bottom: 1px solid black;
- //padding: 8.5px;
-
- .propertiesView-appearance-title {
- font-weight: bold;
- font-size: 12.5px;
- padding: 4px;
- display: flex;
- color: white;
- padding-left: 8px;
- background-color: rgb(51, 51, 51);
-
- &:hover {
- cursor: pointer;
- }
-
- .propertiesView-appearance-title-icon {
- float: right;
- justify-items: right;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 9px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
-
- .propertiesView-appearance-content {
- font-size: 10px;
- padding: 10px;
- margin-left: 5px;
- }
- }
-
- .propertiesView-transform {
- //border-bottom: 1px solid black;
- //padding: 8.5px;
-
- .propertiesView-transform-title {
- font-weight: bold;
- font-size: 12.5px;
- padding: 4px;
- display: flex;
- color: white;
- padding-left: 8px;
- background-color: rgb(51, 51, 51);
-
- &:hover {
- cursor: pointer;
- }
-
- .propertiesView-transform-title-icon {
- float: right;
- justify-items: right;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 9px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
-
- .propertiesView-transform-content {
- font-size: 10px;
- padding: 10px;
- margin-left: 5px;
- }
- }
-
.notify-button {
padding: 2px;
width: 12px;
height: 12px;
- background-color: black;
border-radius: 10px;
padding-left: 2px;
padding-right: 2px;
@@ -393,58 +200,6 @@
}
}
- .propertiesView-fields {
- //border-bottom: 1px solid black;
- //padding: 8.5px;
-
- .propertiesView-fields-title {
- font-weight: bold;
- font-size: 12.5px;
- padding: 4px;
- display: flex;
- color: white;
- padding-left: 8px;
- background-color: rgb(51, 51, 51);
-
- &:hover {
- cursor: pointer;
- }
-
- .propertiesView-fields-title-icon {
- float: right;
- justify-items: right;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 9px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
-
- .propertiesView-fields-checkbox {
- float: right;
- height: 20px;
- margin-top: -9px;
-
- .propertiesView-fields-checkbox-text {
- font-size: 7px;
- margin-top: -10px;
- margin-left: 6px;
- }
- }
-
- .propertiesView-fields-content {
- font-size: 10px;
- margin-left: 2px;
- padding: 10px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
.propertiesView-field {
display: flex;
@@ -466,109 +221,14 @@
}
}
- .propertiesView-contexts {
- .propertiesView-contexts-title {
- font-weight: bold;
- font-size: 12.5px;
- padding: 4px;
- display: flex;
- color: white;
- padding-left: 8px;
- background-color: rgb(51, 51, 51);
-
- &:hover {
- cursor: pointer;
- }
-
- .propertiesView-contexts-title-icon {
- float: right;
- justify-items: right;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 9px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
-
- .propertiesView-contexts-content {
- overflow: hidden;
- padding: 10px;
- }
- }
-
- .propertiesView-layout {
- .propertiesView-layout-title {
- font-weight: bold;
- font-size: 12.5px;
- padding: 4px;
- display: flex;
- color: white;
- padding-left: 8px;
- background-color: rgb(51, 51, 51);
-
- &:hover {
- cursor: pointer;
- }
-
- .propertiesView-layout-title-icon {
- float: right;
- justify-items: right;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 9px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
-
- .propertiesView-layout-content {
- overflow: hidden;
- padding: 10px;
- }
}
.propertiesView-presTrails {
//border-bottom: 1px solid black;
//padding: 8.5px;
- .propertiesView-presTrails-title {
- font-weight: bold;
- font-size: 12.5px;
- padding: 4px;
- display: flex;
- color: white;
- padding-left: 8px;
- background-color: rgb(51, 51, 51);
-
- &:hover {
- cursor: pointer;
- }
-
- .propertiesView-presTrails-title-icon {
- float: right;
- justify-items: right;
- align-items: flex-end;
- margin-left: auto;
- margin-right: 9px;
-
- &:hover {
- cursor: pointer;
- }
- }
- }
-
- .propertiesView-presTrails-content {
- font-size: 10px;
- padding: 10px;
- margin-left: 5px;
- }
+
}
-}
.inking-button {
display: flex;
@@ -847,10 +507,6 @@
padding: 5%;
}
-.propertiesView-section {
- padding-left: 20px;
-}
-
.propertiesView-input {
padding: 4px 8px;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 09aac053a..e86506f92 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -35,6 +35,8 @@ import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector
import { PropertiesDocContextSelector } from './PropertiesDocContextSelector';
import './PropertiesView.scss';
import { DefaultStyleProvider } from './StyleProvider';
+import { Button, EditableText, NumberDropdown, Size, Slider, Type } from 'browndash-components';
+import { PropertiesSection } from './PropertiesSection';
const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -332,7 +334,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
return (
<Tooltip title={<div className="dash-tooltip">Notify with message</div>}>
<div className="notify-button">
- <FontAwesomeIcon className="notify-button-icon" icon="bell" color="white" size="sm" />
+ <FontAwesomeIcon className="notify-button-icon" icon="bell" size="sm" />
</div>
</Tooltip>
);
@@ -435,29 +437,57 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@action
toggleCheckbox = () => (this.layoutFields = !this.layoutFields);
+ @computed get color() {
+ return StrCast(Doc.UserDoc().userColor);
+ }
+
+ @computed get backgroundColor() {
+ return StrCast(Doc.UserDoc().userBackgroundColor);
+ }
+
+ @computed get variantColor() {
+ return StrCast(Doc.UserDoc().userVariantColor);
+ }
+
@computed get editableTitle() {
const titles = new Set<string>();
- SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title)));
const title = Array.from(titles.keys()).length > 1 ? '--multiple selected--' : StrCast(this.selectedDoc?.title);
+ SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title)));
return (
- <div className="editable-title">
- <EditableView key="editableView" contents={title} height={25} fontSize={14} GetValue={() => title} SetValue={this.setTitle} />
- </div>
+ <EditableText
+ val={title}
+ setVal={this.setTitle}
+ color={this.color}
+ type={Type.SEC}
+ formLabel={"Title"}
+ fillWidth
+ />
+ );
+ }
+
+ @computed get type() {
+ const type = StrCast(this.selectedDoc?.type);
+ return (
+ <Button
+ formLabel={"Type"}
+ text={type}
+ color={this.color}
+ align='flex-start'
+ fillWidth
+ />
);
}
@undoBatch
@action
- setTitle = (value: string) => {
+ setTitle = (value: string | number) => {
+ console.log(value)
if (SelectionManager.Views().length > 1) {
SelectionManager.Views().map(dv => Doc.SetInPlace(dv.rootDoc, 'title', value, true));
- return true;
} else if (this.dataDoc) {
if (this.selectedDoc) Doc.SetInPlace(this.selectedDoc, 'title', value, true);
- else KeyValueBox.SetField(this.dataDoc, 'title', value, true);
- return true;
+ else KeyValueBox.SetField(this.dataDoc, 'title', value as string, true);
}
- return false;
};
@undoBatch
@@ -515,7 +545,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
className="inking-button-points"
style={{ backgroundColor: InkStrokeProperties.Instance._controlButton ? 'black' : '' }}
onPointerDown={action(() => (InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton))}>
- <FontAwesomeIcon icon="bezier-curve" color="white" size="lg" />
+ <FontAwesomeIcon icon="bezier-curve" size="lg" />
</div>
</Tooltip>
</div>
@@ -534,10 +564,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<input className="inputBox-input" type="text" value={value} onChange={e => setter(e.target.value)} onKeyPress={e => e.stopPropagation()} />
<div className="inputBox-button">
<div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}>
- <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
+ <FontAwesomeIcon icon="caret-up" size="sm" />
</div>
<div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}>
- <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
+ <FontAwesomeIcon icon="caret-down" size="sm" />
</div>
</div>
</div>
@@ -791,10 +821,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<input className="inputBox-input" type="text" value={value} onChange={e => setter(e.target.value)} />
<div className="inputBox-button">
<div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}>
- <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
+ <FontAwesomeIcon icon="caret-up" size="sm" />
</div>
<div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}>
- <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
+ <FontAwesomeIcon icon="caret-down" size="sm" />
</div>
</div>
</div>
@@ -884,6 +914,29 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
return (
<div className="transform-editor">
{this.isInk ? this.controlPointsButton : null}
+ <Slider
+ formLabel={'Height'}
+ multithumb={false}
+ color={this.color}
+ size={Size.XSMALL}
+ min={0}
+ max={1000}
+ number={Number(this.shapeHgt)}
+ setNumber={undoable((val: string) => !isNaN(Number(val)) && (this.shapeHgt = val), 'set height')}
+ fillWidth
+ />
+ <Slider
+ formLabel={'Width'}
+ multithumb={false}
+ color={this.color}
+ size={Size.XSMALL}
+ min={0}
+ max={1000}
+ number={Number(this.shapeWid)}
+ setNumber={undoable((val: string) => !isNaN(Number(val)) && (this.shapeWid = val), 'set width')}
+ fillWidth
+ />
+
{this.hgtInput}
{this.XpsInput}
</div>
@@ -891,52 +944,38 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
@computed get optionsSubMenu() {
- return (
- <div className="propertiesView-settings" onPointerEnter={action(() => (this.inOptions = true))} onPointerLeave={action(() => (this.inOptions = false))}>
- <div className="propertiesView-settings-title" onPointerDown={action(() => (this.openOptions = !this.openOptions))} style={{ backgroundColor: this.openOptions ? 'black' : '' }}>
- Options
- <div className="propertiesView-settings-title-icon">
- <FontAwesomeIcon icon={this.openOptions ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
- </div>
- {!this.openOptions ? null : (
- <div className="propertiesView-settings-content">
- <PropertiesButtons />
- </div>
- )}
- </div>
- );
+ return <PropertiesSection
+ title="Options"
+ content={<PropertiesButtons />}
+ inSection={this.inOptions}
+ isOpen={this.openOptions}
+ setInSection={(bool) => this.inOptions = bool}
+ setIsOpen={(bool) => this.openOptions = bool}
+ />
}
@computed get sharingSubMenu() {
- return (
- <div className="propertiesView-sharing">
- <div className="propertiesView-sharing-title" onPointerDown={action(() => (this.openSharing = !this.openSharing))} style={{ backgroundColor: this.openSharing ? 'black' : '' }}>
- Sharing {'&'} Permissions
- <div className="propertiesView-sharing-title-icon">
- <FontAwesomeIcon icon={this.openSharing ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
- </div>
- {!this.openSharing ? null : (
- <div className="propertiesView-sharing-content">
- <div className="propertiesView-buttonContainer">
- {!Doc.noviceMode ? (
- <div className="propertiesView-acls-checkbox">
- <Checkbox color="primary" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} />
- <div className="propertiesView-acls-checkbox-text">Layout</div>
- </div>
- ) : null}
- {/* <Tooltip title={<><div className="dash-tooltip">{"Re-distribute sharing settings"}</div></>}>
- <button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}>
- <FontAwesomeIcon icon="redo-alt" color="white" size="1x" />
- </button>
- </Tooltip> */}
+ return <PropertiesSection
+ title="Sharing & Permissions"
+ content={<>
+ <div className="propertiesView-buttonContainer">
+ {!Doc.noviceMode ? (
+ <div className="propertiesView-acls-checkbox">
+ <Checkbox color="primary" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} />
+ <div className="propertiesView-acls-checkbox-text">Layout</div>
</div>
- {this.sharingTable}
- </div>
- )}
- </div>
- );
+ ) : null}
+ {/* <Tooltip title={<><div className="dash-tooltip">{"Re-distribute sharing settings"}</div></>}>
+ <button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}>
+ <FontAwesomeIcon icon="redo-alt" size="1x" />
+ </button>
+ </Tooltip> */}
+ </div>
+ {this.sharingTable}
+ </>}
+ isOpen={this.openSharing}
+ setIsOpen={(bool) => this.openSharing = bool}
+ />
}
/**
@@ -964,111 +1003,71 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
};
@computed get filtersSubMenu() {
- return (
- <div className="propertiesView-filters">
- <div className="propertiesView-filters-title" onPointerDown={action(() => (this.openFilters = !this.openFilters))} style={{ backgroundColor: this.openFilters ? 'black' : '' }}>
- Filters
- <div className="propertiesView-filters-title-icon">
- <FontAwesomeIcon icon={this.openFilters ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
- </div>
- {!this.openFilters ? null : (
- <div className="propertiesView-filters-content" style={{ position: 'relative', height: 'auto' }}>
- <FilterPanel rootDoc={this.selectedDoc ?? Doc.ActiveDashboard!} />
- </div>
- )}
- </div>
- );
+ return <PropertiesSection
+ title="Filters"
+ content={<div className="propertiesView-content filters" style={{ position: 'relative', height: 'auto' }}>
+ <FilterPanel rootDoc={this.selectedDoc ?? Doc.ActiveDashboard!} />
+ </div>}
+ isOpen={this.openFilters}
+ setIsOpen={(bool) => this.openFilters = bool}
+ />
}
@computed get inkSubMenu() {
return (
<>
- {!this.isInk ? null : (
- <div className="propertiesView-appearance">
- <div className="propertiesView-appearance-title" onPointerDown={action(() => (this.openAppearance = !this.openAppearance))} style={{ backgroundColor: this.openAppearance ? 'black' : '' }}>
- Appearance
- <div className="propertiesView-appearance-title-icon">
- <FontAwesomeIcon icon={this.openAppearance ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
- </div>
- {!this.openAppearance ? null : <div className="propertiesView-appearance-content">{this.appearanceEditor}</div>}
- </div>
- )}
-
- <div className="propertiesView-transform">
- <div className="propertiesView-transform-title" onPointerDown={action(() => (this.openTransform = !this.openTransform))} style={{ backgroundColor: this.openTransform ? 'black' : '' }}>
- Transform
- <div className="propertiesView-transform-title-icon">
- <FontAwesomeIcon icon={this.openTransform ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
- </div>
- {this.openTransform ? <div className="propertiesView-transform-content">{this.transformEditor}</div> : null}
- </div>
+ <PropertiesSection
+ title="Appearance"
+ content={this.isInk ? this.appearanceEditor : null}
+ isOpen={this.openAppearance}
+ setIsOpen={(bool) => this.openAppearance = bool}
+ />
+ <PropertiesSection
+ title="Transform"
+ content={this.transformEditor}
+ isOpen={this.openTransform}
+ setIsOpen={(bool) => this.openTransform = bool}
+ />
</>
);
}
@computed get fieldsSubMenu() {
- return (
- <div className="propertiesView-fields">
- <div className="propertiesView-fields-title" onPointerDown={action(() => (this.openFields = !this.openFields))} style={{ backgroundColor: this.openFields ? 'black' : '' }}>
- Fields {'&'} Tags
- <div className="propertiesView-fields-title-icon">
- <FontAwesomeIcon icon={this.openFields ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
- </div>
- {!Doc.noviceMode && this.openFields ? (
- <div className="propertiesView-fields-checkbox">
- {this.fieldsCheckbox}
- <div className="propertiesView-fields-checkbox-text">Layout</div>
- </div>
- ) : null}
- {!this.openFields ? null : <div className="propertiesView-fields-content">{Doc.noviceMode ? this.noviceFields : this.expandedField}</div>}
- </div>
- );
+ return <PropertiesSection
+ title="Fields & Tags"
+ content={<div className="propertiesView-content fields">{
+ Doc.noviceMode ? this.noviceFields : this.expandedField}
+ </div>}
+ isOpen={this.openFields}
+ setIsOpen={(bool) => this.openFields = bool}
+ />
}
@computed get contextsSubMenu() {
- return (
- <div className="propertiesView-contexts">
- <div className="propertiesView-contexts-title" onPointerDown={action(() => (this.openContexts = !this.openContexts))} style={{ backgroundColor: this.openContexts ? 'black' : '' }}>
- Other Contexts
- <div className="propertiesView-contexts-title-icon">
- <FontAwesomeIcon icon={this.openContexts ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
- </div>
- {this.openContexts ? <div className="propertiesView-contexts-content">{this.contexts}</div> : null}
- </div>
- );
+ return <PropertiesSection
+ title="Other Contexts"
+ content={this.contexts}
+ isOpen={this.openContexts}
+ setIsOpen={(bool) => this.openContexts = bool}
+ />
}
@computed get linksSubMenu() {
- return (
- <div className="propertiesView-contexts">
- <div className="propertiesView-contexts-title" onPointerDown={action(() => (this.openLinks = !this.openLinks))} style={{ backgroundColor: this.openLinks ? 'black' : '' }}>
- Linked To
- <div className="propertiesView-contexts-title-icon">
- <FontAwesomeIcon icon={this.openLinks ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
- </div>
- {this.openLinks ? <div className="propertiesView-contexts-content">{this.links}</div> : null}
- </div>
- );
+ return <PropertiesSection
+ title="Linked To"
+ content={this.links}
+ isOpen={this.openLinks}
+ setIsOpen={(bool) => this.openLinks = bool}
+ />
}
@computed get layoutSubMenu() {
- return (
- <div className="propertiesView-layout">
- <div className="propertiesView-layout-title" onPointerDown={action(() => (this.openLayout = !this.openLayout))} style={{ backgroundColor: this.openLayout ? 'black' : '' }}>
- Layout
- <div className="propertiesView-layout-title-icon">
- <FontAwesomeIcon icon={this.openLayout ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
- </div>
- {this.openLayout ? <div className="propertiesView-layout-content">{this.layoutPreview}</div> : null}
- </div>
- );
+ return <PropertiesSection
+ title="Layout"
+ content={this.layoutPreview}
+ isOpen={this.openLayout}
+ setIsOpen={(bool) => this.openLayout = bool}
+ />
}
@computed get description() {
@@ -1269,6 +1268,226 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
if (scale > 1) scale = 1;
this.sourceAnchor && (this.sourceAnchor.followLinkZoomScale = scale);
};
+
+ @computed get linkProperties() {
+ const zoom = Number((NumCast(this.sourceAnchor?.followLinkZoomScale, 1) * 100).toPrecision(3));
+ const targZoom = this.sourceAnchor?.followLinkZoom;
+ const indent = 30;
+ const hasSelectedAnchor = LinkManager.Links(this.sourceAnchor).includes(LinkManager.currentLink!);
+
+ return <>
+ <div className="propertiesView-section" style={{ background: 'darkgray' }}>
+ <div className="propertiesView-input first" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
+ <p>Relationship</p>
+ {this.editRelationship}
+ </div>
+ <div className="propertiesView-input" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
+ <p>Description</p>
+ {this.editDescription}
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Show link</p>
+ <button
+ style={{ background: !LinkManager.currentLink?.link_displayLine ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleLinkProp(e, 'link_displayLine')}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
+ <p>Auto-move anchors</p>
+ <button
+ style={{ background: !LinkManager.currentLink?.link_autoMoveAnchors ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleLinkProp(e, 'link_autoMoveAnchors')}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
+ <p>Display arrow</p>
+ <button
+ style={{ background: !LinkManager.currentLink?.link_displayArrow ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleLinkProp(e, 'link_displayArrow')}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+ </button>
+ </div>
+ </div>
+ {!hasSelectedAnchor ? null : (
+ <div className="propertiesView-section">
+ <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 84px)' }}>
+ <p>Follow by</p>
+ <select onChange={e => this.changeFollowBehavior(e.currentTarget.value === 'Default' ? undefined : e.currentTarget.value)} value={Cast(this.sourceAnchor?.followLinkLocation, 'string', null)}>
+ <option value={undefined}>Default</option>
+ <option value={OpenWhere.addLeft}>Opening in new left pane</option>
+ <option value={OpenWhere.addRight}>Opening in new right pane</option>
+ <option value={OpenWhere.replaceLeft}>Replacing left tab</option>
+ <option value={OpenWhere.replaceRight}>Replacing right tab</option>
+ <option value={OpenWhere.fullScreen}>Overlaying current tab</option>
+ <option value={OpenWhere.lightbox}>Opening in lightbox</option>
+ <option value={OpenWhere.add}>Opening in new tab</option>
+ <option value={OpenWhere.replace}>Replacing current tab</option>
+ <option value={OpenWhere.inParent}>Opening in same collection</option>
+ {LinkManager.currentLink?.linksToAnnotation ? <option value="openExternal">Open in external page</option> : null}
+ </select>
+ </div>
+ <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 134px) 50px' }}>
+ <p>Animation</p>
+ <select style={{ width: '100%', gridColumn: 2 }} onChange={e => this.changeAnimationBehavior(e.currentTarget.value)} value={StrCast(this.sourceAnchor?.followLinkAnimEffect, 'default')}>
+ <option value="default">Default</option>
+ {[PresEffect.None, PresEffect.Zoom, PresEffect.Lightspeed, PresEffect.Fade, PresEffect.Flip, PresEffect.Rotate, PresEffect.Bounce, PresEffect.Roll].map(effect => (
+ <option key={effect.toString()} value={effect.toString()}>
+ {effect.toString()}
+ </option>
+ ))}
+ </select>
+ <div className="effectDirection" style={{ marginLeft: '10px', display: 'grid', width: 40, height: 36, gridColumn: 3, gridTemplateRows: '12px 12px 12px' }}>
+ {this.animationDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
+ {this.animationDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
+ {this.animationDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
+ {this.animationDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
+ {this.animationDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
+ </div>
+ </div>
+ {PresBox.inputter(
+ '0.1',
+ '0.1',
+ '10',
+ NumCast(this.sourceAnchor?.followLinkTransitionTime) / 1000,
+ true,
+ (val: string) => PresBox.SetTransitionTime(val, (timeInMS: number) => this.sourceAnchor && (this.sourceAnchor.followLinkTransitionTime = timeInMS)),
+ indent
+ )}{' '}
+ <div
+ className={'slider-headers'}
+ style={{
+ display: 'grid',
+ justifyContent: 'space-between',
+ width: `calc(100% - ${indent * 2}px)`,
+ marginLeft: indent,
+ marginRight: indent,
+ gridTemplateColumns: 'auto auto',
+ borderTop: 'solid',
+ }}>
+ <div className="slider-text">Fast</div>
+ <div className="slider-text">Slow</div>
+ </div>{' '}
+ <div className="propertiesView-input inline">
+ <p>Play Target Audio</p>
+ <button
+ style={{ background: !this.sourceAnchor?.followLinkAudio ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkAudio', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Zoom Text Selections</p>
+ <button
+ style={{ background: !this.sourceAnchor?.followLinkZoomText ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoomText', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Toggle Follow to Outer Context</p>
+ <button
+ style={{ background: !this.sourceAnchor?.followLinkToOuterContext ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToOuterContext', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faWindowMaximize as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Toggle Target (Show/Hide)</p>
+ <button
+ style={{ background: !this.sourceAnchor?.followLinkToggle ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToggle', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Ease Transitions</p>
+ <button
+ style={{ background: this.sourceAnchor?.followLinkEase === 'linear' ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkEase', this.sourceAnchor, 'ease', 'linear')}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Capture Offset to Target</p>
+ <button
+ style={{ background: this.sourceAnchor?.followLinkXoffset === undefined ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => {
+ this.toggleAnchorProp(e, 'followLinkXoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.x) - NumCast(this.sourceAnchor?.x), undefined);
+ this.toggleAnchorProp(e, 'followLinkYoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.y) - NumCast(this.sourceAnchor?.y), undefined);
+ }}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Center Target (no zoom)</p>
+ <button
+ style={{ background: this.sourceAnchor?.followLinkZoom ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline" style={{ display: 'grid', gridTemplateColumns: '78px calc(100% - 108px) 50px' }}>
+ <p>Zoom %</p>
+ <div className="ribbon-property" style={{ display: !targZoom ? 'none' : 'inline-flex' }}>
+ <input className="presBox-input" style={{ width: '100%' }} readOnly={true} type="number" value={zoom} />
+ <div className="ribbon-propertyUpDown" style={{ display: 'flex', flexDirection: 'column' }}>
+ <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), 0.1))}>
+ <FontAwesomeIcon icon={'caret-up'} />
+ </div>
+ <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), -0.1))}>
+ <FontAwesomeIcon icon={'caret-down'} />
+ </div>
+ </div>
+ </div>
+ <button
+ style={{ background: !targZoom || this.sourceAnchor?.followLinkZoomScale === 0 ? '' : '#4476f7', borderRadius: 3, gridColumn: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+ </button>
+ </div>
+ {!targZoom ? null : PresBox.inputter('0', '1', '100', zoom, true, this.setZoom, 30)}
+ <div
+ className={'slider-headers'}
+ style={{
+ display: !targZoom ? 'none' : 'grid',
+ justifyContent: 'space-between',
+ width: `calc(100% - ${indent * 2}px)`,
+ marginLeft: indent,
+ marginRight: indent,
+ gridTemplateColumns: 'auto auto',
+ borderTop: 'solid',
+ }}>
+ <div className="slider-text">0%</div>
+ <div className="slider-text">100%</div>
+ </div>{' '}
+ </div>
+ )}
+ </>
+ }
/**
* Handles adding and removing members from the sharing panel
@@ -1283,9 +1502,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
render() {
const isNovice = Doc.noviceMode;
- const zoom = Number((NumCast(this.sourceAnchor?.followLinkZoomScale, 1) * 100).toPrecision(3));
- const targZoom = this.sourceAnchor?.followLinkZoom;
- const indent = 30;
const hasSelectedAnchor = LinkManager.Links(this.sourceAnchor).includes(LinkManager.currentLink!);
if (!this.selectedDoc && !this.isPres) {
return (
@@ -1301,243 +1517,26 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div
className="propertiesView"
style={{
+ background: StrCast(Doc.UserDoc().userBackgroundColor),
+ color: StrCast(Doc.UserDoc().userColor),
width: this.props.width,
minWidth: this.props.width,
- //overflowY: this.scrolling ? "scroll" : "visible"
}}>
<div className="propertiesView-title" style={{ width: this.props.width }}>
Properties
</div>
<div className="propertiesView-name">{this.editableTitle}</div>
-
+ <div className="propertiesView-type">{this.type}</div>
{this.contextsSubMenu}
-
{this.linksSubMenu}
{!this.selectedDoc || !LinkManager.currentLink || (!hasSelectedAnchor && this.selectedDoc !== LinkManager.currentLink) ? null : (
- <>
- <div className="propertiesView-section" style={{ background: 'darkgray' }}>
- <div className="propertiesView-input first" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
- <p>Relationship</p>
- {this.editRelationship}
- </div>
- <div className="propertiesView-input" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
- <p>Description</p>
- {this.editDescription}
- </div>
- <div className="propertiesView-input inline">
- <p>Show link</p>
- <button
- style={{ background: !LinkManager.currentLink?.link_displayLine ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleLinkProp(e, 'link_displayLine')}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
- <p>Auto-move anchors</p>
- <button
- style={{ background: !LinkManager.currentLink?.link_autoMoveAnchors ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleLinkProp(e, 'link_autoMoveAnchors')}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
- <p>Display arrow</p>
- <button
- style={{ background: !LinkManager.currentLink?.link_displayArrow ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleLinkProp(e, 'link_displayArrow')}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
- </button>
- </div>
- </div>
- {!hasSelectedAnchor ? null : (
- <div className="propertiesView-section">
- <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 84px)' }}>
- <p>Follow by</p>
- <select onChange={e => this.changeFollowBehavior(e.currentTarget.value === 'Default' ? undefined : e.currentTarget.value)} value={Cast(this.sourceAnchor?.followLinkLocation, 'string', null)}>
- <option value={undefined}>Default</option>
- <option value={OpenWhere.addLeft}>Opening in new left pane</option>
- <option value={OpenWhere.addRight}>Opening in new right pane</option>
- <option value={OpenWhere.replaceLeft}>Replacing left tab</option>
- <option value={OpenWhere.replaceRight}>Replacing right tab</option>
- <option value={OpenWhere.fullScreen}>Overlaying current tab</option>
- <option value={OpenWhere.lightbox}>Opening in lightbox</option>
- <option value={OpenWhere.add}>Opening in new tab</option>
- <option value={OpenWhere.replace}>Replacing current tab</option>
- <option value={OpenWhere.inParent}>Opening in same collection</option>
- {LinkManager.currentLink?.linksToAnnotation ? <option value="openExternal">Open in external page</option> : null}
- </select>
- </div>
- <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 134px) 50px' }}>
- <p>Animation</p>
- <select style={{ width: '100%', gridColumn: 2 }} onChange={e => this.changeAnimationBehavior(e.currentTarget.value)} value={StrCast(this.sourceAnchor?.followLinkAnimEffect, 'default')}>
- <option value="default">Default</option>
- {[PresEffect.None, PresEffect.Zoom, PresEffect.Lightspeed, PresEffect.Fade, PresEffect.Flip, PresEffect.Rotate, PresEffect.Bounce, PresEffect.Roll].map(effect => (
- <option key={effect.toString()} value={effect.toString()}>
- {effect.toString()}
- </option>
- ))}
- </select>
- <div className="effectDirection" style={{ marginLeft: '10px', display: 'grid', width: 40, height: 36, gridColumn: 3, gridTemplateRows: '12px 12px 12px' }}>
- {this.animationDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
- {this.animationDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
- {this.animationDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
- {this.animationDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
- {this.animationDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
- </div>
- </div>
- {PresBox.inputter(
- '0.1',
- '0.1',
- '10',
- NumCast(this.sourceAnchor?.followLinkTransitionTime) / 1000,
- true,
- (val: string) => PresBox.SetTransitionTime(val, (timeInMS: number) => this.sourceAnchor && (this.sourceAnchor.followLinkTransitionTime = timeInMS)),
- indent
- )}{' '}
- <div
- className={'slider-headers'}
- style={{
- display: 'grid',
- justifyContent: 'space-between',
- width: `calc(100% - ${indent * 2}px)`,
- marginLeft: indent,
- marginRight: indent,
- gridTemplateColumns: 'auto auto',
- borderTop: 'solid',
- }}>
- <div className="slider-text">Fast</div>
- <div className="slider-text">Slow</div>
- </div>{' '}
- <div className="propertiesView-input inline">
- <p>Play Target Audio</p>
- <button
- style={{ background: !this.sourceAnchor?.followLinkAudio ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkAudio', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline">
- <p>Zoom Text Selections</p>
- <button
- style={{ background: !this.sourceAnchor?.followLinkZoomText ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoomText', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline">
- <p>Toggle Follow to Outer Context</p>
- <button
- style={{ background: !this.sourceAnchor?.followLinkToOuterContext ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToOuterContext', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faWindowMaximize as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline">
- <p>Toggle Target (Show/Hide)</p>
- <button
- style={{ background: !this.sourceAnchor?.followLinkToggle ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToggle', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline">
- <p>Ease Transitions</p>
- <button
- style={{ background: this.sourceAnchor?.followLinkEase === 'linear' ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkEase', this.sourceAnchor, 'ease', 'linear')}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline">
- <p>Capture Offset to Target</p>
- <button
- style={{ background: this.sourceAnchor?.followLinkXoffset === undefined ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => {
- this.toggleAnchorProp(e, 'followLinkXoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.x) - NumCast(this.sourceAnchor?.x), undefined);
- this.toggleAnchorProp(e, 'followLinkYoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.y) - NumCast(this.sourceAnchor?.y), undefined);
- }}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline">
- <p>Center Target (no zoom)</p>
- <button
- style={{ background: this.sourceAnchor?.followLinkZoom ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline" style={{ display: 'grid', gridTemplateColumns: '78px calc(100% - 108px) 50px' }}>
- <p>Zoom %</p>
- <div className="ribbon-property" style={{ display: !targZoom ? 'none' : 'inline-flex' }}>
- <input className="presBox-input" style={{ width: '100%' }} readOnly={true} type="number" value={zoom} />
- <div className="ribbon-propertyUpDown" style={{ display: 'flex', flexDirection: 'column' }}>
- <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), 0.1))}>
- <FontAwesomeIcon icon={'caret-up'} />
- </div>
- <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), -0.1))}>
- <FontAwesomeIcon icon={'caret-down'} />
- </div>
- </div>
- </div>
- <button
- style={{ background: !targZoom || this.sourceAnchor?.followLinkZoomScale === 0 ? '' : '#4476f7', borderRadius: 3, gridColumn: 3 }}
- onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
- </button>
- </div>
- {!targZoom ? null : PresBox.inputter('0', '1', '100', zoom, true, this.setZoom, 30)}
- <div
- className={'slider-headers'}
- style={{
- display: !targZoom ? 'none' : 'grid',
- justifyContent: 'space-between',
- width: `calc(100% - ${indent * 2}px)`,
- marginLeft: indent,
- marginRight: indent,
- gridTemplateColumns: 'auto auto',
- borderTop: 'solid',
- }}>
- <div className="slider-text">0%</div>
- <div className="slider-text">100%</div>
- </div>{' '}
- </div>
- )}
- </>
+ this.linkProperties
)}
-
{this.inkSubMenu}
-
{this.optionsSubMenu}
-
{this.fieldsSubMenu}
-
{isNovice ? null : this.sharingSubMenu}
-
{isNovice ? null : this.filtersSubMenu}
-
{isNovice ? null : this.layoutSubMenu}
</div>
);
@@ -1549,7 +1548,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
: PresBox.targetRenderedDoc(PresBox.Instance.activeItem)?.type;
return (
<div className="propertiesView" style={{ width: this.props.width }}>
- <div className="propertiesView-title" style={{ width: this.props.width }}>
+ <div className="propertiesView-sectionTitle" style={{ width: this.props.width }}>
Presentation
</div>
<div className="propertiesView-name" style={{ borderBottom: 0 }}>
@@ -1564,7 +1563,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div className="propertiesView-presTrails-title" onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Transitions
<div className="propertiesView-presTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+ <FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" />
</div>
</div>
{this.openPresTransitions ? <div className="propertiesView-presTrails-content">{PresBox.Instance.transitionDropdown}</div> : null}
@@ -1578,7 +1577,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Visibilty
<div className="propertiesView-presTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+ <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" />
</div>
</div>
{this.openPresVisibilityAndDuration ? <div className="propertiesView-presTrails-content">{PresBox.Instance.visibiltyDurationDropdown}</div> : null}
@@ -1589,7 +1588,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div className="propertiesView-presTrails-title" onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Progressivize
<div className="propertiesView-presTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+ <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" />
</div>
</div>
{this.openPresProgressivize ? <div className="propertiesView-presTrails-content">{PresBox.Instance.progressivizeDropdown}</div> : null}
@@ -1600,7 +1599,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div className="propertiesView-presTrails-title" onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))} style={{ backgroundColor: this.openSlideOptions ? 'black' : '' }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={type === DocumentType.AUDIO ? 'file-audio' : 'file-video'} /> &nbsp; {type === DocumentType.AUDIO ? 'Audio Options' : 'Video Options'}
<div className="propertiesView-presTrails-title-icon">
- <FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+ <FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg" />
</div>
</div>
{this.openSlideOptions ? <div className="propertiesView-presTrails-content">{PresBox.Instance.mediaOptionsDropdown}</div> : null}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 96502115d..472eefa6a 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -160,7 +160,9 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
''
);
case StyleProp.Color:
- if (MainView.Instance.LastButton === doc) return Colors.DARK_GRAY;
+ if (MainView.Instance.LastButton === doc) return Doc.UserDoc().userBackgroundColor;
+ if (Doc.IsSystem(doc!)) return StrCast(Doc.UserDoc().userColor)
+ if (doc?.type === DocumentType.FONTICON) return Doc.UserDoc().userColor;
const docColor: Opt<string> = StrCast(doc?.[fieldKey + 'color'], StrCast(doc?._color));
if (docColor) return docColor;
const docView = props?.DocumentView?.();
@@ -196,7 +198,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
? 15
: 0;
case StyleProp.BackgroundColor: {
- if (MainView.Instance.LastButton === doc) return Colors.LIGHT_GRAY;
+ if (MainView.Instance.LastButton === doc) return StrCast(Doc.UserDoc().userColor); // hack to indicate active menu panel item
let docColor: Opt<string> = StrCast(doc?.[fieldKey + '_backgroundColor'], StrCast(doc?._backgroundColor, isCaption ? 'rgba(0,0,0,0.4)' : ''));
// prettier-ignore
switch (doc?.type) {
@@ -221,9 +223,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
case DocumentType.COL:
if (StrCast(Doc.LayoutField(doc)).includes(SliderBox.name)) break;
docColor = docColor || (Doc.IsSystem(doc)
- ? darkScheme()
- ? undefined
- : undefined // system docs (seen in treeView) get a grayish background
+ ? StrCast(Doc.UserDoc().userBackgroundColor)
: doc.annotationOn
? '#00000010' // faint interior for collections on PDFs, images, etc
: doc?._isGroup
diff --git a/src/client/views/UndoStack.scss b/src/client/views/UndoStack.scss
index ab21e6d7e..192b99a12 100644
--- a/src/client/views/UndoStack.scss
+++ b/src/client/views/UndoStack.scss
@@ -2,9 +2,10 @@
height: 100%;
display: flex;
flex-direction: column;
+ justify-content: center;
+ align-items: center;
position: relative;
pointer-events: all;
- padding-left: 4px;
}
.undoStack-resultContainer {
@@ -21,9 +22,11 @@
}
.undoStack-commandsContainer {
- background-color: whitesmoke;
flex: 1 1 auto;
overflow-y: scroll;
- height: 30px;
+ height: fit-content;
+ width: 200px;
border-radius: 5px;
+ padding: 5px;
+ max-height: 200px;
}
diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx
index f5af09e5b..28f1b8bd9 100644
--- a/src/client/views/UndoStack.tsx
+++ b/src/client/views/UndoStack.tsx
@@ -3,6 +3,9 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { UndoManager } from '../util/UndoManager';
import './UndoStack.scss';
+import { StrCast } from '../../fields/Types';
+import { Doc } from '../../fields/Doc';
+import { Popup, Type } from 'browndash-components';
interface UndoStackProps {
width?: number;
@@ -15,32 +18,31 @@ export class UndoStack extends React.Component<UndoStackProps> {
@observable static Expand: boolean;
render() {
return this.props.inline && UndoStack.HideInline ? null : (
- <div
- className="undoStack-outerContainer"
- style={{ width: this.props.width, height: this.props.height ? (UndoStack.Expand ? 4 : 1) * this.props.height : undefined, top: UndoStack.Expand && this.props.height ? -this.props.height * 3 : undefined }}
- onClick={action(e => (UndoStack.Expand = !UndoStack.Expand))}
- onDoubleClick={action(e => (UndoStack.Expand = UndoStack.HideInline = false))}>
- <div className="undoStack-commandsContainer" ref={r => r?.scroll({ behavior: 'auto', top: r?.scrollHeight + 20 })} style={{ background: UndoManager.batchCounter.get() ? 'yellow' : undefined }}>
- <div className="undoStack-resultContainer" key={0}>
- <div className="undoStack-commandString" style={{ fontWeight: 'bold', textAlign: 'center' }}>
- Undo/Redo Stack
- </div>
- </div>
- {UndoManager.undoStackNames.map((name, i) => (
- <div className="undoStack-resultContainer" key={i}>
- <div className="undoStack-commandString">{name.replace(/[^\.]*\./, '')}</div>
- </div>
- ))}
- {Array.from(UndoManager.redoStackNames)
- .reverse()
- .map((name, i) => (
+ <div className="undoStack-outerContainer">
+ <Popup
+ text={'Undo/Redo Stack'}
+ color={StrCast(Doc.UserDoc().userVariantColor)}
+ placement={`top-start`}
+ type={Type.TERT}
+ popup={
+ <div className="undoStack-commandsContainer" ref={r => r?.scroll({ behavior: 'auto', top: r?.scrollHeight + 20 })} style={{ background: UndoManager.batchCounter.get() ? 'yellow' : undefined }}>
+ {UndoManager.undoStackNames.map((name, i) => (
<div className="undoStack-resultContainer" key={i}>
- <div className="undoStack-commandString" style={{ fontWeight: 'bold', color: 'red' }}>
- {name.replace(/[^\.]*\./, '')}
- </div>
+ <div className="undoStack-commandString">{name.replace(/[^\.]*\./, '')}</div>
</div>
))}
- </div>
+ {Array.from(UndoManager.redoStackNames)
+ .reverse()
+ .map((name, i) => (
+ <div className="undoStack-resultContainer" key={i}>
+ <div className="undoStack-commandString" style={{ fontWeight: 'bold', color: 'red' }}>
+ {name.replace(/[^\.]*\./, '')}
+ </div>
+ </div>
+ ))}
+ </div>
+ }
+ />
</div>
);
}
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index 9db8fe532..6eeccc94e 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -10,650 +10,13 @@
border-bottom: $standard-border;
padding: 0 10px;
align-items: center;
+ overflow-x: scroll;
+ &::-webkit-scrollbar {
+ display: none;
+ }
- .collectionMenu-hardCodedButton {
- cursor: pointer;
- color: $white;
- width: 25px;
- height: 25px;
- padding: 5;
- text-align: center;
+ .hardCodedButtons {
display: flex;
- justify-content: center;
- align-items: center;
- position: relative;
- transition: 0.2s;
- border-radius: 3px;
-
- &:hover {
- background-color: rgba(0, 0, 0, 0.2);
- }
+ flex-direction: row;
}
-}
-
-// .collectionMenu-cont {
-// position: relative;
-// display: inline-flex;
-// width: 100%;
-// opacity: 0.9;
-// z-index: 901;
-// transition: top .5s;
-// background: $dark-gray;
-// color: $white;
-// transform-origin: top left;
-// top: 0;
-// width: 100%;
-
-// .recordButtonOutline {
-// border-radius: 100%;
-// width: 18px;
-// height: 18px;
-// border: solid 1px $white;
-// display: flex;
-// align-items: center;
-// justify-content: center;
-// }
-
-// .recordButtonInner {
-// border-radius: 100%;
-// width: 70%;
-// height: 70%;
-// background: $white;
-// }
-
-// .collectionMenu {
-// display: flex;
-// height: 100%;
-// overflow: visible;
-// z-index: 901;
-// border: unset;
-
-// .collectionMenu-divider {
-// height: 100%;
-// margin-left: 3px;
-// margin-right: 3px;
-// width: 2px;
-// background-color: $medium-gray;
-// }
-
-// .collectionViewBaseChrome {
-// display: flex;
-// align-items: center;
-
-// .collectionViewBaseChrome-viewPicker {
-// font-size: $small-text;
-// outline-color: $black;
-// color: $white;
-// border: none;
-// background: $dark-gray;
-// }
-
-// .collectionViewBaseChrome-viewPicker:focus {
-// outline: none;
-// border: none;
-// }
-
-// .collectionViewBaseChrome-viewPicker:active {
-// outline-color: $black;
-// }
-
-// .collectionViewBaseChrome-button {
-// font-size: $small-text;
-// text-transform: uppercase;
-// letter-spacing: 2px;
-// background: $white;
-// color: $pink;
-// outline-color: $black;
-// border: none;
-// padding: 12px 10px 11px 10px;
-// margin-left: 10px;
-// }
-
-// .collectionViewBaseChrome-cmdPicker {
-// margin-left: 3px;
-// margin-right: 0px;
-// font-size: $small-text;
-// text-transform: capitalize;
-// color: $white;
-// border: none;
-// background: $dark-gray;
-// }
-
-// .collectionViewBaseChrome-cmdPicker:focus {
-// border: none;
-// outline: none;
-// }
-
-// .commandEntry-outerDiv {
-// pointer-events: all;
-// background-color: transparent;
-// display: flex;
-// flex-direction: row;
-// align-items: center;
-// justify-content: center;
-// height: 100%;
-// overflow: hidden;
-
-// .commandEntry-drop {
-// color: $white;
-// width: 30px;
-// margin-top: auto;
-// margin-bottom: auto;
-// }
-// }
-
-// .commandEntry-outerDiv:hover{
-// background-color: $drop-shadow;
-
-// .collectionViewBaseChrome-viewPicker,
-// .collectionViewBaseChrome-cmdPicker{
-// background: $dark-gray;
-// }
-// }
-
-// .collectionViewBaseChrome-collapse {
-// transition: all .5s, opacity 0.3s;
-// position: absolute;
-// width: 30px;
-// transform-origin: top left;
-// pointer-events: all;
-// // margin-top: 10px;
-// }
-
-// @media only screen and (max-device-width: 480px) {
-// .collectionViewBaseChrome-collapse {
-// display: none;
-// }
-// }
-
-// .collectionViewBaseChrome-template,
-// .collectionViewBaseChrome-viewModes {
-// align-items: center;
-// height: 100%;
-// display: flex;
-// background: transparent;
-// color: $medium-gray;
-// justify-content: center;
-// }
-
-// .collectionViewBaseChrome-viewSpecs {
-// margin-left: 5px;
-// display: grid;
-// border: none;
-// border-right: solid $medium-gray 1px;
-
-// .collectionViewBaseChrome-filterIcon {
-// position: relative;
-// display: flex;
-// margin: auto;
-// background: $dark-gray;
-// color: $white;
-// width: 30px;
-// height: 30px;
-// align-items: center;
-// justify-content: center;
-// border: none;
-// border-right: solid $medium-gray 1px;
-// }
-
-// .collectionViewBaseChrome-viewSpecsInput {
-// padding: 12px 10px 11px 10px;
-// border: 0px;
-// color: $medium-gray;
-// text-align: center;
-// letter-spacing: 2px;
-// outline-color: $black;
-// font-size: $small-text;
-// background: $white;
-// height: 100%;
-// width: 75px;
-// }
-
-// .collectionViewBaseChrome-viewSpecsMenu {
-// overflow: hidden;
-// transition: height .5s, display .5s;
-// position: absolute;
-// top: 60px;
-// z-index: 100;
-// display: flex;
-// flex-direction: column;
-// background: $white;
-// box-shadow: $medium-gray 2px 2px 4px;
-
-// .qs-datepicker {
-// left: unset;
-// right: 0;
-// }
-
-// .collectionViewBaseChrome-viewSpecsMenu-row {
-// display: grid;
-// grid-template-columns: 150px 200px 150px;
-// margin-top: 10px;
-// margin-right: 10px;
-
-// .collectionViewBaseChrome-viewSpecsMenu-rowLeft,
-// .collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
-// .collectionViewBaseChrome-viewSpecsMenu-rowRight {
-// font-size: $small-text;
-// letter-spacing: 2px;
-// color: $medium-gray;
-// margin-left: 10px;
-// padding: 5px;
-// border: none;
-// outline-color: $black;
-// }
-// }
-
-// .collectionViewBaseChrome-viewSpecsMenu-lastRow {
-// display: grid;
-// grid-template-columns: 1fr 1fr 1fr;
-// grid-gap: 10px;
-// margin: 10px;
-// }
-// }
-// }
-// }
-
-// .collectionStackingViewChrome-cont,
-// .collectionTreeViewChrome-cont,
-// .collection3DCarouselViewChrome-cont {
-// display: flex;
-// justify-content: space-between;
-// }
-
-// .collectionGridViewChrome-cont {
-// display: flex;
-// margin-left: 10;
-
-// .collectionGridViewChrome-viewPicker {
-// font-size: $small-text;
-// //text-transform: uppercase;
-// //letter-spacing: 2px;
-// background: $dark-gray;
-// color: $white;
-// outline-color: $black;
-// color: $white;
-// border: none;
-// border-right: solid $medium-gray 1px;
-// }
-
-// .collectionGridViewChrome-viewPicker:active {
-// outline-color: $black;
-// }
-
-// .grid-control {
-// align-self: center;
-// display: flex;
-// flex-direction: row;
-// margin-right: 5px;
-
-// .grid-icon {
-// margin-right: 5px;
-// align-self: center;
-// }
-
-// .flexLabel {
-// margin-bottom: 0;
-// }
-
-// .collectionGridViewChrome-entryBox {
-// width: 50%;
-// color: $black;
-// }
-
-// .collectionGridViewChrome-columnButton {
-// color: $black;
-// }
-// }
-// }
-
-// .collectionStackingViewChrome-sort,
-// .collectionTreeViewChrome-sort {
-// display: flex;
-// align-items: center;
-// justify-content: space-between;
-
-// .collectionStackingViewChrome-sortIcon,
-// .collectionTreeViewChrome-sortIcon {
-// transition: transform .5s;
-// margin-left: 10px;
-// }
-// }
-
-// button:hover {
-// transform: scale(1);
-// }
-
-
-// .collectionStackingViewChrome-pivotField-cont,
-// .collectionTreeViewChrome-pivotField-cont,
-// .collection3DCarouselViewChrome-scrollSpeed-cont {
-// justify-self: right;
-// align-items: center;
-// display: flex;
-// grid-auto-columns: auto;
-// font-size: $small-text;
-// letter-spacing: 2px;
-
-// .collectionStackingViewChrome-pivotField-label,
-// .collectionTreeViewChrome-pivotField-label,
-// .collection3DCarouselViewChrome-scrollSpeed-label {
-// grid-column: 1;
-// margin-right: 7px;
-// user-select: none;
-// font-family: $sans-serif;
-// letter-spacing: normal;
-// }
-
-// .collectionStackingViewChrome-sortIcon {
-// transition: transform .5s;
-// grid-column: 3;
-// text-align: center;
-// display: flex;
-// justify-content: center;
-// align-items: center;
-// cursor: pointer;
-// width: 25px;
-// height: 25px;
-// border-radius: 100%;
-// }
-
-// .collectionStackingViewChrome-sortIcon:hover {
-// background-color: $drop-shadow;
-// }
-
-// .collectionStackingViewChrome-pivotField,
-// .collectionTreeViewChrome-pivotField,
-// .collection3DCarouselViewChrome-scrollSpeed {
-// color: $white;
-// grid-column: 2;
-// grid-row: 1;
-// width: 90%;
-// min-width: 100px;
-// display: flex;
-// height: 80%;
-// border-radius: 7px;
-// align-items: center;
-// background: $white;
-
-// .editable-view-input,
-// input,
-// .editableView-container-editing-oneLine,
-// .editableView-container-editing {
-// margin: auto;
-// border: 0px;
-// color: $light-gray !important;
-// text-align: center;
-// letter-spacing: 2px;
-// outline-color: $black;
-// height: 100%;
-// }
-
-// .react-autosuggest__container {
-// margin: 0;
-// color: $medium-gray;
-// padding: 0px;
-// }
-// }
-// }
-
-// .collectionStackingViewChrome-pivotField:hover,
-// .collectionTreeViewChrome-pivotField:hover,
-// .collection3DCarouselViewChrome-scrollSpeed:hover {
-// cursor: text;
-// }
-
-// }
-// }
-
-// .collectionMenu-webUrlButtons {
-// margin-left: 44;
-// background: lightGray;
-// display: flex;
-// }
-
-// .webBox-urlEditor {
-// position: relative;
-// opacity: 0.9;
-// z-index: 901;
-// transition: top .5s;
-
-// .urlEditor {
-// display: grid;
-// grid-template-columns: 1fr auto;
-// padding-bottom: 10px;
-// overflow: hidden;
-// margin-top: 5px;
-// height: 35px;
-
-// .editorBase {
-// display: flex;
-
-// .editor-collapse {
-// transition: all .5s, opacity 0.3s;
-// position: absolute;
-// width: 40px;
-// transform-origin: top left;
-// }
-
-// .switchToText {
-// color: $medium-gray;
-// }
-
-// .switchToText:hover {
-// color: $dark-gray;
-// }
-// }
-
-// button:hover {
-// transform: scale(1);
-// }
-// }
-// }
-
-// .collectionMenu-urlInput {
-// padding: 12px 10px 11px 10px;
-// border: 0px;
-// color: $black;
-// font-size: $small-text;
-// letter-spacing: 2px;
-// outline-color: $black;
-// background: $white;
-// width: 100%;
-// min-width: 350px;
-// margin-right: 10px;
-// height: 100%;
-// }
-
-// .collectionFreeFormMenu-cont {
-// display: inline-flex;
-// position: relative;
-// align-items: center;
-// height: 100%;
-
-// .color-previewI {
-// width: 60%;
-// top: 80%;
-// position: absolute;
-// height: 4px;
-// }
-
-// .color-previewII {
-// width: 80%;
-// height: 80%;
-// margin-left: 10%;
-// position: absolute;
-// bottom: 5;
-// }
-
-// .btn-group {
-// display: grid;
-// grid-template-columns: auto auto auto auto;
-// margin: auto;
-// /* Make the buttons appear below each other */
-// }
-
-// .btn-draw {
-// display: inline-flex;
-// margin: auto;
-// /* Make the buttons appear below each other */
-// }
-
-// .fwdKeyframe,
-// .numKeyframe,
-// .backKeyframe {
-// cursor: pointer;
-// position: relative;
-// width: 20;
-// height: 30;
-// bottom: 0;
-// background: $dark-gray;
-// display: inline-flex;
-// align-items: center;
-// color: $white;
-// }
-
-// .backKeyframe {
-// svg {
-// display: block;
-// margin: auto;
-// }
-// }
-
-
-// .numKeyframe {
-// flex-direction: column;
-// padding-top: 5px;
-// }
-
-// .fwdKeyframe {
-// svg {
-// display: block;
-// margin: auto;
-// }
-
-// border-right: solid $medium-gray 1px;
-// }
-// }
-
-// .collectionSchemaViewChrome-cont {
-// display: flex;
-// font-size: $small-text;
-
-// .collectionSchemaViewChrome-toggle {
-// display: flex;
-// margin-left: 10px;
-// }
-
-// .collectionSchemaViewChrome-label {
-// text-transform: uppercase;
-// letter-spacing: 2px;
-// margin-right: 5px;
-// display: flex;
-// flex-direction: column;
-// justify-content: center;
-// }
-
-// .collectionSchemaViewChrome-toggler {
-// width: 100px;
-// height: 35px;
-// background-color: $black;
-// position: relative;
-// }
-
-// .collectionSchemaViewChrome-togglerButton {
-// width: 47px;
-// height: 30px;
-// background-color: $light-gray;
-// // position: absolute;
-// transition: all 0.5s ease;
-// // top: 3px;
-// margin-top: 3px;
-// color: $medium-gray;
-// letter-spacing: 2px;
-// text-transform: uppercase;
-// display: flex;
-// flex-direction: column;
-// justify-content: center;
-// text-align: center;
-
-// &.on {
-// margin-left: 3px;
-// }
-
-// &.off {
-// margin-left: 50px;
-// }
-// }
-// }
-
-
-// .commandEntry-outerDiv {
-// display: flex;
-// flex-direction: column;
-// height: 40px;
-// }
-
-// .commandEntry-inputArea {
-// display: flex;
-// flex-direction: row;
-// width: 150px;
-// margin: auto auto auto auto;
-// }
-
-// .react-autosuggest__container {
-// position: relative;
-// width: 100%;
-// margin-left: 5px;
-// margin-right: 5px;
-// }
-
-// .react-autosuggest__input {
-// border: 1px solid $light-gray;
-// border-radius: 4px;
-// width: 100%;
-// }
-
-// .react-autosuggest__input--focused {
-// outline: none;
-// }
-
-// .react-autosuggest__input--open {
-// border-bottom-left-radius: 0;
-// border-bottom-right-radius: 0;
-// }
-
-// .react-autosuggest__suggestions-container {
-// display: none;
-// }
-
-// .react-autosuggest__suggestions-container--open {
-// display: block;
-// position: fixed;
-// overflow-y: auto;
-// max-height: 400px;
-// width: 180px;
-// border: 1px solid $light-gray;
-// background-color: $white;
-// font-family: $sans-serif;
-// font-weight: 300;
-// font-size: $large-header;
-// border-bottom-left-radius: 4px;
-// border-bottom-right-radius: 4px;
-// z-index: 2;
-// }
-
-// .react-autosuggest__suggestions-list {
-// margin: 0;
-// padding: 0;
-// list-style-type: none;
-// }
-
-// .react-autosuggest__suggestion {
-// cursor: pointer;
-// padding: 10px 20px;
-// }
-
-// .react-autosuggest__suggestion--highlighted {
-// background-color: $light-gray;
-// } \ No newline at end of file
+} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 38692b924..9eb716763 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -2,23 +2,23 @@ import React = require('react');
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon, FontAwesomeIconProps } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
-import { action, computed, Lambda, observable, reaction, runInAction } from 'mobx';
+import { Toggle, ToggleType, Type } from 'browndash-components';
+import { Lambda, action, computed, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { ColorState } from 'react-color';
+import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { Document } from '../../../fields/documentSchemas';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
import { RichTextField } from '../../../fields/RichTextField';
import { listSpec } from '../../../fields/Schema';
-import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
+import { Document } from '../../../fields/documentSchemas';
import { GestureUtils } from '../../../pen-gestures/GestureUtils';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils';
-import { Docs } from '../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
import { DragManager } from '../../util/DragManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
@@ -28,21 +28,19 @@ import { undoBatch } from '../../util/UndoManager';
import { AntimodeMenu } from '../AntimodeMenu';
import { EditableView } from '../EditableView';
import { GestureOverlay } from '../GestureOverlay';
-import { Colors } from '../global/globalEnums';
import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from '../InkingStroke';
import { LightboxView } from '../LightboxView';
+import { MainView } from '../MainView';
+import { DefaultStyleProvider } from '../StyleProvider';
import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
import { DocumentView, OpenWhereMod } from '../nodes/DocumentView';
-import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
-import { DefaultStyleProvider } from '../StyleProvider';
import { CollectionDockingView } from './CollectionDockingView';
-import { CollectionLinearView } from './collectionLinear';
import './CollectionMenu.scss';
import { COLLECTION_BORDER_WIDTH } from './CollectionView';
import { TabDocView } from './TabDocView';
import { CollectionFreeFormView } from './collectionFreeForm';
-import { Group, IconButton, Toggle, ToggleType, Type } from 'browndash-components';
+import { CollectionLinearView } from './collectionLinear';
interface CollectionMenuProps {
panelHeight: () => number;
@@ -96,6 +94,15 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
}
};
+ @action
+ toggleProperties = () => {
+ if (MainView.Instance.propertiesWidth() > 0) {
+ SettingsManager.propertiesWidth = 0;
+ } else {
+ SettingsManager.propertiesWidth = 300;
+ }
+ };
+
buttonBarXf = () => {
if (!this._docBtnRef.current) return Transform.Identity();
const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
@@ -140,18 +147,30 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
}
render() {
- const propIcon = SettingsManager.headerBarHeight > 0 ? 'angle-double-up' : 'angle-double-down';
- const propTitle = SettingsManager.headerBarHeight > 0 ? 'Close Header Bar' : 'Open Header Bar';
+ const headerIcon = SettingsManager.headerBarHeight > 0 ? 'angle-double-up' : 'angle-double-down';
+ const headerTitle = SettingsManager.headerBarHeight > 0 ? 'Close Header Bar' : 'Open Header Bar';
+ const propIcon = SettingsManager.propertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left';
+ const propTitle = SettingsManager.propertiesWidth > 0 ? 'Close Properties' : 'Open Properties';
const hardCodedButtons = (
<div className={`hardCodedButtons`}>
<Toggle
toggleType={ToggleType.BUTTON}
type={Type.PRIM}
- color={Colors.LIGHT_GRAY}
+ color={StrCast(Doc.UserDoc().userColor)}
onClick={this.toggleTopBar}
toggleStatus={SettingsManager.headerBarHeight > 0}
+ icon={<FontAwesomeIcon icon={headerIcon} size="lg" />}
+ tooltip={headerTitle}
+ />
+ <Toggle
+ toggleType={ToggleType.BUTTON}
+ type={Type.PRIM}
+ color={StrCast(Doc.UserDoc().userColor)}
+ onClick={this.toggleProperties}
+ toggleStatus={SettingsManager.propertiesWidth > 0}
icon={<FontAwesomeIcon icon={propIcon} size="lg" />}
+ tooltip={propTitle}
/>
</div>
);
@@ -159,7 +178,11 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
// NEW BUTTONS
//dash col linear view buttons
const contMenuButtons = (
- <div className="collectionMenu-container">
+ <div className="collectionMenu-container"
+ style={{
+ background: StrCast(Doc.UserDoc().userBackgroundColor),
+ // borderColor: StrCast(Doc.UserDoc().userColor)
+ }} >
{this.contMenuButtons}
{hardCodedButtons}
</div>
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 4cd3885f5..09be9dc76 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -386,6 +386,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
@observable _headerHeight = 0;
@computed get content() {
const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor);
+ const color = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.Color);
const pointerEvents = () => (this.props.isContentActive() === false ? 'none' : undefined);
const titleBar = this.props.treeViewHideTitle || this.doc.treeViewHideTitle ? null : this.titleBar;
return (
@@ -402,6 +403,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
ref={r => !this.doc.treeViewHasOverlay && r && this.createTreeDropTarget(r)}
style={{
...(!titleBar ? { marginLeft: this.marginX(), paddingTop: this.marginTop() } : {}),
+ color: color(),
overflow: 'auto',
width: '100%',
height: '100%',
diff --git a/src/client/views/collections/TabDocView.scss b/src/client/views/collections/TabDocView.scss
index 58605c3f4..13bb3a577 100644
--- a/src/client/views/collections/TabDocView.scss
+++ b/src/client/views/collections/TabDocView.scss
@@ -65,11 +65,7 @@ input.lm_title {
}
.miniMap {
- position: absolute;
overflow: hidden;
- right: 15;
- bottom: 15;
- border: solid 1px;
width: 100%;
height: 100%;
transition: all 0.5s;
@@ -90,18 +86,5 @@ input.lm_title {
cursor: pointer;
position: absolute;
bottom: 5;
- display: flex;
right: 5;
- width: 25px;
- height: 25px;
- border-radius: 3px;
- padding: 2px;
- justify-content: center;
- align-items: center;
- align-content: center;
- background-color: $light-gray;
-
- &:hover {
- box-shadow: none;
- }
}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 4d780f46b..714619a74 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -34,6 +34,7 @@ import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormV
import { CollectionView } from './CollectionView';
import './TabDocView.scss';
import React = require('react');
+import { Popup, Toggle, Type } from 'browndash-components';
const _global = (window /* browser */ || global) /* node */ as any;
interface TabDocViewProps {
@@ -573,63 +574,53 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
const miniTop = 50 + ((NumCast(this.props.document._freeform_panY) - this.renderBounds.cy) / this.renderBounds.dim) * 100 - miniHeight / 2;
const miniSize = this.returnMiniSize();
return (
- <>
- {' '}
- {this.props.document?.layout_hideMinimap ? null : (
- <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.props.background() }}>
- <CollectionFreeFormView
- Document={this.props.document}
- docViewPath={returnEmptyDoclist}
- childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
- noOverlay={true} // don't render overlay Docs since they won't scale
- setHeight={returnFalse}
- isContentActive={emptyFunction}
- isAnyChildContentActive={returnFalse}
- select={emptyFunction}
- isSelected={returnFalse}
- dontRegisterView={true}
- fieldKey={Doc.LayoutFieldKey(this.props.document)}
- bringToFront={emptyFunction}
- rootSelected={returnTrue}
- addDocument={returnFalse}
- moveDocument={returnFalse}
- removeDocument={returnFalse}
- PanelWidth={this.returnMiniSize}
- PanelHeight={this.returnMiniSize}
- ScreenToLocalTransform={Transform.Identity}
- renderDepth={0}
- whenChildContentsActiveChanged={emptyFunction}
- focus={emptyFunction}
- styleProvider={TabMinimapView.miniStyleProvider}
- addDocTab={this.props.addDocTab}
- pinToPres={TabDocView.PinDoc}
- childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
- childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
- searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
- fitContentsToBox={returnTrue}
- />
- <div className="miniOverlay" onPointerDown={this.miniDown}>
- <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% ` }} />
+ <div className="miniMap-hidden">
+ <Popup
+ icon={<FontAwesomeIcon icon="globe-asia" size="lg" />}
+ color={StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}
+ type={Type.TERT}
+ onPointerDown={e => e.stopPropagation()}
+ placement={'top-end'}
+ popup={
+ <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.props.background() }}>
+ <CollectionFreeFormView
+ Document={this.props.document}
+ docViewPath={returnEmptyDoclist}
+ childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
+ noOverlay={true} // don't render overlay Docs since they won't scale
+ setHeight={returnFalse}
+ isContentActive={emptyFunction}
+ isAnyChildContentActive={returnFalse}
+ select={emptyFunction}
+ isSelected={returnFalse}
+ dontRegisterView={true}
+ fieldKey={Doc.LayoutFieldKey(this.props.document)}
+ bringToFront={emptyFunction}
+ rootSelected={returnTrue}
+ addDocument={returnFalse}
+ moveDocument={returnFalse}
+ removeDocument={returnFalse}
+ PanelWidth={this.returnMiniSize}
+ PanelHeight={this.returnMiniSize}
+ ScreenToLocalTransform={Transform.Identity}
+ renderDepth={0}
+ whenChildContentsActiveChanged={emptyFunction}
+ focus={emptyFunction}
+ styleProvider={TabMinimapView.miniStyleProvider}
+ addDocTab={this.props.addDocTab}
+ pinToPres={TabDocView.PinDoc}
+ childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
+ childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
+ searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
+ fitContentsToBox={returnTrue}
+ />
+ <div className="miniOverlay" onPointerDown={this.miniDown}>
+ <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% ` }} />
+ </div>
</div>
- </div>
- )}
- <Tooltip key="ttip" title={<div className="dash-tooltip">{this.props.document.layout_hideMinimap ? 'Open minimap' : 'Close minimap'}</div>}>
- <div
- className="miniMap-hidden"
- style={{
- color: this.props.document.layout_hideMinimap ? Colors.BLACK : Colors.WHITE,
- backgroundColor: this.props.document.layout_hideMinimap ? Colors.LIGHT_GRAY : Colors.MEDIUM_BLUE,
- boxShadow: this.props.document.layout_hideMinimap ? Shadows.STANDARD_SHADOW : undefined,
- }}
- onPointerDown={e => e.stopPropagation()}
- onClick={action(e => {
- e.stopPropagation();
- this.props.document!.layout_hideMinimap = !this.props.document!.layout_hideMinimap;
- })}>
- <FontAwesomeIcon icon="globe-asia" size="lg" />
- </div>
- </Tooltip>
- </>
+ }
+ />
+ </div>
);
}
}
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index 7eab03e1d..85f99b9c2 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -24,34 +24,18 @@
// width: $TREE_BULLET_WIDTH;
width: 100%;
height: 100%;
- position: absolute;
-
- .treeView-expandIcon {
- display: none;
- left: -10px;
- position: absolute;
- }
-
- .treeView-checkIcon {
- left: 3.5px;
- top: 2px;
- position: absolute;
- }
-
- &:hover {
- .treeView-expandIcon {
- display: unset;
- }
- }
+ position: relative;
+ display: flex;
+ flex-direction: row;
}
- .treeView-bulletIcons:hover img {
- left: 14px;
- position: absolute;
- transform-origin: center left;
- transform: scale(6);
- pointer-events: none;
- }
+ // .treeView-bulletIcons:hover img {
+ // left: 14px;
+ // position: absolute;
+ // transform-origin: center left;
+ // transform: scale(6);
+ // pointer-events: none;
+ // }
.bullet {
grid-column: 1;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 8d8d895c6..55f62cdf2 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -34,6 +34,7 @@ import { CollectionTreeView, TreeViewType } from './CollectionTreeView';
import { CollectionView } from './CollectionView';
import './TreeView.scss';
import React = require('react');
+import { IconButton, Size } from 'browndash-components';
export interface TreeViewProps {
treeView: CollectionTreeView;
@@ -541,6 +542,8 @@ export class TreeView extends React.Component<TreeViewProps> {
TraceMobx();
const expandKey = this.treeViewExpandedView;
const sortings = (this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) as { [key: string]: { color: string; label: string } }) ?? {};
+ const color = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Color)
+ console.log("tree view", color, this.doc.title, Doc.IsSystem(this.doc))
if (['links', 'annotations', 'embeddings', this.fieldKey].includes(expandKey)) {
const sorting = StrCast(this.doc.treeViewSortCriterion, TreeSort.None);
const sortKeys = Object.keys(sortings);
@@ -580,7 +583,9 @@ export class TreeView extends React.Component<TreeViewProps> {
);
}
return (
- <>
+ <div style={{
+ color: color
+ }}>
{!docs?.length || this.props.AddToMap /* hack to identify pres box trees */ ? null : (
<div className={'treeView-sorting'} style={{ background: sortings[sorting]?.color }}>
{sortings[sorting]?.label}
@@ -640,17 +645,18 @@ export class TreeView extends React.Component<TreeViewProps> {
this._renderCount
)}
</ul>
- </>
+ </div>
);
} else if (this.treeViewExpandedView === 'fields') {
return (
- <ul key={this.doc[Id] + this.doc.title} style={{ cursor: 'inherit' }}>
+ <ul key={this.doc[Id] + this.doc.title} style={{ cursor: 'inherit', color: color }}>
<div>{this.expandedField}</div>
</ul>
);
}
return (
<ul
+ style={{ color: color }}
onPointerDown={e => {
e.preventDefault();
e.stopPropagation();
@@ -685,6 +691,7 @@ export class TreeView extends React.Component<TreeViewProps> {
@computed get renderBullet() {
TraceMobx();
const iconType = this.props.treeView.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':open' : !this.childDocs.length ? ':empty' : '')) || 'question';
+ const color = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Color)
const checked = this.onCheckedClick ? this.doc.treeViewChecked ?? 'unchecked' : undefined;
return (
<div
@@ -705,14 +712,26 @@ export class TreeView extends React.Component<TreeViewProps> {
}>
{this.props.treeView.outlineMode ? (
!(this.doc.text as RichTextField)?.Text ? null : (
- <FontAwesomeIcon size="sm" icon={[this.childDocs?.length && !this.treeViewOpen ? 'fas' : 'far', 'circle']} />
+ <IconButton
+ color={color}
+ icon={<FontAwesomeIcon icon={[this.childDocs?.length && !this.treeViewOpen ? 'fas' : 'far', 'circle']} />}
+ size={Size.XSMALL}
+ />
)
) : (
<div className="treeView-bulletIcons" style={{ color: Doc.IsSystem(DocCast(this.doc.proto)) ? 'red' : undefined }}>
- <div className={`treeView-${this.onCheckedClick ? 'checkIcon' : 'expandIcon'}`}>
- <FontAwesomeIcon size="sm" icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} />
- </div>
- {this.onCheckedClick ? null : typeof iconType === 'string' ? <FontAwesomeIcon icon={iconType as IconProp} /> : iconType}
+ <IconButton
+ color={color}
+ icon={<FontAwesomeIcon size="sm" icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} />}
+ size={Size.XSMALL}
+ />
+ {this.onCheckedClick ? null :
+ <IconButton
+ color={color}
+ icon={<FontAwesomeIcon icon={iconType as IconProp} />}
+ size={Size.XSMALL}
+ />
+ }
</div>
)}
</div>
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index c9168d40a..0f51fe6ff 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -4,6 +4,10 @@ import { Tooltip } from '@material-ui/core';
import { observer } from 'mobx-react';
import { unimplementedFunction } from '../../../../Utils';
import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
+import { IconButton } from 'browndash-components';
+import { StrCast } from '../../../../fields/Types';
+import { Doc } from '../../../../fields/Doc';
+import { computed } from 'mobx';
@observer
export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -22,39 +26,44 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
MarqueeOptionsMenu.Instance = this;
}
+ @computed get userColor() {
+ return StrCast(Doc.UserDoc().userColor)
+ }
+
render() {
- const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: 'auto', width: 19, transform: 'translate(-2px, -2px)' }} />;
+ const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ width: 19 }} />;
const buttons = (
<>
- <Tooltip key="collect" title={<div className="dash-tooltip">Create a Collection</div>} placement="bottom">
- <button className="antimodeMenu-button" onPointerDown={this.createCollection}>
- <FontAwesomeIcon icon="object-group" size="lg" />
- </button>
- </Tooltip>
- ,
- <Tooltip key="group" title={<div className="dash-tooltip">Create a Grouping</div>} placement="bottom">
- <button className="antimodeMenu-button" onPointerDown={e => this.createCollection(e, true)}>
- <FontAwesomeIcon icon="layer-group" size="lg" />
- </button>
- </Tooltip>
- ,
- <Tooltip key="summarize" title={<div className="dash-tooltip">Summarize Documents</div>} placement="bottom">
- <button className="antimodeMenu-button" onPointerDown={this.summarize}>
- <FontAwesomeIcon icon="compress-arrows-alt" size="lg" />
- </button>
- </Tooltip>
- ,
- <Tooltip key="delete" title={<div className="dash-tooltip">Delete Documents</div>} placement="bottom">
- <button className="antimodeMenu-button" onPointerDown={this.delete}>
- <FontAwesomeIcon icon="trash-alt" size="lg" />
- </button>
- </Tooltip>
- ,
- <Tooltip key="pinWithView" title={<div className="dash-tooltip">Pin selected region to trail</div>} placement="bottom">
- <button className="antimodeMenu-button" onPointerDown={this.pinWithView}>
- {presPinWithViewIcon}
- </button>
- </Tooltip>
+ <IconButton
+ tooltip={"Create a Collection"}
+ onPointerDown={this.createCollection}
+ icon={<FontAwesomeIcon icon="object-group"/>}
+ color={this.userColor}
+ />
+ <IconButton
+ tooltip={"Create a Grouping"}
+ onPointerDown={e => this.createCollection(e, true)}
+ icon={<FontAwesomeIcon icon="layer-group"/>}
+ color={this.userColor}
+ />
+ <IconButton
+ tooltip={"Summarize Documents"}
+ onPointerDown={this.summarize}
+ icon={<FontAwesomeIcon icon="compress-arrows-alt"/>}
+ color={this.userColor}
+ />
+ <IconButton
+ tooltip={"Delete Documents"}
+ onPointerDown={this.delete}
+ icon={<FontAwesomeIcon icon="trash-alt"/>}
+ color={this.userColor}
+ />
+ <IconButton
+ tooltip={"Pin selected region"}
+ onPointerDown={this.pinWithView}
+ icon={presPinWithViewIcon}
+ color={this.userColor}
+ />
</>
);
return this.getElement(buttons);
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index 446e720e8..56b8366d0 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -20,7 +20,8 @@ import { UndoStack } from '../../UndoStack';
import { CollectionStackedTimeline } from '../CollectionStackedTimeline';
import { CollectionSubView } from '../CollectionSubView';
import './CollectionLinearView.scss';
-import { Button, Type } from 'browndash-components';
+import { Button, Toggle, ToggleType, Type } from 'browndash-components';
+import { Colors } from '../../global/globalEnums';
/**
* CollectionLinearView is the class for rendering the horizontal collection
@@ -47,7 +48,7 @@ export class CollectionLinearView extends CollectionSubView() {
componentDidMount() {
this._widthDisposer = reaction(
- () => 5 + NumCast(this.rootDoc.linearBtnWidth, this.dimension()) + (this.layoutDoc.linearView_IsExpanded ? this.childDocs.filter(doc => !doc.hidden).reduce((tot, doc) => (doc[Width]() || this.dimension()) + tot + 4, 0) : 0),
+ () => 5 + NumCast(this.rootDoc.linearBtnWidth, this.dimension()) + (this.layoutDoc.linearView_IsOpen ? this.childDocs.filter(doc => !doc.hidden).reduce((tot, doc) => (doc[Width]() || this.dimension()) + tot + 4, 0) : 0),
width => this.childDocs.length && (this.layoutDoc._width = width),
{ fireImmediately: true }
);
@@ -199,36 +200,48 @@ export class CollectionLinearView extends CollectionSubView() {
render() {
const flexDir = StrCast(this.Document.flexDirection); // Specify direction of linear view content
const flexGap = NumCast(this.Document.flexGap); // Specify the gap between linear view content
- const isExpanded = BoolCast(this.layoutDoc.linearView_IsExpanded);
+ const isExpanded = BoolCast(this.layoutDoc.linearView_IsOpen);
const menuOpener = (
- <Button
+ <Toggle
text={Cast(this.props.Document.icon, 'string', null)}
- icon={<FontAwesomeIcon icon={isExpanded ? 'minus' : 'plus'} />}
+ icon={Cast(this.props.Document.icon, 'string', null) ? undefined : <FontAwesomeIcon icon={isExpanded ? 'minus' : 'plus'} />}
type={Type.TERT}
+ color={StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}
onPointerDown={e => e.stopPropagation()}
+ toggleType={ToggleType.BUTTON}
+ toggleStatus={BoolCast(this.layoutDoc.linearView_IsOpen)}
onClick={() => {
- this.layoutDoc.linearView_IsExpanded = !isExpanded;
+ this.layoutDoc.linearView_IsOpen = !isExpanded;
}}
tooltip={isExpanded ? 'Close' : 'Open'}
+ fillWidth={true}
+ align={'center'}
/>
);
return (
- <div className={`collectionLinearView-outer ${this.layoutDoc.linearView_SubMenu}`} style={{ backgroundColor: this.layoutDoc.linearView_IsExpanded ? undefined : 'transparent' }}>
+ <div className={`collectionLinearView-outer ${this.layoutDoc.linearView_SubMenu}`} style={{ backgroundColor: this.layoutDoc.linearView_IsOpen ? undefined : 'transparent' }}>
<div className="collectionLinearView" ref={this.createDashEventsTarget} onContextMenu={this.myContextMenu} style={{ minHeight: this.dimension(), pointerEvents: 'all' }}>
- {!this.props.Document.linearView_Expandable ? null : menuOpener}
- {!this.layoutDoc.linearView_IsExpanded ? null : (
- <div
- className="collectionLinearView-content"
- style={{
- height: this.dimension(),
- flexDirection: flexDir as any,
- gap: flexGap,
- }}>
- {this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))}
- </div>
- )}
+ {this.props.Document.linearView_Dropdown ?
+ <div>Hello World!</div>
+ :
+ <>
+ {!this.props.Document.linearView_Expandable ? null : menuOpener}
+ {!this.layoutDoc.linearView_IsOpen ? null : (
+ <div
+ className="collectionLinearView-content"
+ style={{
+ height: this.dimension(),
+ flexDirection: flexDir as any,
+ gap: flexGap,
+ }}>
+ {this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))}
+ </div>
+ )}
+ </>
+ }
+
</div>
</div>
);
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 8f6d898fe..d22b6b4d9 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -66,19 +66,20 @@ ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: b
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function setHeaderColor(color?: string, checkResult?: boolean) {
if (checkResult) {
- return Doc.SharingDoc().userColor;
+ return Doc.SharingDoc().headingColor;
}
- Doc.SharingDoc().userColor = undefined;
- Doc.GetProto(Doc.SharingDoc()).userColor = color;
+ Doc.SharingDoc().headingColor = undefined;
+ Doc.GetProto(Doc.SharingDoc()).headingColor = color;
Doc.UserDoc().layout_showTitle = color === 'transparent' ? undefined : StrCast(Doc.UserDoc().layout_showTitle, 'author_date');
});
// toggle: Set overlay status of selected document
ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) {
+ console.log(checkResult);
const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
if (checkResult) {
- if (NumCast(selected?.Document.z) >= 1) return Colors.MEDIUM_BLUE;
- return 'transparent';
+ if (NumCast(selected?.Document.z) >= 1) return true;
+ return false;
}
selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log('[FontIconBox.tsx] toggleOverlay failed');
});
@@ -88,45 +89,47 @@ ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'grid' | 'snapli
// prettier-ignore
const map: Map<'flashcards' | 'grid' | 'snaplines' | 'clusters' | 'arrange'| 'viewAll', { waitForRender?: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc) => void;}> = new Map([
['grid', {
- checkResult: (doc:Doc) => doc._freeform_backgroundGrid,
+ checkResult: (doc:Doc) => BoolCast(doc._freeform_backgroundGrid, false),
setDoc: (doc:Doc) => doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid,
}],
['snaplines', {
- checkResult: (doc:Doc) => doc._freeform_snapLines,
+ checkResult: (doc:Doc) => BoolCast(doc._freeform_snapLines, false),
setDoc: (doc:Doc) => doc._freeform_snapLines = !doc._freeform_snapLines,
}],
['viewAll', {
- checkResult: (doc:Doc) => doc._freeform_fitContentsToBox,
+ checkResult: (doc:Doc) => BoolCast(doc._freeform_fitContentsToBox, false),
setDoc: (doc:Doc) => doc._freeform_fitContentsToBox = !doc._freeform_fitContentsToBox,
}],
['clusters', {
waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire
- checkResult: (doc:Doc) => doc._freeform_useClusters,
+ checkResult: (doc:Doc) => BoolCast(doc._freeform_useClusters, false),
setDoc: (doc:Doc) => doc._freeform_useClusters = !doc._freeform_useClusters,
}],
['arrange', {
waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire
- checkResult: (doc:Doc) => doc._autoArrange,
+ checkResult: (doc:Doc) => BoolCast(doc._autoArrange, false),
setDoc: (doc:Doc) => doc._autoArrange = !doc._autoArrange,
}],
['flashcards', {
- checkResult: (doc:Doc) => Doc.UserDoc().defaultToFlashcards,
+ checkResult: (doc:Doc) => BoolCast(Doc.UserDoc().defaultToFlashcards, false),
setDoc: (doc:Doc) => Doc.UserDoc().defaultToFlashcards = !Doc.UserDoc().defaultToFlashcards,
}],
]);
if (checkResult) {
- return map.get(attr)?.checkResult(selected) ? Colors.MEDIUM_BLUE : 'transparent';
+ console.log(attr, map.get(attr)?.checkResult(selected))
+ return map.get(attr)?.checkResult(selected);
}
const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} };
SelectionManager.Docs().map(dv => map.get(attr)?.setDoc(dv));
setTimeout(() => batch.end(), 100);
});
-ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highlight' | 'fontSize', value: any, checkResult?: boolean) {
+
+ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highlight' | 'fontSize' | 'alignment', value: any, checkResult?: boolean) {
const editorView = RichTextMenu.Instance?.TextView?.EditorView;
const selected = SelectionManager.Docs().lastElement();
// prettier-ignore
- const map: Map<'font'|'fontColor'|'highlight'|'fontSize', { checkResult: () => any; setDoc: () => void;}> = new Map([
+ const map: Map<'font'|'fontColor'|'highlight'|'fontSize'|'alignment', { checkResult: () => any; setDoc: () => void;}> = new Map([
['font', {
checkResult: () => RichTextMenu.Instance?.fontFamily,
setDoc: () => value && RichTextMenu.Instance.setFontFamily(value),
@@ -139,6 +142,10 @@ ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highligh
checkResult: () => RichTextMenu.Instance?.fontColor,
setDoc: () => value && RichTextMenu.Instance.setColor(value),
}],
+ ['alignment', {
+ checkResult: () => RichTextMenu.Instance.textAlign,
+ setDoc: () => value && editorView?.state ? RichTextMenu.Instance.align(editorView, editorView.dispatch, value):(Doc.UserDoc().textAlign = value),
+ }],
['fontSize', {
checkResult: () => RichTextMenu.Instance?.fontSize.replace('px', ''),
setDoc: () => {
@@ -157,6 +164,7 @@ ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highligh
type attrname = 'noAutoLink' | 'dictation' | 'bold' | 'italics' | 'underline' | 'left' | 'center' | 'right' | 'bullet' | 'decimal';
type attrfuncs = [attrname, { checkResult: () => boolean; toggle: () => any }];
+
ScriptingGlobals.add(function toggleCharStyle(charStyle: attrname, checkResult?: boolean) {
const textView = RichTextMenu.Instance?.TextView;
const editorView = textView?.EditorView;
@@ -182,7 +190,10 @@ ScriptingGlobals.add(function toggleCharStyle(charStyle: attrname, checkResult?:
toggle: editorView ? RichTextMenu.Instance.toggleUnderline : () => (Doc.UserDoc().textDecoration = Doc.UserDoc().textDecoration === 'underline' ? undefined : 'underline') }]]
const map = new Map(attrs.concat(alignments).concat(listings));
- if (checkResult) return map.get(charStyle)?.checkResult() ? Colors.MEDIUM_BLUE : 'transparent';
+ if (checkResult) {
+ console.log(charStyle, checkResult, map.get(charStyle)?.checkResult());
+ return map.get(charStyle)?.checkResult();
+ }
map.get(charStyle)?.toggle();
});
@@ -270,9 +281,9 @@ function setActiveTool(tool: InkTool | GestureUtils.Gestures, keepPrim: boolean,
if (checkResult) {
return (Doc.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool
? GestureOverlay.Instance?.KeepPrimitiveMode || ![GestureUtils.Gestures.Circle, GestureUtils.Gestures.Line, GestureUtils.Gestures.Rectangle].includes(tool as GestureUtils.Gestures)
- ? Colors.MEDIUM_BLUE
- : Colors.MEDIUM_BLUE_ALT
- : 'transparent';
+ ? true
+ : true
+ : false;
}
runInAction(() => {
if (GestureOverlay.Instance) {
@@ -308,7 +319,7 @@ ScriptingGlobals.add(function setInkProperty(option: 'inkMask' | 'fillColor' | '
// prettier-ignore
const map: Map<'inkMask' | 'fillColor' | 'strokeWidth' | 'strokeColor', { checkResult: () => any; setInk: (doc: Doc) => void; setMode: () => void }> = new Map([
['inkMask', {
- checkResult: () => ((selected?.type === DocumentType.INK ? BoolCast(selected.stroke_isInkMask) : ActiveIsInkMask()) ? Colors.MEDIUM_BLUE : 'transparent'),
+ checkResult: () => ((selected?.type === DocumentType.INK ? BoolCast(selected.stroke_isInkMask) : ActiveIsInkMask())),
setInk: (doc: Doc) => (doc.stroke_isInkMask = !doc.stroke_isInkMask),
setMode: () => selected?.type !== DocumentType.INK && SetActiveIsInkMask(!ActiveIsInkMask()),
}],
diff --git a/src/client/views/linking/LinkPopup.scss b/src/client/views/linking/LinkPopup.scss
index b20ad9476..4bfb4b0b9 100644
--- a/src/client/views/linking/LinkPopup.scss
+++ b/src/client/views/linking/LinkPopup.scss
@@ -4,7 +4,6 @@
top: 0;
height: 200px;
width: 200px;
- position: absolute;
// padding: 15px;
border-radius: 3px;
@@ -37,8 +36,4 @@
margin: auto;
}
}
-
- .searchBox-container {
- background: pink;
- }
}
diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx
index 745efea08..6895c0746 100644
--- a/src/client/views/linking/LinkPopup.tsx
+++ b/src/client/views/linking/LinkPopup.tsx
@@ -14,7 +14,6 @@ import React = require('react');
import { OpenWhere } from '../nodes/DocumentView';
interface LinkPopupProps {
- showPopup: boolean;
linkFrom?: () => Doc | undefined;
linkCreateAnchor?: () => Doc | undefined;
linkCreated?: (link: Doc) => void;
@@ -44,10 +43,9 @@ export class LinkPopup extends React.Component<LinkPopupProps> {
getPHeight = () => 500;
render() {
- const popupVisibility = this.props.showPopup ? 'block' : 'none';
const linkDoc = this.props.linkFrom ? this.props.linkFrom : undefined;
return (
- <div className="linkPopup-container" style={{ display: popupVisibility }}>
+ <div className="linkPopup-container">
{/* <div className="linkPopup-url-container">
<input autoComplete="off" type="text" value={this.linkURL} placeholder="Enter URL..." onChange={this.onLinkChange} />
<button onPointerDown={e => this.makeLinkToURL(this.linkURL, "add:right")}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index e954d0484..7e8eef0a5 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -18,7 +18,7 @@ import { SearchBox } from '../search/SearchBox';
import { DashWebRTCVideo } from '../webcam/DashWebRTCVideo';
import { YoutubeBox } from './../../apis/youtube/YoutubeBox';
import { AudioBox } from './AudioBox';
-import { FontIconBox } from './button/FontIconBox';
+import { FontIconBox } from './FontIconBox/FontIconBox';
import { ColorBox } from './ColorBox';
import { ComparisonBox } from './ComparisonBox';
import { DataVizBox } from './DataVizBox/DataVizBox';
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8a35ca2a4..0b8ea1150 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1111,8 +1111,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
);
const targetDoc = layout_showTitle?.startsWith('_') ? this.layoutDoc : this.rootDoc;
const background = StrCast(
- SharingManager.Instance.users.find(u => u.user.email === this.dataDoc.author)?.sharingDoc.userColor,
- Doc.UserDoc().layout_showTitle && [DocumentType.RTF, DocumentType.COL].includes(this.rootDoc.type as any) ? StrCast(Doc.SharingDoc().userColor) : 'rgba(0,0,0,0.4)'
+ SharingManager.Instance.users.find(u => u.user.email === this.dataDoc.author)?.sharingDoc.headingColor,
+ Doc.UserDoc().layout_showTitle && [DocumentType.RTF, DocumentType.COL].includes(this.rootDoc.type as any) ? StrCast(Doc.SharingDoc().headingColor) : 'rgba(0,0,0,0.4)'
);
const layout_sidebarWidthPercent = +StrCast(this.layoutDoc.layout_sidebarWidthPercent).replace('%', '');
const titleView = !layout_showTitle ? null : (
diff --git a/src/client/views/nodes/FontIconBox/ButtonInterface.ts b/src/client/views/nodes/FontIconBox/ButtonInterface.ts
new file mode 100644
index 000000000..0aa2ac8e1
--- /dev/null
+++ b/src/client/views/nodes/FontIconBox/ButtonInterface.ts
@@ -0,0 +1,12 @@
+import { Doc } from "../../../../fields/Doc";
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
+import { ButtonType } from "./FontIconBox";
+
+export interface IButtonProps {
+ type: string | ButtonType;
+ rootDoc: Doc;
+ label: any;
+ icon: IconProp;
+ color: string;
+ backgroundColor: string;
+} \ No newline at end of file
diff --git a/src/client/views/nodes/FontIconBox/FontIconBadge.scss b/src/client/views/nodes/FontIconBox/FontIconBadge.scss
new file mode 100644
index 000000000..78f506e57
--- /dev/null
+++ b/src/client/views/nodes/FontIconBox/FontIconBadge.scss
@@ -0,0 +1,11 @@
+.fontIconBadge {
+ background: red;
+ width: 15px;
+ height: 15px;
+ top: 8px;
+ display: block;
+ position: absolute;
+ right: 5;
+ border-radius: 50%;
+ text-align: center;
+} \ No newline at end of file
diff --git a/src/client/views/nodes/FontIconBox/FontIconBadge.tsx b/src/client/views/nodes/FontIconBox/FontIconBadge.tsx
new file mode 100644
index 000000000..b50588ce2
--- /dev/null
+++ b/src/client/views/nodes/FontIconBox/FontIconBadge.tsx
@@ -0,0 +1,37 @@
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import './FontIconBadge.scss';
+
+interface FontIconBadgeProps {
+ value: string | undefined;
+}
+
+@observer
+export class FontIconBadge extends React.Component<FontIconBadgeProps> {
+ _notifsRef = React.createRef<HTMLDivElement>();
+
+ // onPointerDown = (e: React.PointerEvent) => {
+ // setupMoveUpEvents(this, e,
+ // (e: PointerEvent) => {
+ // const dragData = new DragManager.DocumentDragData([this.props.collection!]);
+ // DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y);
+ // return true;
+ // },
+ // returnFalse, emptyFunction, false);
+ // }
+
+ render() {
+ if (this.props.value === undefined) return null;
+ return (
+ <div className="fontIconBadge-container" ref={this._notifsRef}>
+ <div
+ className="fontIconBadge"
+ style={{ display: 'initial' }}
+ // onPointerDown={this.onPointerDown}
+ >
+ {this.props.value}
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/src/client/views/nodes/button/FontIconBox.scss b/src/client/views/nodes/FontIconBox/FontIconBox.scss
index 9d9fa26b0..9d9fa26b0 100644
--- a/src/client/views/nodes/button/FontIconBox.scss
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.scss
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index e31407f4b..2958fa737 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -1,10 +1,10 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, ColorPicker, Dropdown, DropdownType, EditableText, IconButton, IListItemProps, NumberDropdown, NumberDropdownType, Size, Toggle, ToggleType, Type } from 'browndash-components';
+import { Button, ColorPicker, Dropdown, DropdownType, EditableText, IconButton, IListItemProps, NumberDropdown, NumberDropdownType, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, StrListCast } from '../../../../fields/Doc';
+import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
import { ScriptField } from '../../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
@@ -15,21 +15,22 @@ import { DocComponent } from '../../DocComponent';
import { EditableView } from '../../EditableView';
import { Colors } from '../../global/globalEnums';
import { StyleProp } from '../../StyleProvider';
-import { FieldView, FieldViewProps } from '.././FieldView';
+import { FieldView, FieldViewProps } from '../FieldView';
import { OpenWhere } from '../DocumentView';
import { RichTextMenu } from '../formattedText/RichTextMenu';
import './FontIconBox.scss';
+import { SelectedDocView } from '../../selectedDoc';
export enum ButtonType {
TextButton = 'textBtn',
MenuButton = 'menuBtn',
- DropdownList = 'drpdownList',
- DropdownButton = 'drpdownBtn',
+ DropdownList = 'dropdownList',
+ DropdownButton = 'dropdownBtn',
ClickButton = 'clickBtn',
- DoubleButton = 'dblBtn',
- ToggleButton = 'tglBtn',
+ ToggleButton = 'toggleBtn',
ColorButton = 'colorBtn',
ToolButton = 'toolBtn',
+ MultiToggleButton = 'multiToggleBtn',
NumberSliderButton = 'numSliderBtn',
NumberDropdownButton = 'numDropdownBtn',
NumberInlineButton = 'numInlineBtn',
@@ -144,10 +145,13 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
color={color}
numberDropdownType={type}
showPlusMinus={false}
+ tooltip={this.label}
+ type={Type.PRIM}
min={NumCast(this.rootDoc.numBtnMin, 0)}
max={NumCast(this.rootDoc.numBtnMax, 100)}
number={checkResult}
setNumber={undoable(value => numScript(value), `${this.rootDoc.title} button set from list`)}
+ fillWidth
/>
}
@@ -195,29 +199,50 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
let noviceList: string[] = [];
let text: string | undefined;
let dropdown = true;
+ let getStyle: (val: string) => any = () => {};
let icon: IconProp = 'caret-down';
+ let isViewDropdown: boolean = script?.script.originalScript.startsWith('setView')
try {
- if (script?.script.originalScript.startsWith('setView')) {
+ if (isViewDropdown) {
+ const selectedDocs: Doc[] = SelectionManager.Docs();
const selected = SelectionManager.Docs().lastElement();
console.log('selected')
if (selected) {
if (StrCast(selected.type) === DocumentType.COL) {
text = StrCast(selected._type_collection);
} else {
- console.log("doc selected", selected.title)
+ console.log("doc selected", selected.title);
dropdown = false;
- text = selected.type === DocumentType.RTF ? 'Text' : StrCast(selected.type);
- icon = Doc.toIcon(selected);
- return <div>Hi!</div>
+ if (selectedDocs.length > 1) {
+ text = selectedDocs.length + " documents selected"
+ } else {
+ text = selected.type === DocumentType.RTF ? 'Text' : StrCast(selected.type);
+ icon = Doc.toIcon(selected);
+ }
+ return <Popup
+ icon={<FontAwesomeIcon size={'1x'} icon={icon} />}
+ text={text}
+ type={Type.TERT}
+ color={color}
+ popup={<SelectedDocView selectedDocs={selectedDocs}/>}
+ fillWidth
+ />
}
} else {
dropdown = false;
- icon = 'globe-asia';
- text = 'User Default';
- return <div>Hi!</div>
+ return <Button
+ text={`None Selected`}
+ type={Type.TERT}
+ color={color}
+ fillWidth
+ inactive
+ />
}
noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
- } else text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+ } else {
+ text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+ getStyle = (val: string) => { return { fontFamily: val } }
+ }
} catch (e) {
console.log(e);
}
@@ -229,9 +254,9 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
.filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value))
.map(value => (
{
- text: value,
+ text: value.charAt(0).toUpperCase() + value.slice(1),
val: value,
- style: { fontFamily: value },
+ style: getStyle(value),
onClick: undoable(() => script.script.run({ self: this.rootDoc, value }), value)
// shortcut: '#',
}
@@ -242,11 +267,12 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
<Dropdown
selectedVal={text}
setSelectedVal={undoable((val) => script.script.run({ self: this.rootDoc, val }), `dropdown select ${this.label}`)}
- color={Colors.WHITE}
- type={Type.PRIM}
+ color={color}
+ type={isViewDropdown ? Type.TERT : Type.PRIM}
dropdownType={DropdownType.SELECT}
items={list}
tooltip={this.label}
+ fillWidth
/>
)
}
@@ -283,17 +309,18 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
@computed get toggleButton() {
// Determine the type of toggle button
- const switchToggle: boolean = BoolCast(this.rootDoc.switchToggle);
const buttonText: string = StrCast(this.rootDoc.buttonText);
const tooltip: string = StrCast(this.rootDoc.toolTip);
-
+
+ const script = ScriptCast(this.rootDoc.onClick);
+ const toggleStatus = script ? script.script.run({ self: this.rootDoc, value: undefined, _readOnly_: true }).result : false;
// Colors
const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
- console.log(buttonText, tooltip);
+ console.log(tooltip, toggleStatus);
return (
- <Toggle tooltip={`Toggle + ${tooltip}`} toggleType={ToggleType.BUTTON} type={Type.PRIM} toggleStatus={switchToggle} text={buttonText} color={color} icon={this.Icon(color)!} label={this.label}/>
+ <Toggle tooltip={`Toggle ${tooltip}`} toggleType={ToggleType.BUTTON} type={Type.PRIM} toggleStatus={toggleStatus} text={buttonText} color={color} icon={this.Icon(color)!} label={this.label}/>
)
}
@@ -319,7 +346,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ value, _readOnly_: false }).result;
return <EditableText
- editing={false} onEdit={() => {}} setEditing={(editing: boolean) => {}}
+ editing={false} setEditing={(editing: boolean) => {}}
/>
return (
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 5480600b0..64ea4f52c 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -15,6 +15,8 @@ import { GPTPopup, GPTPopupMode } from './GPTPopup/GPTPopup';
import { LightboxView } from '../LightboxView';
import { EditorView } from 'prosemirror-view';
import './AnchorMenu.scss';
+import { ColorPicker, Group, IconButton, Popup, Size, Type } from 'browndash-components';
+import { StrCast } from '../../../fields/Types';
@observer
export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -42,7 +44,6 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
];
@observable private highlightColor: string = 'rgba(245, 230, 95, 0.616)';
- @observable private _showLinkPopup: boolean = false;
@observable public Status: 'marquee' | 'annotation' | '' = '';
@@ -131,7 +132,6 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
() => this._opacity,
opacity => {
if (!opacity) {
- this._showLinkPopup = false;
this.setGPTPopupVis(false);
this.setGPTPopupText('');
}
@@ -141,7 +141,6 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
this._disposer = reaction(
() => SelectionManager.Views().slice(),
selected => {
- this._showLinkPopup = false;
this.setGPTPopupVis(false);
this.setGPTPopupText('');
AnchorMenu.Instance.fadeOut(true);
@@ -253,49 +252,25 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
AnchorMenu.Instance.fadeOut(true);
};
- @action
- toggleLinkPopup = (e: React.MouseEvent) => {
- //ignore the potential null type error because this method cannot be called unless the user selects text and clicks the link button
- //change popup visibility field to visible
- this._showLinkPopup = !this._showLinkPopup;
- };
-
@computed get highlighter() {
- const button = (
- <button className="antimodeMenu-button anchor-color-preview-button" title="" key="highlighter-button" onClick={this.highlightClicked}>
- <div className="anchor-color-preview">
- <FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: 'transform 0.1s', transform: 'rotate(-45deg)' }} />
- <div className="color-preview" style={{ backgroundColor: this.highlightColor }}></div>
- </div>
- </button>
- );
-
- const dropdownContent = (
- <div className="dropdown">
- <p>Change highlighter color:</p>
- <div className="color-wrapper">
- {this._palette.map(color => {
- if (color) {
- return this.highlightColor === color ? (
- <button className="color-button active" key={`active ${color}`} style={{ backgroundColor: color }} onPointerDown={e => this.changeHighlightColor(color, e)}></button>
- ) : (
- <button className="color-button" key={`inactive ${color}`} style={{ backgroundColor: color }} onPointerDown={e => this.changeHighlightColor(color, e)}></button>
- );
- }
- })}
- </div>
- </div>
- );
- return (
- <Tooltip key="highlighter" title={<div className="dash-tooltip">{'Click to Highlight'}</div>}>
- <div className="anchorMenu-highlighter">
- <ButtonDropdown key={'highlighter'} button={button} dropdownContent={dropdownContent} pdf={true} />
- </div>
- </Tooltip>
- );
+ return <Group>
+ <IconButton
+ icon={<FontAwesomeIcon icon="highlighter" style={{ transition: 'transform 0.1s', transform: 'rotate(-45deg)' }} />}
+ tooltip={'Click to Highlight'}
+ onClick={this.highlightClicked}
+ colorPicker={this.highlightColor}
+ color={StrCast(Doc.UserDoc().userColor)}
+ />
+ <ColorPicker
+ colorPickerType={'github'}
+ selectedColor={this.highlightColor}
+ setSelectedColor={color => this.changeHighlightColor(color)}
+ size={Size.XSMALL}
+ />
+ </Group>
}
- @action changeHighlightColor = (color: string, e: React.PointerEvent) => {
+ @action changeHighlightColor = (color: string) => {
const col: ColorState = {
hex: color,
hsl: { a: 0, h: 0, s: 0, l: 0, source: '' },
@@ -304,8 +279,6 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
oldHue: 0,
source: '',
};
- e.preventDefault();
- e.stopPropagation();
this.highlightColor = Utils.colorString(col);
};
@@ -339,11 +312,12 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
this.Status === 'marquee' ? (
<>
{this.highlighter}
- <Tooltip key="annotate" title={<div className="dash-tooltip">Drag to Place Annotation</div>}>
- <button className="antimodeMenu-button annotate" ref={this._commentCont} onPointerDown={this.pointerDown} style={{ cursor: 'grab' }}>
- <FontAwesomeIcon icon="comment-alt" size="lg" />
- </button>
- </Tooltip>
+ <IconButton
+ tooltip={'Drag to Place Annotation'}
+ onPointerDown={this.pointerDown}
+ icon={<FontAwesomeIcon icon="comment-alt"/>}
+ color={StrCast(Doc.UserDoc().userColor)}
+ />
{/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection*/}
{AnchorMenu.Instance.StartCropDrag === unimplementedFunction && this.canSummarize() && (
<Tooltip key="gpt" title={<div className="dash-tooltip">Summarize with AI</div>}>
@@ -364,32 +338,35 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
mode={this.GPTMode}
/>
{AnchorMenu.Instance.OnAudio === unimplementedFunction ? null : (
- <Tooltip key="annoaudiotate" title={<div className="dash-tooltip">Click to Record Annotation</div>}>
- <button className="antimodeMenu-button annotate" onPointerDown={this.audioDown} style={{ cursor: 'grab' }}>
- <FontAwesomeIcon icon="microphone" size="lg" />
- </button>
- </Tooltip>
+ <IconButton
+ tooltip={'Click to Record Annotation'}
+ onPointerDown={this.audioDown}
+ icon={<FontAwesomeIcon icon="microphone" />}
+ color={StrCast(Doc.UserDoc().userColor)}
+ />
)}
{this.canEdit() && (
- <Tooltip key="gpttextedit" title={<div className="dash-tooltip">AI edit suggestions</div>}>
- <button className="antimodeMenu-button annotate" onPointerDown={this.gptEdit} style={{ cursor: 'grab' }}>
- <FontAwesomeIcon icon="pencil-alt" size="lg" />
- </button>
- </Tooltip>
+ <IconButton
+ tooltip={'AI edit suggestions'}
+ onPointerDown={this.gptEdit}
+ icon={<FontAwesomeIcon icon="pencil-alt" />}
+ color={StrCast(Doc.UserDoc().userColor)}
+ />
)}
- <Tooltip key="link" title={<div className="dash-tooltip">Find document to link to selected text</div>}>
- <button className="antimodeMenu-button link" onPointerDown={this.toggleLinkPopup}>
- <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(1.5)' }} icon={'search'} size="lg" />
- <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(0.5)', transformOrigin: 'top left', top: 12, left: 12 }} icon={'link'} size="lg" />
- </button>
- </Tooltip>
- <LinkPopup key="popup" showPopup={this._showLinkPopup} linkCreateAnchor={this.onMakeAnchor} />,
+ <Popup
+ tooltip='Find document to link to selected text'
+ type={Type.PRIM}
+ icon={<FontAwesomeIcon icon={'search'} />}
+ popup={<LinkPopup key="popup" linkCreateAnchor={this.onMakeAnchor} />}
+ color={StrCast(Doc.UserDoc().userColor)}
+ />
{AnchorMenu.Instance.StartCropDrag === unimplementedFunction ? null : (
- <Tooltip key="crop" title={<div className="dash-tooltip">Click/Drag to create cropped image</div>}>
- <button className="antimodeMenu-button annotate" onPointerDown={this.cropDown} style={{ cursor: 'grab' }}>
- <FontAwesomeIcon icon="image" size="lg" />
- </button>
- </Tooltip>
+ <IconButton
+ tooltip={'Click/Drag to create cropped image'}
+ onPointerDown={this.cropDown}
+ icon={<FontAwesomeIcon icon="image"/>}
+ color={StrCast(Doc.UserDoc().userColor)}
+ />
)}
</>
) : (
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index 5516cf205..a439aea3e 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -9,7 +9,6 @@
background: none;
z-index: 1000;
padding: 0px;
- overflow: scroll;
cursor: default;
.searchBox-bar {
@@ -22,7 +21,7 @@
padding: 5px;
top: 0px;
position: sticky;
- background: $light-gray;
+ overflow-y: scroll;
border-bottom: $standard-border;
.searchBox-type {
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 12c25ca09..11f22ad5e 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -17,6 +17,7 @@ import { FieldView, FieldViewProps } from '../nodes/FieldView';
import './SearchBox.scss';
import { fetchRecommendations } from '../newlightbox/utils';
import { IRecommendation, Recommendation } from '../newlightbox/components';
+import { Colors } from '../global/globalEnums';
const DAMPENING_FACTOR = 0.9;
const MAX_ITERATIONS = 25;
@@ -528,7 +529,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
))
return (
- <div style={{ pointerEvents: 'all' }} className="searchBox-container">
+ <div className="searchBox-container" style={{pointerEvents: 'all', background: StrCast(Doc.UserDoc().userBackgroundColor)}}>
<div className="searchBox-bar">
{isLinkSearch ? null : (
<select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
@@ -552,14 +553,14 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
/>
</div>
{resultsJSX.length > 0 && <div className="searchBox-results-container">
- <div className="section-header">
+ <div className="section-header" style={{background: StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}}>
<div className="section-title">Results</div>
<div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
</div>
<div className="searchBox-results-view">{resultsJSX}</div>
</div>}
{recommendationsJSX.length > 0 && <div className="searchBox-recommendations-container">
- <div className="section-header">
+ <div className="section-header" style={{background: StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}}>
<div className="section-title">Recommendations</div>
<div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
</div>
diff --git a/src/client/views/selectedDoc/SelectedDocView.scss b/src/client/views/selectedDoc/SelectedDocView.scss
new file mode 100644
index 000000000..156dfc37b
--- /dev/null
+++ b/src/client/views/selectedDoc/SelectedDocView.scss
@@ -0,0 +1,3 @@
+.selectedDocView-container {
+
+} \ No newline at end of file
diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx
new file mode 100644
index 000000000..1c9e124a2
--- /dev/null
+++ b/src/client/views/selectedDoc/SelectedDocView.tsx
@@ -0,0 +1,47 @@
+import React = require('react');
+import { Doc } from "../../../fields/Doc";
+import { observer } from "mobx-react";
+import { computed } from "mobx";
+import { StrCast } from "../../../fields/Types";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Colors, ListBox } from 'browndash-components';
+import { DocumentManager } from '../../util/DocumentManager';
+import { DocFocusOptions } from '../nodes/DocumentView';
+
+export interface SelectedDocViewProps {
+ selectedDocs: Doc[];
+}
+
+@observer
+export class SelectedDocView extends React.Component<SelectedDocViewProps> {
+
+ @computed get selectedDocs() {
+ return this.props.selectedDocs;
+ }
+
+
+ render() {
+ return <div className={`selectedDocView-container`}>
+ <ListBox
+ items={this.selectedDocs.map((doc) => {
+ const icon = Doc.toIcon(doc);
+ const iconEle = <FontAwesomeIcon size={'1x'} icon={icon} />;
+ const text = StrCast(doc.title)
+ const finished = () => {
+
+ };
+ const options: DocFocusOptions = {
+ playAudio: false,
+ };
+ return {
+ text: text,
+ val: StrCast(doc._id),
+ icon: iconEle,
+ onClick: () => {DocumentManager.Instance.showDocument(doc, options, finished);}
+ }
+ })}
+ color={Colors.WHITE}
+ />
+ </div>
+ }
+} \ No newline at end of file
diff --git a/src/client/views/selectedDoc/index.ts b/src/client/views/selectedDoc/index.ts
new file mode 100644
index 000000000..1f1db91f6
--- /dev/null
+++ b/src/client/views/selectedDoc/index.ts
@@ -0,0 +1 @@
+export * from './SelectedDocView' \ No newline at end of file
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index b613a0e3e..1b0c6803c 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, IconButton, FontSize, Size, Type } from 'browndash-components';
+import { Button, IconButton, FontSize, Size, Type, isDark } from 'browndash-components';
import { action, computed, observable, reaction } from 'mobx';
import { Tooltip } from '@mui/material';
import { observer } from 'mobx-react';
@@ -36,9 +36,10 @@ export class TopBar extends React.Component {
});
};
- @observable textColor: string = Colors.LIGHT_GRAY;
+ @computed get color() { return StrCast(Doc.UserDoc().userColor, Colors.LIGHT_GRAY); }
+ @computed get variantColor() { return StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE); }
@computed get backgroundColor() {
- return PingManager.Instance.IsBeating ? Colors.DARK_GRAY : Colors.MEDIUM_GRAY;
+ return PingManager.Instance.IsBeating ? StrCast(Doc.UserDoc().userBackgroundColor, Colors.DARK_GRAY) : Colors.MEDIUM_GRAY;
}
@observable happyHeart: boolean = PingManager.Instance.IsBeating;
@@ -59,16 +60,16 @@ export class TopBar extends React.Component {
return (
<div className="topbar-left">
{Doc.ActiveDashboard ? (
- <IconButton onClick={this.navigateToHome} icon={<FontAwesomeIcon icon="home" />} color={this.textColor} />
+ <IconButton onClick={this.navigateToHome} icon={<FontAwesomeIcon icon="home" />} color={this.color} />
) : (
<div className="logo-container">
<img className="logo" src="/assets/medium-blue-light-blue-circle.png" alt="dash logo"></img>
- <span style={{ color: Colors.LIGHT_GRAY, fontWeight: 200 }}>brown</span>
- <span style={{ color: Colors.LIGHT_BLUE, fontWeight: 500 }}>dash</span>
+ <span style={{ color: isDark(this.backgroundColor) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, fontWeight: 200 }}>brown</span>
+ <span style={{ color: isDark(this.backgroundColor) ? Colors.LIGHT_BLUE : Colors.MEDIUM_BLUE, fontWeight: 500 }}>dash</span>
</div>
)}
{Doc.ActiveDashboard && (
- <Button text="Explore" tooltip="Browsing mode for directly navigating to documents" size={Size.SMALL} color={this.textColor} onClick={action(() => (MainView.Instance._exploreMode = !MainView.Instance._exploreMode))} />
+ <Button text="Explore" tooltip="Browsing mode for directly navigating to documents" size={Size.SMALL} color={this.color} onClick={action(() => (MainView.Instance._exploreMode = !MainView.Instance._exploreMode))} />
)}
</div>
);
@@ -97,7 +98,7 @@ export class TopBar extends React.Component {
text={StrCast(Doc.ActiveDashboard.title)}
tooltip="Open Dashboards"
size={Size.SMALL}
- color={'white'}
+ color={this.color}
style={{fontWeight: 700, fontSize: '1rem'}}
onClick={(e: React.MouseEvent) => {
const dashView = Doc.ActiveDashboard && DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard);
@@ -118,7 +119,7 @@ export class TopBar extends React.Component {
<IconButton
tooltip="Work on a copy of the dashboard layout"
size={Size.SMALL}
- color={this.textColor}
+ color={this.color}
onClick={async () => {
const batch = UndoManager.StartBatch('snapshot');
await DashboardView.snapshotDashboard();
@@ -142,23 +143,25 @@ export class TopBar extends React.Component {
{Doc.ActiveDashboard && <Button
text={GetEffectiveAcl(Doc.GetProto(Doc.ActiveDashboard)) === AclAdmin ? 'Share' : 'View Original'}
type={Type.TERT}
+ color={this.variantColor}
onClick={() => {
SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
}}
size={Size.SMALL}
/>}
- <IconButton tooltip={"Server ⌘⇧S"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
- <IconButton tooltip={"Issue Reporter ⌘I"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ReportManager.Instance.open} icon={<FaBug />} />
- <IconButton tooltip={"Documentation ⌘D"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
- <IconButton tooltip={"Settings ⌘⇧S"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
+ <IconButton tooltip={"Server ⌘⇧S"} size={Size.SMALL} color={this.color} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
+ <IconButton tooltip={"Issue Reporter ⌘I"} size={Size.SMALL} color={this.color} onClick={ReportManager.Instance.open} icon={<FaBug />} />
+ <IconButton tooltip={"Documentation ⌘D"} size={Size.SMALL} color={this.color} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
+ <IconButton tooltip={"Settings ⌘⇧S"} size={Size.SMALL} color={this.color} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
<IconButton
size={Size.SMALL}
onClick={PingManager.Instance.showAlert}
+ type={Type.TERT}
tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running'}
color={this.happyHeart ? Colors.LIGHT_BLUE : Colors.ERROR_RED}
icon={<FontAwesomeIcon icon={this.happyHeart ? 'heart' : 'heart-broken'} />}
/>
- {/* <Button text={'Logout'} borderRadius={5} hoverStyle={'gray'} backgroundColor={Colors.DARK_GRAY} color={this.textColor} fontSize={FontSize.SECONDARY} onClick={() => window.location.assign(Utils.prepend('/logout'))} /> */}
+ {/* <Button text={'Logout'} borderRadius={5} hoverStyle={'gray'} backgroundColor={Colors.DARK_GRAY} color={this.color} fontSize={FontSize.SECONDARY} onClick={() => window.location.assign(Utils.prepend('/logout'))} /> */}
</div>
);
}
@@ -168,8 +171,9 @@ export class TopBar extends React.Component {
//TODO:glr Add support for light / dark mode
<div style={{
pointerEvents: 'all',
- color: this.textColor,
- background: this.backgroundColor,
+ color: this.color,
+ background: this.backgroundColor,
+ // borderColor: this.color
}} className="topbar-container">
<div className="topbar-inner-container">
{this.topbarLeft}