aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/CurrentUserUtils.ts8
-rw-r--r--src/client/views/DashboardView.tsx85
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx56
-rw-r--r--src/fields/Doc.ts5
4 files changed, 120 insertions, 34 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index fdac3c00a..ad14ab141 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -475,15 +475,15 @@ export class CurrentUserUtils {
_showTitle: "title", _height: 400, _gridGap: 5, _forceActive: true, _lockedPosition: true,
contextMenuLabels: new List<string>(["Create New Dashboard"]),
contextMenuIcons: new List<string>(["plus"]),
- childContextMenuLabels: new List<string>(["Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]),// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters
- childContextMenuIcons: new List<string>(["chalkboard", "tv", "camera", "users", "times"]), // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters
+ childContextMenuLabels: new List<string>(["Toggle Dark Theme", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"]),// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters
+ childContextMenuIcons: new List<string>(["chalkboard", "tv", "camera", "users", "times", "trash"]), // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters
explainer: "This is your collection of dashboards. A dashboard represents the tab configuration of your workspace. To manage documents as folders, go to the Files."
};
myDashboards = DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.TreeDocument([], opts), reqdOpts);
const toggleDarkTheme = `this.colorScheme = this.colorScheme ? undefined : "${ColorScheme.Dark}"`;
const contextMenuScripts = [newDashboard];
- const childContextMenuScripts = [toggleDarkTheme, `toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters
- const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts
+ const childContextMenuScripts = [toggleDarkTheme, `toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(self)`, 'removeDashboard(self)', 'resetDashboard(self)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters
+ const childContextMenuFilters = ['!IsNoviceMode()', '!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, undefined as any];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts
if (Cast(myDashboards.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) {
myDashboards.contextMenuScripts = new List<ScriptField>(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!));
}
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 11bb0c6a8..192e55431 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -294,6 +294,88 @@ export class DashboardView extends React.Component {
}
};
+ public static resetDashboard = (dashboard: Doc) => {
+ const config = StrCast(dashboard.dockingConfig);
+ const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+ const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) ?? [];
+
+ const components =
+ docids.map(docid => ({
+ type: 'component',
+ component: 'DocumentFrameRenderer',
+ title: 'Untitled Tab 1',
+ width: 600,
+ props: {
+ documentId: docid,
+ },
+ componentName: 'lm-react-component',
+ isClosable: true,
+ reorderEnabled: true,
+ componentState: null,
+ })) ?? [];
+ const reset = {
+ isClosable: true,
+ reorderEnabled: true,
+ title: '',
+ openPopouts: [],
+ maximisedItemId: null,
+ settings: {
+ hasHeaders: true,
+ constrainDragToContainer: true,
+ reorderEnabled: true,
+ selectionEnabled: false,
+ popoutWholeStack: false,
+ blockedPopoutsThrowError: true,
+ closePopoutsOnUnload: true,
+ showPopoutIcon: true,
+ showMaximiseIcon: true,
+ showCloseIcon: true,
+ responsiveMode: 'onload',
+ tabOverlapAllowance: 0,
+ reorderOnTabMenuClick: false,
+ tabControlOffset: 10,
+ },
+ dimensions: {
+ borderWidth: 3,
+ borderGrabWidth: 5,
+ minItemHeight: 10,
+ minItemWidth: 20,
+ headerHeight: 27,
+ dragProxyWidth: 300,
+ dragProxyHeight: 200,
+ },
+ labels: {
+ close: 'close',
+ maximise: 'maximise',
+ minimise: 'minimise',
+ popout: 'new tab',
+ popin: 'pop in',
+ tabDropdown: 'additional tabs',
+ },
+ content: [
+ {
+ type: 'row',
+ isClosable: true,
+ reorderEnabled: true,
+ title: '',
+ content: [
+ {
+ type: 'stack',
+ width: 100,
+ isClosable: true,
+ reorderEnabled: true,
+ title: '',
+ activeItemIndex: 0,
+ content: components,
+ },
+ ],
+ },
+ ],
+ };
+ Doc.SetInPlace(dashboard, 'dockingConfig', JSON.stringify(reset), true);
+ return reset;
+ };
+
public static createNewDashboard = (id?: string, name?: string, background?: string) => {
const dashboards = Doc.MyDashboards;
const dashboardCount = DocListCast(dashboards.data).length + 1;
@@ -393,6 +475,9 @@ ScriptingGlobals.add(function shareDashboard(dashboard: Doc) {
ScriptingGlobals.add(function removeDashboard(dashboard: Doc) {
DashboardView.removeDashboard(dashboard);
}, 'Remove Dashboard from Dashboards');
+ScriptingGlobals.add(function resetDashboard(dashboard: Doc) {
+ DashboardView.resetDashboard(dashboard);
+}, 'move all dashboard tabs to single stack');
ScriptingGlobals.add(function addToDashboards(dashboard: Doc) {
DashboardView.openDashboard(Doc.MakeAlias(dashboard));
}, 'adds Dashboard to set of Dashboards');
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index c6ac5ee0c..40a5876e0 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -281,38 +281,36 @@ export class CollectionDockingView extends CollectionSubView() {
this.stateChanged();
return true;
}
-
setupGoldenLayout = async () => {
- const config = StrCast(this.props.Document.dockingConfig);
- if (config) {
- const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g);
- const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) ?? [];
- await Promise.all(docids.map(id => DocServer.GetRefField(id)));
-
- if (this._goldenLayout) {
- if (config === JSON.stringify(this._goldenLayout.toConfig())) {
- return;
- } else {
- try {
- this._goldenLayout.unbind('tabCreated', this.tabCreated);
- this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
- this._goldenLayout.unbind('stackCreated', this.stackCreated);
- } catch (e) {}
- }
- this.tabMap.clear();
- this._goldenLayout.destroy();
+ const config = StrCast(this.props.Document.dockingConfig, JSON.stringify(DashboardView.resetDashboard(this.props.Document)));
+ const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+ const docids = matches?.map(m => m.replace('"documentId":"', '').replace('"', '')) ?? [];
+
+ await Promise.all(docids.map(id => DocServer.GetRefField(id)));
+
+ if (this._goldenLayout) {
+ if (config === JSON.stringify(this._goldenLayout.toConfig())) {
+ return;
+ } else {
+ try {
+ this._goldenLayout.unbind('tabCreated', this.tabCreated);
+ this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
+ this._goldenLayout.unbind('stackCreated', this.stackCreated);
+ } catch (e) {}
}
- const glay = (this._goldenLayout = new GoldenLayout(JSON.parse(config)));
- glay.on('tabCreated', this.tabCreated);
- glay.on('tabDestroyed', this.tabDestroyed);
- glay.on('stackCreated', this.stackCreated);
- glay.registerComponent('DocumentFrameRenderer', TabDocView);
- glay.container = this._containerRef.current;
- glay.init();
- glay.root.layoutManager.on('itemDropped', this.tabItemDropped);
- glay.root.layoutManager.on('dragStart', this.tabDragStart);
- glay.root.layoutManager.on('activeContentItemChanged', this.stateChanged);
+ this.tabMap.clear();
+ this._goldenLayout.destroy();
}
+ const glay = (this._goldenLayout = new GoldenLayout(JSON.parse(config)));
+ glay.on('tabCreated', this.tabCreated);
+ glay.on('tabDestroyed', this.tabDestroyed);
+ glay.on('stackCreated', this.stackCreated);
+ glay.registerComponent('DocumentFrameRenderer', TabDocView);
+ glay.container = this._containerRef.current;
+ glay.init();
+ glay.root.layoutManager.on('itemDropped', this.tabItemDropped);
+ glay.root.layoutManager.on('dragStart', this.tabDragStart);
+ glay.root.layoutManager.on('activeContentItemChanged', this.stateChanged);
};
componentDidMount: () => void = () => {
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index a3c742f28..ea3c122a4 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -33,7 +33,10 @@ export namespace Field {
return !Field.IsField(field) ? '' : (onDelegate ? '=' : '') + (field instanceof ComputedField ? `:=${field.script.originalScript}` : Field.toScriptString(field));
}
export function toScriptString(field: Field): string {
- if (typeof field === 'string') return `"${field}"`;
+ if (typeof field === 'string') {
+ if (field.startsWith('{"')) return `'${field}'`; // bcz: hack ... want to quote the string the right way. if there are nested "'s, then use ' instead of ". In this case, test for the start of a JSON string of the format {"property": ... } and use outer 's instead of "s
+ return `"${field}"`;
+ }
if (typeof field === 'number' || typeof field === 'boolean') return String(field);
if (field === undefined || field === null) return 'null';
return field[ToScriptString]();