mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-13 16:14:07 -08:00
fix(editor): Allow overriding theme from query params (#7591)
Allow overriding theme through query params.. to be able to override it from preview iframe in webcomponent Github issue / Community forum post (link here to close automatically):
This commit is contained in:
parent
59dc36abd9
commit
2854a0cf46
23
cypress/e2e/31-demo.cy.ts
Normal file
23
cypress/e2e/31-demo.cy.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import workflow from '../fixtures/Manual_wait_set.json';
|
||||||
|
import { importWorkflow, vistDemoPage } from '../pages/demo';
|
||||||
|
import { WorkflowPage } from '../pages/workflow';
|
||||||
|
|
||||||
|
const workflowPage = new WorkflowPage();
|
||||||
|
|
||||||
|
describe('Demo', () => {
|
||||||
|
it('can import template', () => {
|
||||||
|
vistDemoPage();
|
||||||
|
importWorkflow(workflow);
|
||||||
|
workflowPage.getters.canvasNodes().should('have.length', 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can override theme to dark', () => {
|
||||||
|
vistDemoPage('dark');
|
||||||
|
cy.get('body').should('have.attr', 'data-theme', 'dark');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can override theme to light', () => {
|
||||||
|
vistDemoPage('light');
|
||||||
|
cy.get('body').should('have.attr', 'data-theme', 'light');
|
||||||
|
});
|
||||||
|
});
|
21
cypress/pages/demo.ts
Normal file
21
cypress/pages/demo.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* Actions
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function vistDemoPage(theme?: 'dark' | 'light') {
|
||||||
|
const query = theme ? `?theme=${theme}` : '';
|
||||||
|
cy.visit('/workflows/demo' + query);
|
||||||
|
cy.waitForLoad();
|
||||||
|
cy.window().then((win) => {
|
||||||
|
// @ts-ignore
|
||||||
|
win.preventNodeViewBeforeUnload = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function importWorkflow(workflow: object) {
|
||||||
|
const OPEN_WORKFLOW = {command: 'openWorkflow', workflow};
|
||||||
|
cy.window().then($window => {
|
||||||
|
const message = JSON.stringify(OPEN_WORKFLOW);
|
||||||
|
$window.postMessage(message, '*')
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
import { BasePage } from './base';
|
import { BasePage } from './base';
|
||||||
import { WorkflowPage } from './workflow';
|
|
||||||
|
|
||||||
const workflowPage = new WorkflowPage();
|
|
||||||
export class TemplatesPage extends BasePage {
|
export class TemplatesPage extends BasePage {
|
||||||
url = '/templates';
|
url = '/templates';
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ import {
|
||||||
DEBUG_PAYWALL_MODAL_KEY,
|
DEBUG_PAYWALL_MODAL_KEY,
|
||||||
N8N_PRICING_PAGE_URL,
|
N8N_PRICING_PAGE_URL,
|
||||||
WORKFLOW_HISTORY_VERSION_RESTORE,
|
WORKFLOW_HISTORY_VERSION_RESTORE,
|
||||||
LOCAL_STORAGE_THEME,
|
|
||||||
} from '@/constants';
|
} from '@/constants';
|
||||||
import type {
|
import type {
|
||||||
CloudUpdateLinkSourceType,
|
CloudUpdateLinkSourceType,
|
||||||
|
@ -64,37 +63,23 @@ import { useCloudPlanStore } from '@/stores/cloudPlan.store';
|
||||||
import { useTelemetryStore } from '@/stores/telemetry.store';
|
import { useTelemetryStore } from '@/stores/telemetry.store';
|
||||||
import { dismissBannerPermanently } from '@/api/ui';
|
import { dismissBannerPermanently } from '@/api/ui';
|
||||||
import type { BannerName } from 'n8n-workflow';
|
import type { BannerName } from 'n8n-workflow';
|
||||||
|
import {
|
||||||
|
addThemeToBody,
|
||||||
|
getPreferredTheme,
|
||||||
|
getThemeOverride,
|
||||||
|
isValidTheme,
|
||||||
|
updateTheme,
|
||||||
|
} from './ui.utils';
|
||||||
|
|
||||||
let savedTheme: ThemeOption = 'system';
|
let savedTheme: ThemeOption = 'system';
|
||||||
try {
|
try {
|
||||||
const value = localStorage.getItem(LOCAL_STORAGE_THEME) as AppliedThemeOption;
|
const value = getThemeOverride();
|
||||||
if (['light', 'dark'].includes(value)) {
|
if (isValidTheme(value)) {
|
||||||
savedTheme = value;
|
savedTheme = value;
|
||||||
addThemeToBody(value);
|
addThemeToBody(value);
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
function addThemeToBody(theme: AppliedThemeOption) {
|
|
||||||
window.document.body.setAttribute('data-theme', theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTheme(theme: ThemeOption) {
|
|
||||||
if (theme === 'system') {
|
|
||||||
window.document.body.removeAttribute('data-theme');
|
|
||||||
localStorage.removeItem(LOCAL_STORAGE_THEME);
|
|
||||||
} else {
|
|
||||||
addThemeToBody(theme);
|
|
||||||
localStorage.setItem(LOCAL_STORAGE_THEME, theme);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPreferredTheme(): AppliedThemeOption {
|
|
||||||
const isDarkMode =
|
|
||||||
!!window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)')?.matches;
|
|
||||||
|
|
||||||
return isDarkMode ? 'dark' : 'light';
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useUIStore = defineStore(STORES.UI, {
|
export const useUIStore = defineStore(STORES.UI, {
|
||||||
state: (): UIState => ({
|
state: (): UIState => ({
|
||||||
activeActions: [],
|
activeActions: [],
|
||||||
|
|
36
packages/editor-ui/src/stores/ui.utils.ts
Normal file
36
packages/editor-ui/src/stores/ui.utils.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import type { AppliedThemeOption, ThemeOption } from '@/Interface';
|
||||||
|
import { LOCAL_STORAGE_THEME } from '@/constants';
|
||||||
|
|
||||||
|
export function addThemeToBody(theme: AppliedThemeOption) {
|
||||||
|
window.document.body.setAttribute('data-theme', theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isValidTheme(theme: string | null): theme is AppliedThemeOption {
|
||||||
|
return !!theme && ['light', 'dark'].includes(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
// query param allows overriding theme for demo view in preview iframe without flickering
|
||||||
|
export function getThemeOverride() {
|
||||||
|
return getQueryParam('theme') || localStorage.getItem(LOCAL_STORAGE_THEME);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getQueryParam(paramName: string): string | null {
|
||||||
|
return new URLSearchParams(window.location.search).get(paramName);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateTheme(theme: ThemeOption) {
|
||||||
|
if (theme === 'system') {
|
||||||
|
window.document.body.removeAttribute('data-theme');
|
||||||
|
localStorage.removeItem(LOCAL_STORAGE_THEME);
|
||||||
|
} else {
|
||||||
|
addThemeToBody(theme);
|
||||||
|
localStorage.setItem(LOCAL_STORAGE_THEME, theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPreferredTheme(): AppliedThemeOption {
|
||||||
|
const isDarkMode =
|
||||||
|
!!window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)')?.matches;
|
||||||
|
|
||||||
|
return isDarkMode ? 'dark' : 'light';
|
||||||
|
}
|
Loading…
Reference in a new issue