Line data Source code
1 : import type { AppSettings } from './app_config.js';
2 :
3 : /// The logo of a flavor
4 : export interface AppFlavorLogo {
5 : /// The id of the symbol in the svg sprite
6 : symbol: string;
7 : /// The width of the logo relative to its height, 1 for a square mark
8 : aspectRatio: number;
9 : /// Does the logo spell out the name? The name is then not repeated next to it
10 : wordmark: boolean;
11 : }
12 :
13 : /// The features of a flavor.
14 : /// Unlike the app settings, they are fixed by the flavor and can neither be changed by the user nor persisted.
15 : export interface AppFlavorFeatures {
16 : /// Can sessions be exported as .dashql archives?
17 : sessionArchiveExport: boolean;
18 : }
19 :
20 : /// A page that a flavor will have, announced by a disabled button in the rail
21 : export interface AppFlavorUpcomingPage {
22 : type: 'upcoming';
23 : /// The label of the button
24 : label: string;
25 : /// The id of the icon in the svg sprite
26 : icon: string;
27 : }
28 :
29 : /// A page of the rail, the workspace, the shell or a page that is not there yet
30 : export type AppFlavorRailPage = { type: 'workspace' } | { type: 'shell' } | AppFlavorUpcomingPage;
31 :
32 1 : const WORKSPACE: AppFlavorRailPage = { type: 'workspace' };
33 1 : const SHELL: AppFlavorRailPage = { type: 'shell' };
34 :
35 : /// A page that is not there yet
36 1 : function upcoming(label: string, icon: string): AppFlavorUpcomingPage {
37 1 : return { type: 'upcoming', label, icon };
38 1 : }
39 :
40 : /// A product flavor of the app: brand identity, theme tokens and settings defaults.
41 : /// The theme tokens live in `@ankoh/dashql-ui/styles/flavors/<id>.css`, scoped to `:root[data-flavor="<id>"]`.
42 : export interface AppFlavor {
43 : /// The flavor id, used in `?flavor=<id>` and as the `data-flavor` attribute
44 : id: string;
45 : /// The product name shown in the UI and the document title
46 : displayName: string;
47 : /// The logo
48 : logo: AppFlavorLogo;
49 : /// The tagline shown in smaller type next to the logo in the navbar of the shell, null shows none
50 : tagline: string | null;
51 : /// The favicon replacing the static favicons of the html entry pages, null keeps them
52 : favicon: URL | null;
53 : /// The features
54 : features: AppFlavorFeatures;
55 : /// The pages of the rail in groups with a separator between them.
56 : /// The pages that are not there yet are disabled buttons.
57 : railPages: AppFlavorRailPage[][];
58 : /// Settings layered over the settings of config.json, persisted user settings still win
59 : settings?: AppSettings;
60 : }
61 :
62 : /// The default flavor, the static html entry pages are branded for it
63 1 : export const DASHQL_FLAVOR: AppFlavor = {
64 1 : id: 'dashql',
65 1 : displayName: 'DashQL',
66 1 : logo: { symbol: 'dashql', aspectRatio: 1, wordmark: false },
67 1 : tagline: null,
68 1 : favicon: null,
69 1 : features: {
70 1 : sessionArchiveExport: true,
71 1 : },
72 1 : railPages: [[WORKSPACE, SHELL]],
73 1 : };
74 :
75 : /// The sidb flavor
76 1 : export const SIDB_FLAVOR: AppFlavor = {
77 1 : id: 'sidb',
78 1 : displayName: 'SIDB',
79 1 : logo: { symbol: 'sidb', aspectRatio: 2231 / 688, wordmark: true },
80 1 : tagline: 'powered by Hyper',
81 1 : favicon: new URL('../../static/favicons/sidb/favicon.svg?no-inline', import.meta.url),
82 1 : features: {
83 1 : sessionArchiveExport: false,
84 1 : },
85 1 : railPages: [
86 1 : [WORKSPACE, SHELL, upcoming('Ingestion', 'upload_24'), upcoming('Data Pipelines', 'workflow_24')],
87 1 : [
88 1 : upcoming('Indexes', 'tree_structure_24'),
89 1 : upcoming('AI & ML', 'ai_model_24'),
90 1 : upcoming('PostgreSQL', 'postgresql_24'),
91 1 : upcoming('Marketplace', 'apps_24'),
92 1 : ],
93 1 : [
94 1 : upcoming('Catalog', 'database_24'),
95 1 : upcoming('Monitoring', 'pulse_24'),
96 1 : upcoming('Governance', 'shield_lock_24'),
97 1 : upcoming('Sharing', 'share_android_24'),
98 1 : ],
99 1 : [upcoming('Compute', 'zap_24'), upcoming('Admin', 'settings_24')],
100 1 : ],
101 1 : };
102 :
103 : /// All flavors by id
104 1 : export const FLAVORS: Map<string, AppFlavor> = new Map([DASHQL_FLAVOR, SIDB_FLAVOR].map(f => [f.id, f]));
105 :
106 : /// Layer the settings of a flavor over the settings of the app config
107 1 : export function applyFlavorSettings(settings: AppSettings | undefined, flavor: AppFlavor): AppSettings | undefined {
108 1 : if (flavor.settings == null) {
109 1 : return settings;
110 : }
111 1 : return { ...(settings ?? {}), ...flavor.settings };
112 1 : }
|