mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) support ?embed=true and &style=light for a clean embed experience
Summary: This adds query parameters useful for tailoring the Grist experience, with an eye to embedding. Setting `style=light` removes side and top bars, as a first pass at a focused view of a single document page (this would benefit from refining). Setting `embed=true` has no significant effect just yet other than it restricts document access to viewer at most (this can be overridden by specifying `/m/default`). Test Plan: added tests Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2585
This commit is contained in:
@@ -8,8 +8,9 @@ export type DocEntryTag = ''|'sample'|'invite'|'shared';
|
||||
|
||||
export const OpenDocMode = StringUnion(
|
||||
'default', // open doc with user's maximal access level
|
||||
'fork', // open doc limited to view access (if user has at least that level of access)
|
||||
'view' // as for 'view', but suggest a fork on any attempt to edit
|
||||
'view', // open doc limited to view access (if user has at least that level of access)
|
||||
'fork', // as for 'view', but suggest a fork on any attempt to edit - the client will
|
||||
// enable the editing UI experience and trigger a fork on any edit.
|
||||
);
|
||||
export type OpenDocMode = typeof OpenDocMode.type;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {BillingPage, BillingSubPage, BillingTask} from 'app/common/BillingAPI';
|
||||
import {OpenDocMode} from 'app/common/DocListAPI';
|
||||
import {encodeQueryParams} from 'app/common/gutil';
|
||||
import {encodeQueryParams, isAffirmative} from 'app/common/gutil';
|
||||
import {localhostRegex} from 'app/common/LoginState';
|
||||
import {Document} from 'app/common/UserAPI';
|
||||
import identity = require('lodash/identity');
|
||||
@@ -17,6 +17,10 @@ export type IHomePage = typeof HomePage.type;
|
||||
export const WelcomePage = StringUnion('user', 'teams');
|
||||
export type WelcomePage = typeof WelcomePage.type;
|
||||
|
||||
// Overall UI style. "full" is normal, "light" is a single page focused, panels hidden experience.
|
||||
export const InterfaceStyle = StringUnion('light', 'full');
|
||||
export type InterfaceStyle = typeof InterfaceStyle.type;
|
||||
|
||||
// Default subdomain for home api service if not otherwise specified.
|
||||
export const DEFAULT_HOME_SUBDOMAIN = 'api';
|
||||
|
||||
@@ -59,6 +63,8 @@ export interface IGristUrlState {
|
||||
params?: {
|
||||
billingPlan?: string;
|
||||
billingTask?: BillingTask;
|
||||
embed?: boolean;
|
||||
style?: InterfaceStyle;
|
||||
};
|
||||
hash?: HashLink; // if present, this specifies an individual row within a section of a page.
|
||||
}
|
||||
@@ -240,6 +246,16 @@ export function decodeUrl(gristConfig: Partial<GristLoadConfig>, location: Locat
|
||||
if (sp.has('billingTask')) {
|
||||
state.params!.billingTask = parseBillingTask(sp.get('billingTask')!);
|
||||
}
|
||||
if (sp.has('style')) {
|
||||
state.params!.style = parseInterfaceStyle(sp.get('style')!);
|
||||
}
|
||||
if (sp.has('embed')) {
|
||||
const embed = state.params!.embed = isAffirmative(sp.get('embed'));
|
||||
// Turn view mode on if no mode has been specified.
|
||||
if (embed && !state.mode) { state.mode = 'view'; }
|
||||
// Turn on light style if no style has been specified.
|
||||
if (embed && !state.params!.style) { state.params!.style = 'light'; }
|
||||
}
|
||||
if (location.hash) {
|
||||
const hash = location.hash;
|
||||
const hashParts = hash.split('.');
|
||||
@@ -301,6 +317,13 @@ function parseWelcomePage(p: string): WelcomePage {
|
||||
return WelcomePage.guard(p) ? p : 'user';
|
||||
}
|
||||
|
||||
/**
|
||||
* Read interface style and make sure it is either valid or left undefined.
|
||||
*/
|
||||
function parseInterfaceStyle(t: string): InterfaceStyle|undefined {
|
||||
return InterfaceStyle.guard(t) ? t : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the URL like "foo.bar.baz" into the pair {org: "foo", base: ".bar.baz"}.
|
||||
* Port is allowed and included into base.
|
||||
|
||||
@@ -780,3 +780,12 @@ export async function isLongerThan(promise: Promise<any>, timeoutMsec: number):
|
||||
]);
|
||||
return isPending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the parameter, when rendered as a string, matches
|
||||
* 1, on, or true (case insensitively). Useful for processing query
|
||||
* parameters that may have been manually set.
|
||||
*/
|
||||
export function isAffirmative(parameter: any): boolean {
|
||||
return ['1', 'on', 'true', 'yes'].includes(String(parameter).toLowerCase());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user