(core) New look for site switcher in top-left corner, with support for per-org logos

Summary:
  - Site switcher will show initials (either from user's name or team name),
  - Anonymous users see a grist logo on personal site, but team logo (or initials) on team site,
  - Admin pages (and other pages without orgs) show grist logo,
  - Custom image can be switched on the billing page, common formats are supported up to 100KB.
  - Larger images are down-scaled (on the front-end)
  - SVG larger than 100KB are not accepted
  - Files are stored as data URL's in org prefs,

Test Plan: Added new tests

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D4341
This commit is contained in:
Jarosław Sadziński
2024-10-07 16:54:03 +02:00
parent e8f9da9b5c
commit 0bdc838975
15 changed files with 267 additions and 91 deletions

View File

@@ -149,7 +149,8 @@ export interface ILimit {
export interface IBillingOrgSettings {
name: string;
domain: string;
domain: string|null;
customLogoUrl?: string|null;
}
// Full description of billing account, including nested list of orgs and managers.
@@ -204,7 +205,7 @@ export interface BillingAPI {
getSubscription(): Promise<IBillingSubscription>;
getBillingAccount(): Promise<FullBillingAccount>;
updateBillingManagers(delta: ManagerDelta): Promise<void>;
updateSettings(settings: IBillingOrgSettings): Promise<void>;
updateSettings(settings: Partial<IBillingOrgSettings>): Promise<void>;
subscriptionStatus(planId: string): Promise<boolean>;
createFreeTeam(name: string, domain: string): Promise<void>;
createTeam(name: string, domain: string, plan: PlanSelection, next?: string): Promise<{
@@ -261,7 +262,7 @@ export class BillingAPIImpl extends BaseAPI implements BillingAPI {
});
}
public async updateSettings(settings?: IBillingOrgSettings): Promise<void> {
public async updateSettings(settings?: Partial<IBillingOrgSettings>): Promise<void> {
await this.request(`${this._url}/api/billing/settings`, {
method: 'POST',
body: JSON.stringify({ settings })

View File

@@ -4,8 +4,8 @@ import {UserPrefs} from 'app/common/Prefs';
// User profile info for the user. When using Cognito, it is fetched during login.
export interface UserProfile {
email: string; // TODO: Used inconsistently: as lowercase login email or display email.
loginEmail?: string; // When set, this is consistently normalized (lowercase) login email.
name: string;
loginEmail?: string; // When set, this is consistently normalized (lowercase) login email.
picture?: string|null; // when present, a url to a public image of unspecified dimensions.
anonymous?: boolean; // when present, asserts whether user is anonymous (not authorized).
connectId?: string|null, // used by GristConnect to identify user in external provider.

View File

@@ -56,7 +56,10 @@ export interface UserOrgPrefs extends Prefs {
seenDocTours?: string[];
}
export type OrgPrefs = Prefs;
export interface OrgPrefs extends Prefs {
/* The URL (might be data url) of the custom logo to use for the org. */
customLogoUrl?: string|null;
}
/**
* List of all deprecated warnings that user can see and dismiss.

View File

@@ -451,6 +451,9 @@ export const ThemeColors = t.iface([], {
"markdown-cell-light-bg": "string",
"markdown-cell-light-border": "string",
"markdown-cell-medium-border": "string",
"app-header-bg": "string",
"app-header-hover-bg": "string",
"app-header-border": "string",
});
const exportedTypeSuite: t.ITypeSuite = {

View File

@@ -589,6 +589,11 @@ export interface ThemeColors {
'markdown-cell-light-bg': string;
'markdown-cell-light-border': string;
'markdown-cell-medium-border': string;
/* App Header */
'app-header-bg': string;
'app-header-hover-bg': string;
'app-header-border': string;
}
export const ThemePrefsChecker = createCheckers(ThemePrefsTI).ThemePrefs as CheckerT<ThemePrefs>;

View File

@@ -568,4 +568,9 @@ export const GristDark: ThemeColors = {
'markdown-cell-light-bg': '#494958',
'markdown-cell-light-border': '#32323F',
'markdown-cell-medium-border': '#555563',
/* App Header */
'app-header-bg': '#32323F',
'app-header-border': '#FFFFFF00',
'app-header-hover-bg': 'rgba(111,111,125,0.6)',
};

View File

@@ -568,4 +568,9 @@ export const GristLight: ThemeColors = {
'markdown-cell-light-bg': '#F7F7F7',
'markdown-cell-light-border': '#E8E8E8',
'markdown-cell-medium-border': '#D9D9D9',
/* App header */
'app-header-bg': 'var(--grist-theme-page-panels-main-panel-bg)',
'app-header-border': 'var(--grist-theme-menu-border)',
'app-header-hover-bg': 'var(--grist-theme-hover)',
};