mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Restructure to monorepo (#6907)
* wip: restructure to monorepo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor create-release-pr to a package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * github workflow fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix typo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * add webpack-env types to core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix github workflows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor/fix integration tests Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * lint fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * yarn run dev Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * eslint settings for vscode Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * move templates to right package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * open-lens build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * integration test fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix nx task dependencies Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * use bash shell for unit tests in test workflow Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix test:unit for windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix build:app on windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove ELECTRON_BUILDER_EXTRA_ARGS Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * sync src/ from master Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove Makefile from core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
1 parent
0066ca4ea2
commit
2657df2293
3321 files changed
+28699
-11447
No files matched your search
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { getGlobalOverride } from "../test-utils/get-global-override";
|
||||
import currentTimezoneInjectable from "./current-timezone.injectable";
|
||||
|
||||
export default getGlobalOverride(currentTimezoneInjectable, () => "Etc/GMT");
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import moment from "moment-timezone";
|
||||
|
||||
const currentTimezoneInjectable = getInjectable({
|
||||
id: "current-timezone",
|
||||
instantiate: () => moment.tz.guess(true),
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default currentTimezoneInjectable;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { getGlobalOverride } from "../test-utils/get-global-override";
|
||||
import userStoreFileNameMigrationInjectable from "./file-name-migration.injectable";
|
||||
|
||||
export default getGlobalOverride(userStoreFileNameMigrationInjectable, () => async () => {});
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import fse from "fs-extra";
|
||||
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||
import { isErrnoException } from "../utils";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import joinPathsInjectable from "../path/join-paths.injectable";
|
||||
|
||||
export type UserStoreFileNameMigration = () => Promise<void>;
|
||||
|
||||
const userStoreFileNameMigrationInjectable = getInjectable({
|
||||
id: "user-store-file-name-migration",
|
||||
instantiate: (di): UserStoreFileNameMigration => {
|
||||
const userDataPath = di.inject(directoryForUserDataInjectable);
|
||||
const joinPaths = di.inject(joinPathsInjectable);
|
||||
const configJsonPath = joinPaths(userDataPath, "config.json");
|
||||
const lensUserStoreJsonPath = joinPaths(userDataPath, "lens-user-store.json");
|
||||
|
||||
return async () => {
|
||||
try {
|
||||
await fse.move(configJsonPath, lensUserStoreJsonPath);
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message === "dest already exists.") {
|
||||
await fse.remove(configJsonPath);
|
||||
} else if (isErrnoException(error) && error.code === "ENOENT" && error.path === configJsonPath) {
|
||||
// (No such file or directory)
|
||||
return; // file already moved
|
||||
} else {
|
||||
// pass other errors along
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default userStoreFileNameMigrationInjectable;
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import userStoreInjectable from "./user-store.injectable";
|
||||
|
||||
const httpsProxyConfigurationInjectable = getInjectable({
|
||||
id: "https-proxy-configuration",
|
||||
instantiate: (di) => {
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
|
||||
return computed(() => userStore.httpsProxy);
|
||||
},
|
||||
});
|
||||
|
||||
export default httpsProxyConfigurationInjectable;
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
export * from "./user-store";
|
||||
export type { KubeconfigSyncEntry, KubeconfigSyncValue, UserPreferencesModel } from "./preferences-helpers";
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import userStoreInjectable from "./user-store.injectable";
|
||||
|
||||
const kubeconfigSyncsInjectable = getInjectable({
|
||||
id: "kubeconfig-syncs",
|
||||
instantiate: (di) => di.inject(userStoreInjectable).syncKubeconfigEntries,
|
||||
});
|
||||
|
||||
export default kubeconfigSyncsInjectable;
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import userStoreInjectable from "./user-store.injectable";
|
||||
|
||||
export type LensColorThemePreference = {
|
||||
useSystemTheme: true;
|
||||
} | {
|
||||
useSystemTheme: false;
|
||||
lensThemeId: string;
|
||||
};
|
||||
|
||||
const lensColorThemePreferenceInjectable = getInjectable({
|
||||
id: "lens-color-theme-preference",
|
||||
instantiate: (di) => {
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
|
||||
return computed((): LensColorThemePreference => {
|
||||
// TODO: remove magic strings
|
||||
if (userStore.colorTheme === "system") {
|
||||
return {
|
||||
useSystemTheme: true,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
useSystemTheme: false,
|
||||
lensThemeId: userStore.colorTheme,
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default lensColorThemePreferenceInjectable;
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||
import type { MigrationDeclaration } from "../base-store/migrations.injectable";
|
||||
|
||||
export const userStoreMigrationInjectionToken = getInjectionToken<MigrationDeclaration>({
|
||||
id: "user-store-migration-token",
|
||||
});
|
||||
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { merge } from "lodash";
|
||||
import type { ObservableMap } from "mobx";
|
||||
import { observable } from "mobx";
|
||||
import homeDirectoryPathInjectable from "../os/home-directory-path.injectable";
|
||||
import joinPathsInjectable from "../path/join-paths.injectable";
|
||||
import { defaultThemeId } from "../vars";
|
||||
import currentTimezoneInjectable from "./current-timezone.injectable";
|
||||
import type { EditorConfiguration, ExtensionRegistry, KubeconfigSyncEntry, KubeconfigSyncValue, TerminalConfig } from "./preferences-helpers";
|
||||
import { defaultExtensionRegistryUrlLocation, defaultEditorConfig, defaultTerminalConfig, defaultPackageMirror, getPreferenceDescriptor, packageMirrors } from "./preferences-helpers";
|
||||
|
||||
export type PreferenceDescriptors = ReturnType<typeof userStorePreferenceDescriptorsInjectable["instantiate"]>;
|
||||
|
||||
const userStorePreferenceDescriptorsInjectable = getInjectable({
|
||||
id: "user-store-preference-descriptors",
|
||||
instantiate: (di) => {
|
||||
const currentTimezone = di.inject(currentTimezoneInjectable);
|
||||
const joinPaths = di.inject(joinPathsInjectable);
|
||||
const homeDirectoryPath = di.inject(homeDirectoryPathInjectable);
|
||||
|
||||
const mainKubeFolderPath = joinPaths(homeDirectoryPath, ".kube");
|
||||
|
||||
return ({
|
||||
httpsProxy: getPreferenceDescriptor<string | undefined>({
|
||||
fromStore: val => val,
|
||||
toStore: val => val || undefined,
|
||||
}),
|
||||
shell: getPreferenceDescriptor<string | undefined>({
|
||||
fromStore: val => val,
|
||||
toStore: val => val || undefined,
|
||||
}),
|
||||
colorTheme: getPreferenceDescriptor<string>({
|
||||
fromStore: val => val || defaultThemeId,
|
||||
toStore: val => !val || val === defaultThemeId
|
||||
? undefined
|
||||
: val,
|
||||
}),
|
||||
terminalTheme: getPreferenceDescriptor<string>({
|
||||
fromStore: val => val || "",
|
||||
toStore: val => val || undefined,
|
||||
}),
|
||||
localeTimezone: getPreferenceDescriptor<string>({
|
||||
fromStore: val => val || currentTimezone,
|
||||
toStore: val => !val || val === currentTimezone
|
||||
? undefined
|
||||
: val,
|
||||
}),
|
||||
allowUntrustedCAs: getPreferenceDescriptor<boolean>({
|
||||
fromStore: val => val ?? false,
|
||||
toStore: val => !val
|
||||
? undefined
|
||||
: val,
|
||||
}),
|
||||
allowErrorReporting: getPreferenceDescriptor<boolean>({
|
||||
fromStore: val => val ?? true,
|
||||
toStore: val => val
|
||||
? undefined
|
||||
: val,
|
||||
}),
|
||||
downloadMirror: getPreferenceDescriptor<string>({
|
||||
fromStore: val => !val || !packageMirrors.has(val)
|
||||
? defaultPackageMirror
|
||||
: val,
|
||||
toStore: val => val === defaultPackageMirror
|
||||
? undefined
|
||||
: val,
|
||||
}),
|
||||
downloadKubectlBinaries: getPreferenceDescriptor<boolean>({
|
||||
fromStore: val => val ?? true,
|
||||
toStore: val => val
|
||||
? undefined
|
||||
: val,
|
||||
}),
|
||||
downloadBinariesPath: getPreferenceDescriptor<string | undefined>({
|
||||
fromStore: val => val,
|
||||
toStore: val => val || undefined,
|
||||
}),
|
||||
kubectlBinariesPath: getPreferenceDescriptor<string | undefined>({
|
||||
fromStore: val => val,
|
||||
toStore: val => val || undefined,
|
||||
}),
|
||||
openAtLogin: getPreferenceDescriptor<boolean>({
|
||||
fromStore: val => val ?? false,
|
||||
toStore: val => !val
|
||||
? undefined
|
||||
: val,
|
||||
}),
|
||||
terminalCopyOnSelect: getPreferenceDescriptor<boolean>({
|
||||
fromStore: val => val ?? false,
|
||||
toStore: val => !val
|
||||
? undefined
|
||||
: val,
|
||||
}),
|
||||
hiddenTableColumns: getPreferenceDescriptor<[string, string[]][], Map<string, Set<string>>>({
|
||||
fromStore: (val = []) => new Map(
|
||||
val.map(([tableId, columnIds]) => [tableId, new Set(columnIds)]),
|
||||
),
|
||||
toStore: (val) => {
|
||||
const res: [string, string[]][] = [];
|
||||
|
||||
for (const [table, columns] of val) {
|
||||
if (columns.size) {
|
||||
res.push([table, Array.from(columns)]);
|
||||
}
|
||||
}
|
||||
|
||||
return res.length ? res : undefined;
|
||||
},
|
||||
}),
|
||||
syncKubeconfigEntries: getPreferenceDescriptor<KubeconfigSyncEntry[], ObservableMap<string, KubeconfigSyncValue>>({
|
||||
fromStore: val => observable.map(
|
||||
val?.map(({ filePath, ...rest }) => [filePath, rest])
|
||||
?? [[mainKubeFolderPath, {}]],
|
||||
),
|
||||
toStore: val => val.size === 1 && val.has(mainKubeFolderPath)
|
||||
? undefined
|
||||
: Array.from(val, ([filePath, rest]) => ({ filePath, ...rest })),
|
||||
}),
|
||||
editorConfiguration: getPreferenceDescriptor<Partial<EditorConfiguration>, EditorConfiguration>({
|
||||
fromStore: val => merge(defaultEditorConfig, val),
|
||||
toStore: val => val,
|
||||
}),
|
||||
terminalConfig: getPreferenceDescriptor<Partial<TerminalConfig>, TerminalConfig>({
|
||||
fromStore: val => merge(defaultTerminalConfig, val),
|
||||
toStore: val => val,
|
||||
}),
|
||||
extensionRegistryUrl: getPreferenceDescriptor<ExtensionRegistry>({
|
||||
fromStore: val => val ?? {
|
||||
location: defaultExtensionRegistryUrlLocation,
|
||||
},
|
||||
toStore: val => val.location === defaultExtensionRegistryUrlLocation
|
||||
? undefined
|
||||
: val,
|
||||
}),
|
||||
}) as const;
|
||||
},
|
||||
});
|
||||
|
||||
export default userStorePreferenceDescriptorsInjectable;
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { editor } from "monaco-editor";
|
||||
import { defaultEditorFontFamily, defaultFontSize, defaultTerminalFontFamily } from "../vars";
|
||||
import type { PreferenceDescriptors } from "./preference-descriptors.injectable";
|
||||
|
||||
export interface KubeconfigSyncEntry extends KubeconfigSyncValue {
|
||||
filePath: string;
|
||||
}
|
||||
|
||||
export interface KubeconfigSyncValue {
|
||||
}
|
||||
export interface TerminalConfig {
|
||||
fontSize: number;
|
||||
fontFamily: string;
|
||||
}
|
||||
|
||||
export const defaultTerminalConfig: TerminalConfig = {
|
||||
fontSize: defaultFontSize,
|
||||
fontFamily: defaultTerminalFontFamily,
|
||||
};
|
||||
|
||||
interface BaseEditorConfiguration extends Required<Pick<editor.IStandaloneEditorConstructionOptions, "minimap" | "tabSize" | "fontSize" | "fontFamily">> {
|
||||
lineNumbers: NonNullable<Exclude<editor.IStandaloneEditorConstructionOptions["lineNumbers"], Function>>;
|
||||
}
|
||||
|
||||
export type EditorConfiguration = Required<BaseEditorConfiguration>;
|
||||
|
||||
export const defaultEditorConfig: EditorConfiguration = {
|
||||
tabSize: 2,
|
||||
lineNumbers: "on",
|
||||
fontSize: defaultFontSize,
|
||||
fontFamily: defaultEditorFontFamily,
|
||||
minimap: {
|
||||
enabled: true,
|
||||
side: "right",
|
||||
},
|
||||
};
|
||||
|
||||
export type StoreType<P> = P extends PreferenceDescription<unknown, infer Store>
|
||||
? Store
|
||||
: never;
|
||||
|
||||
export interface PreferenceDescription<T, R = T> {
|
||||
fromStore(val: T | undefined): R;
|
||||
toStore(val: R): T | undefined;
|
||||
}
|
||||
|
||||
export const getPreferenceDescriptor = <T, R = T>(desc: PreferenceDescription<T, R>) => desc;
|
||||
|
||||
|
||||
export interface DownloadMirror {
|
||||
url: string;
|
||||
label: string;
|
||||
platforms: Set<NodeJS.Platform>;
|
||||
}
|
||||
|
||||
export const defaultPackageMirror = "default";
|
||||
const defaultDownloadMirrorData: DownloadMirror = {
|
||||
url: "https://storage.googleapis.com/kubernetes-release/release",
|
||||
label: "Default (Google)",
|
||||
platforms: new Set(["darwin", "win32", "linux"]),
|
||||
};
|
||||
|
||||
export const packageMirrors = new Map<string, DownloadMirror>([
|
||||
[defaultPackageMirror, defaultDownloadMirrorData],
|
||||
["china", {
|
||||
url: "https://mirror.azure.cn/kubernetes/kubectl",
|
||||
label: "China (Azure)",
|
||||
platforms: new Set(["win32", "linux"]),
|
||||
}],
|
||||
]);
|
||||
|
||||
export type ExtensionRegistryLocation = "default" | "npmrc" | "custom";
|
||||
|
||||
export type ExtensionRegistry = {
|
||||
location: "default" | "npmrc";
|
||||
customUrl?: undefined;
|
||||
} | {
|
||||
location: "custom";
|
||||
customUrl: string;
|
||||
};
|
||||
|
||||
export const defaultExtensionRegistryUrlLocation = "default";
|
||||
export const defaultExtensionRegistryUrl = "https://registry.npmjs.org";
|
||||
|
||||
type PreferencesModelType<field extends keyof PreferenceDescriptors> = PreferenceDescriptors[field] extends PreferenceDescription<infer T, any> ? T : never;
|
||||
type UserStoreModelType<field extends keyof PreferenceDescriptors> = PreferenceDescriptors[field] extends PreferenceDescription<any, infer T> ? T : never;
|
||||
|
||||
export type UserStoreFlatModel = {
|
||||
[field in keyof PreferenceDescriptors]: UserStoreModelType<field>;
|
||||
};
|
||||
|
||||
export type UserPreferencesModel = {
|
||||
[field in keyof PreferenceDescriptors]: PreferencesModelType<field>;
|
||||
} & { updateChannel: string };
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import userInfoInjectable from "./user-info.injectable";
|
||||
import userStoreInjectable from "./user-store.injectable";
|
||||
|
||||
const userShellSettingInjectable = getInjectable({
|
||||
id: "user-shell-setting",
|
||||
instantiate: (di) => {
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
const userInfo = di.inject(userInfoInjectable);
|
||||
|
||||
return computed(() => userStore.shell || userInfo.shell);
|
||||
},
|
||||
});
|
||||
|
||||
export default userShellSettingInjectable;
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import { toJS } from "../utils";
|
||||
import userStoreInjectable from "./user-store.injectable";
|
||||
|
||||
const terminalConfigInjectable = getInjectable({
|
||||
id: "terminal-config",
|
||||
instantiate: (di) => {
|
||||
const store = di.inject(userStoreInjectable);
|
||||
|
||||
return computed(() => toJS(store.terminalConfig));
|
||||
},
|
||||
});
|
||||
|
||||
export default terminalConfigInjectable;
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import userStoreInjectable from "./user-store.injectable";
|
||||
|
||||
const terminalCopyOnSelectInjectable = getInjectable({
|
||||
id: "terminal-copy-on-select",
|
||||
instantiate: (di) => {
|
||||
const store = di.inject(userStoreInjectable);
|
||||
|
||||
return computed(() => store.terminalCopyOnSelect);
|
||||
},
|
||||
});
|
||||
|
||||
export default terminalCopyOnSelectInjectable;
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import userStoreInjectable from "./user-store.injectable";
|
||||
|
||||
export type TerminalThemePreference = {
|
||||
matchLensTheme: true;
|
||||
} | {
|
||||
matchLensTheme: false;
|
||||
themeId: string;
|
||||
};
|
||||
|
||||
const terminalThemePreferenceInjectable = getInjectable({
|
||||
id: "terminal-theme-preference",
|
||||
instantiate: (di) => {
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
|
||||
return computed((): TerminalThemePreference => {
|
||||
// NOTE: remove use of magic strings
|
||||
if (!userStore.terminalTheme) {
|
||||
return {
|
||||
matchLensTheme: true,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
matchLensTheme: false,
|
||||
themeId: userStore.terminalTheme,
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default terminalThemePreferenceInjectable;
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { getGlobalOverride } from "../test-utils/get-global-override";
|
||||
import userInfoInjectable from "./user-info.injectable";
|
||||
|
||||
export default getGlobalOverride(userInfoInjectable, () => ({
|
||||
gid: 1,
|
||||
homedir: "/some-home-dir",
|
||||
shell: "bash",
|
||||
uid: 2,
|
||||
username: "some-user-name",
|
||||
}));
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { userInfo } from "os";
|
||||
|
||||
const userInfoInjectable = getInjectable({
|
||||
id: "user-info",
|
||||
instantiate: () => userInfo(),
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default userInfoInjectable;
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { UserStore } from "./user-store";
|
||||
import selectedUpdateChannelInjectable from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
||||
import emitAppEventInjectable from "../app-event-bus/emit-event.injectable";
|
||||
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||
import getConfigurationFileModelInjectable from "../get-configuration-file-model/get-configuration-file-model.injectable";
|
||||
import loggerInjectable from "../logger.injectable";
|
||||
import storeMigrationVersionInjectable from "../vars/store-migration-version.injectable";
|
||||
import storeMigrationsInjectable from "../base-store/migrations.injectable";
|
||||
import { userStoreMigrationInjectionToken } from "./migrations-token";
|
||||
import { baseStoreIpcChannelPrefixesInjectionToken } from "../base-store/channel-prefix";
|
||||
import { shouldBaseStoreDisableSyncInIpcListenerInjectionToken } from "../base-store/disable-sync";
|
||||
import { persistStateToConfigInjectionToken } from "../base-store/save-to-file";
|
||||
import getBasenameOfPathInjectable from "../path/get-basename.injectable";
|
||||
import { enlistMessageChannelListenerInjectionToken } from "../utils/channel/enlist-message-channel-listener-injection-token";
|
||||
import userStorePreferenceDescriptorsInjectable from "./preference-descriptors.injectable";
|
||||
|
||||
const userStoreInjectable = getInjectable({
|
||||
id: "user-store",
|
||||
|
||||
instantiate: (di) => new UserStore({
|
||||
selectedUpdateChannel: di.inject(selectedUpdateChannelInjectable),
|
||||
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||
directoryForUserData: di.inject(directoryForUserDataInjectable),
|
||||
getConfigurationFileModel: di.inject(getConfigurationFileModelInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
storeMigrationVersion: di.inject(storeMigrationVersionInjectable),
|
||||
migrations: di.inject(storeMigrationsInjectable, userStoreMigrationInjectionToken),
|
||||
getBasenameOfPath: di.inject(getBasenameOfPathInjectable),
|
||||
ipcChannelPrefixes: di.inject(baseStoreIpcChannelPrefixesInjectionToken),
|
||||
persistStateToConfig: di.inject(persistStateToConfigInjectionToken),
|
||||
enlistMessageChannelListener: di.inject(enlistMessageChannelListenerInjectionToken),
|
||||
shouldDisableSyncInListener: di.inject(shouldBaseStoreDisableSyncInIpcListenerInjectionToken),
|
||||
preferenceDescriptors: di.inject(userStorePreferenceDescriptorsInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
export default userStoreInjectable;
|
||||
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { action, observable, makeObservable, isObservableArray, isObservableSet, isObservableMap } from "mobx";
|
||||
import type { BaseStoreDependencies } from "../base-store/base-store";
|
||||
import { BaseStore } from "../base-store/base-store";
|
||||
import { getOrInsertSet, toggle, toJS, object } from "../../renderer/utils";
|
||||
import type { UserPreferencesModel, StoreType } from "./preferences-helpers";
|
||||
import type { EmitAppEvent } from "../app-event-bus/emit-event.injectable";
|
||||
|
||||
// TODO: Remove coupling with Feature
|
||||
import type { SelectedUpdateChannel } from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
||||
import type { ReleaseChannel } from "../../features/application-update/common/update-channels";
|
||||
import type { PreferenceDescriptors } from "./preference-descriptors.injectable";
|
||||
|
||||
export interface UserStoreModel {
|
||||
preferences: UserPreferencesModel;
|
||||
}
|
||||
|
||||
interface Dependencies extends BaseStoreDependencies {
|
||||
readonly selectedUpdateChannel: SelectedUpdateChannel;
|
||||
readonly preferenceDescriptors: PreferenceDescriptors;
|
||||
emitAppEvent: EmitAppEvent;
|
||||
}
|
||||
|
||||
export class UserStore extends BaseStore<UserStoreModel> /* implements UserStoreFlatModel (when strict null is enabled) */ {
|
||||
constructor(protected readonly dependencies: Dependencies) {
|
||||
super(dependencies, {
|
||||
configName: "lens-user-store",
|
||||
});
|
||||
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated No longer used
|
||||
*/
|
||||
@observable seenContexts = observable.set<string>();
|
||||
|
||||
/**
|
||||
* @deprecated No longer used
|
||||
*/
|
||||
@observable newContexts = observable.set<string>();
|
||||
|
||||
@observable allowErrorReporting!: StoreType<PreferenceDescriptors["allowErrorReporting"]>;
|
||||
@observable allowUntrustedCAs!: StoreType<PreferenceDescriptors["allowUntrustedCAs"]>;
|
||||
@observable colorTheme!: StoreType<PreferenceDescriptors["colorTheme"]>;
|
||||
@observable terminalTheme!: StoreType<PreferenceDescriptors["terminalTheme"]>;
|
||||
@observable localeTimezone!: StoreType<PreferenceDescriptors["localeTimezone"]>;
|
||||
@observable downloadMirror!: StoreType<PreferenceDescriptors["downloadMirror"]>;
|
||||
@observable httpsProxy!: StoreType<PreferenceDescriptors["httpsProxy"]>;
|
||||
@observable shell!: StoreType<PreferenceDescriptors["shell"]>;
|
||||
@observable downloadBinariesPath!: StoreType<PreferenceDescriptors["downloadBinariesPath"]>;
|
||||
@observable kubectlBinariesPath!: StoreType<PreferenceDescriptors["kubectlBinariesPath"]>;
|
||||
@observable terminalCopyOnSelect!: StoreType<PreferenceDescriptors["terminalCopyOnSelect"]>;
|
||||
@observable terminalConfig!: StoreType<PreferenceDescriptors["terminalConfig"]>;
|
||||
@observable extensionRegistryUrl!: StoreType<PreferenceDescriptors["extensionRegistryUrl"]>;
|
||||
|
||||
/**
|
||||
* Download kubectl binaries matching cluster version
|
||||
*/
|
||||
@observable downloadKubectlBinaries!: StoreType<PreferenceDescriptors["downloadKubectlBinaries"]>;
|
||||
|
||||
/**
|
||||
* Whether the application should open itself at login.
|
||||
*/
|
||||
@observable openAtLogin!: StoreType<PreferenceDescriptors["openAtLogin"]>;
|
||||
|
||||
/**
|
||||
* The column IDs under each configurable table ID that have been configured
|
||||
* to not be shown
|
||||
*/
|
||||
@observable hiddenTableColumns!: StoreType<PreferenceDescriptors["hiddenTableColumns"]>;
|
||||
|
||||
/**
|
||||
* Monaco editor configs
|
||||
*/
|
||||
@observable editorConfiguration!: StoreType<PreferenceDescriptors["editorConfiguration"]>;
|
||||
|
||||
/**
|
||||
* The set of file/folder paths to be synced
|
||||
*/
|
||||
@observable syncKubeconfigEntries!: StoreType<PreferenceDescriptors["syncKubeconfigEntries"]>;
|
||||
|
||||
/**
|
||||
* Checks if a column (by ID) for a table (by ID) is configured to be hidden
|
||||
* @param tableId The ID of the table to be checked against
|
||||
* @param columnIds The list of IDs the check if one is hidden
|
||||
* @returns true if at least one column under the table is set to hidden
|
||||
*/
|
||||
isTableColumnHidden(tableId: string, ...columnIds: (string | undefined)[]): boolean {
|
||||
if (columnIds.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const config = this.hiddenTableColumns.get(tableId);
|
||||
|
||||
if (!config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return columnIds.some(columnId => columnId && config.has(columnId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the hidden configuration of a table's column
|
||||
*/
|
||||
toggleTableColumnVisibility(tableId: string, columnId: string) {
|
||||
toggle(getOrInsertSet(this.hiddenTableColumns, tableId), columnId);
|
||||
}
|
||||
|
||||
@action
|
||||
resetTheme() {
|
||||
this.colorTheme = this.dependencies.preferenceDescriptors.colorTheme.fromStore(undefined);
|
||||
}
|
||||
|
||||
@action
|
||||
protected fromStore({ preferences }: Partial<UserStoreModel> = {}) {
|
||||
this.dependencies.logger.debug("UserStore.fromStore()", { preferences });
|
||||
|
||||
for (const [key, { fromStore }] of object.entries(this.dependencies.preferenceDescriptors)) {
|
||||
const curVal = this[key];
|
||||
const newVal = fromStore((preferences)?.[key] as never) as never;
|
||||
|
||||
if (isObservableArray(curVal)) {
|
||||
curVal.replace(newVal);
|
||||
} else if (isObservableSet(curVal) || isObservableMap(curVal)) {
|
||||
curVal.replace(newVal);
|
||||
} else {
|
||||
this[key] = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Switch to action-based saving instead saving stores by reaction
|
||||
if (preferences?.updateChannel) {
|
||||
this.dependencies.selectedUpdateChannel.setValue(preferences?.updateChannel as ReleaseChannel);
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): UserStoreModel {
|
||||
const preferences = object.fromEntries(
|
||||
object.entries(this.dependencies.preferenceDescriptors)
|
||||
.map(([key, { toStore }]) => [key, toStore(this[key] as never)]),
|
||||
) as UserPreferencesModel;
|
||||
|
||||
return toJS({
|
||||
preferences: {
|
||||
...preferences,
|
||||
updateChannel: this.dependencies.selectedUpdateChannel.value.get().id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user