mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix test flakiness by removing side effects from userStore preferences
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
a6d1b7a3a4
commit
f95ed19a7d
@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { Stats } from "fs";
|
||||
import fsInjectable from "../fs.injectable";
|
||||
import fsInjectable from "./fs.injectable";
|
||||
|
||||
export type Stat = (path: string) => Promise<Stats>;
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import statInjectable from "./stat.injectable";
|
||||
import { getGlobalOverride } from "../../test-utils/get-global-override";
|
||||
|
||||
export default getGlobalOverride(statInjectable, () => () => {
|
||||
throw new Error("Tried to call stat without explicit override");
|
||||
});
|
||||
@ -7,7 +7,7 @@ import type { AsyncResult } from "../utils/async-result";
|
||||
import { isErrnoException } from "../utils";
|
||||
import type { Stats } from "fs-extra";
|
||||
import { lowerFirst } from "lodash/fp";
|
||||
import statInjectable from "./stat/stat.injectable";
|
||||
import statInjectable from "./stat.injectable";
|
||||
|
||||
export type ValidateDirectory = (path: string) => Promise<AsyncResult<undefined>>;
|
||||
|
||||
|
||||
@ -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");
|
||||
14
src/common/user-store/current-timezone.injectable.ts
Normal file
14
src/common/user-store/current-timezone.injectable.ts
Normal file
@ -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";
|
||||
|
||||
const currentTimezoneInjectable = getInjectable({
|
||||
id: "current-timezone",
|
||||
instantiate: () => moment.tz.guess(true),
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default currentTimezoneInjectable;
|
||||
141
src/common/user-store/preference-descriptors.injectable.ts
Normal file
141
src/common/user-store/preference-descriptors.injectable.ts
Normal file
@ -0,0 +1,141 @@
|
||||
/**
|
||||
* 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 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[], Map<string, KubeconfigSyncValue>>({
|
||||
fromStore: val => new 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;
|
||||
@ -3,14 +3,9 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import moment from "moment-timezone";
|
||||
import path from "path";
|
||||
import os from "os";
|
||||
import type { editor } from "monaco-editor";
|
||||
import merge from "lodash/merge";
|
||||
import { defaultThemeId, defaultEditorFontFamily, defaultFontSize, defaultTerminalFontFamily } from "../vars";
|
||||
import type { ObservableMap } from "mobx";
|
||||
import { observable } from "mobx";
|
||||
import { defaultEditorFontFamily, defaultFontSize, defaultTerminalFontFamily } from "../vars";
|
||||
import type { PreferenceDescriptors } from "./preference-descriptors.injectable";
|
||||
|
||||
export interface KubeconfigSyncEntry extends KubeconfigSyncValue {
|
||||
filePath: string;
|
||||
@ -54,86 +49,8 @@ export interface PreferenceDescription<T, R = T> {
|
||||
toStore(val: R): T | undefined;
|
||||
}
|
||||
|
||||
const httpsProxy: PreferenceDescription<string | undefined> = {
|
||||
fromStore(val) {
|
||||
return val;
|
||||
},
|
||||
toStore(val) {
|
||||
return val || undefined;
|
||||
},
|
||||
};
|
||||
export const getPreferenceDescriptor = <T, R = T>(desc: PreferenceDescription<T, R>) => desc;
|
||||
|
||||
const shell: PreferenceDescription<string | undefined> = {
|
||||
fromStore(val) {
|
||||
return val;
|
||||
},
|
||||
toStore(val) {
|
||||
return val || undefined;
|
||||
},
|
||||
};
|
||||
|
||||
const colorTheme: PreferenceDescription<string> = {
|
||||
fromStore(val) {
|
||||
return val || defaultThemeId;
|
||||
},
|
||||
toStore(val) {
|
||||
if (!val || val === defaultThemeId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const terminalTheme: PreferenceDescription<string> = {
|
||||
fromStore(val) {
|
||||
return val || "";
|
||||
},
|
||||
toStore(val) {
|
||||
return val || undefined;
|
||||
},
|
||||
};
|
||||
|
||||
export const defaultLocaleTimezone = "UTC";
|
||||
|
||||
const localeTimezone: PreferenceDescription<string> = {
|
||||
fromStore(val) {
|
||||
return val || moment.tz.guess(true) || defaultLocaleTimezone;
|
||||
},
|
||||
toStore(val) {
|
||||
if (!val || val === moment.tz.guess(true) || val === defaultLocaleTimezone) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const allowUntrustedCAs: PreferenceDescription<boolean> = {
|
||||
fromStore(val) {
|
||||
return val ?? false;
|
||||
},
|
||||
toStore(val) {
|
||||
if (!val) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const allowErrorReporting: PreferenceDescription<boolean> = {
|
||||
fromStore(val) {
|
||||
return val ?? true;
|
||||
},
|
||||
toStore(val) {
|
||||
if (val === true) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
export interface DownloadMirror {
|
||||
url: string;
|
||||
@ -157,142 +74,6 @@ export const packageMirrors = new Map<string, DownloadMirror>([
|
||||
}],
|
||||
]);
|
||||
|
||||
const downloadMirror: PreferenceDescription<string> = {
|
||||
fromStore(val) {
|
||||
return !val || !packageMirrors.has(val)
|
||||
? defaultPackageMirror
|
||||
: val;
|
||||
},
|
||||
toStore(val) {
|
||||
if (!val || val === defaultPackageMirror) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const downloadKubectlBinaries: PreferenceDescription<boolean> = {
|
||||
fromStore(val) {
|
||||
return val ?? true;
|
||||
},
|
||||
toStore(val) {
|
||||
if (val === true) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const downloadBinariesPath: PreferenceDescription<string | undefined> = {
|
||||
fromStore(val) {
|
||||
return val;
|
||||
},
|
||||
toStore(val) {
|
||||
if (!val) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const kubectlBinariesPath: PreferenceDescription<string | undefined> = {
|
||||
fromStore(val) {
|
||||
return val;
|
||||
},
|
||||
toStore(val) {
|
||||
if (!val) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const openAtLogin: PreferenceDescription<boolean> = {
|
||||
fromStore(val) {
|
||||
return val ?? false;
|
||||
},
|
||||
toStore(val) {
|
||||
if (!val) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const terminalCopyOnSelect: PreferenceDescription<boolean> = {
|
||||
fromStore(val) {
|
||||
return val ?? false;
|
||||
},
|
||||
toStore(val) {
|
||||
if (!val) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const hiddenTableColumns: PreferenceDescription<[string, string[]][], Map<string, Set<string>>> = {
|
||||
fromStore(val) {
|
||||
return 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;
|
||||
},
|
||||
};
|
||||
|
||||
const mainKubeFolder = path.join(os.homedir(), ".kube");
|
||||
|
||||
const syncKubeconfigEntries: PreferenceDescription<KubeconfigSyncEntry[], ObservableMap<string, KubeconfigSyncValue>> = {
|
||||
fromStore(val) {
|
||||
return observable.map(
|
||||
val
|
||||
?.map(({ filePath, ...rest }) => [filePath, rest])
|
||||
?? [[mainKubeFolder, {}]],
|
||||
);
|
||||
},
|
||||
toStore(val) {
|
||||
if (val.size === 1 && val.has(mainKubeFolder)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return Array.from(val, ([filePath, rest]) => ({ filePath, ...rest }));
|
||||
},
|
||||
};
|
||||
|
||||
const editorConfiguration: PreferenceDescription<Partial<EditorConfiguration> | undefined, EditorConfiguration> = {
|
||||
fromStore(val) {
|
||||
return merge(defaultEditorConfig, val);
|
||||
},
|
||||
toStore(val) {
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
const terminalConfig: PreferenceDescription<TerminalConfig, TerminalConfig> = {
|
||||
fromStore(val) {
|
||||
return merge(defaultTerminalConfig, val);
|
||||
},
|
||||
toStore(val) {
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
export type ExtensionRegistryLocation = "default" | "npmrc" | "custom";
|
||||
|
||||
export type ExtensionRegistry = {
|
||||
@ -306,49 +87,13 @@ export type ExtensionRegistry = {
|
||||
export const defaultExtensionRegistryUrlLocation = "default";
|
||||
export const defaultExtensionRegistryUrl = "https://registry.npmjs.org";
|
||||
|
||||
const extensionRegistryUrl: PreferenceDescription<ExtensionRegistry> = {
|
||||
fromStore(val) {
|
||||
return val ?? {
|
||||
location: defaultExtensionRegistryUrlLocation,
|
||||
};
|
||||
},
|
||||
toStore(val) {
|
||||
if (val.location === defaultExtensionRegistryUrlLocation) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
};
|
||||
|
||||
type PreferencesModelType<field extends keyof typeof DESCRIPTORS> = typeof DESCRIPTORS[field] extends PreferenceDescription<infer T, any> ? T : never;
|
||||
type UserStoreModelType<field extends keyof typeof DESCRIPTORS> = typeof DESCRIPTORS[field] extends PreferenceDescription<any, infer T> ? T : never;
|
||||
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 typeof DESCRIPTORS]: UserStoreModelType<field>;
|
||||
[field in keyof PreferenceDescriptors]: UserStoreModelType<field>;
|
||||
};
|
||||
|
||||
export type UserPreferencesModel = {
|
||||
[field in keyof typeof DESCRIPTORS]: PreferencesModelType<field>;
|
||||
[field in keyof PreferenceDescriptors]: PreferencesModelType<field>;
|
||||
} & { updateChannel: string };
|
||||
|
||||
export const DESCRIPTORS = {
|
||||
httpsProxy,
|
||||
shell,
|
||||
colorTheme,
|
||||
terminalTheme,
|
||||
localeTimezone,
|
||||
allowUntrustedCAs,
|
||||
allowErrorReporting,
|
||||
downloadMirror,
|
||||
downloadKubectlBinaries,
|
||||
downloadBinariesPath,
|
||||
kubectlBinariesPath,
|
||||
openAtLogin,
|
||||
hiddenTableColumns,
|
||||
syncKubeconfigEntries,
|
||||
editorConfiguration,
|
||||
terminalCopyOnSelect,
|
||||
terminalConfig,
|
||||
extensionRegistryUrl,
|
||||
};
|
||||
|
||||
@ -17,6 +17,7 @@ import { shouldBaseStoreDisableSyncInIpcListenerInjectionToken } from "../base-s
|
||||
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",
|
||||
@ -34,6 +35,7 @@ const userStoreInjectable = getInjectable({
|
||||
persistStateToConfig: di.inject(persistStateToConfigInjectionToken),
|
||||
enlistMessageChannelListener: di.inject(enlistMessageChannelListenerInjectionToken),
|
||||
shouldDisableSyncInListener: di.inject(shouldBaseStoreDisableSyncInIpcListenerInjectionToken),
|
||||
preferenceDescriptors: di.inject(userStorePreferenceDescriptorsInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@ -7,13 +7,13 @@ import { action, observable, makeObservable, isObservableArray, isObservableSet,
|
||||
import type { BaseStoreDependencies } from "../base-store/base-store";
|
||||
import { BaseStore } from "../base-store/base-store";
|
||||
import { getOrInsertSet, toggle, toJS, object } from "../../renderer/utils";
|
||||
import { DESCRIPTORS } from "./preferences-helpers";
|
||||
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;
|
||||
@ -21,6 +21,7 @@ export interface UserStoreModel {
|
||||
|
||||
interface Dependencies extends BaseStoreDependencies {
|
||||
readonly selectedUpdateChannel: SelectedUpdateChannel;
|
||||
readonly preferenceDescriptors: PreferenceDescriptors;
|
||||
emitAppEvent: EmitAppEvent;
|
||||
}
|
||||
|
||||
@ -43,45 +44,45 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
|
||||
*/
|
||||
@observable newContexts = observable.set<string>();
|
||||
|
||||
@observable allowErrorReporting!: StoreType<typeof DESCRIPTORS["allowErrorReporting"]>;
|
||||
@observable allowUntrustedCAs!: StoreType<typeof DESCRIPTORS["allowUntrustedCAs"]>;
|
||||
@observable colorTheme!: StoreType<typeof DESCRIPTORS["colorTheme"]>;
|
||||
@observable terminalTheme!: StoreType<typeof DESCRIPTORS["terminalTheme"]>;
|
||||
@observable localeTimezone!: StoreType<typeof DESCRIPTORS["localeTimezone"]>;
|
||||
@observable downloadMirror!: StoreType<typeof DESCRIPTORS["downloadMirror"]>;
|
||||
@observable httpsProxy!: StoreType<typeof DESCRIPTORS["httpsProxy"]>;
|
||||
@observable shell!: StoreType<typeof DESCRIPTORS["shell"]>;
|
||||
@observable downloadBinariesPath!: StoreType<typeof DESCRIPTORS["downloadBinariesPath"]>;
|
||||
@observable kubectlBinariesPath!: StoreType<typeof DESCRIPTORS["kubectlBinariesPath"]>;
|
||||
@observable terminalCopyOnSelect!: StoreType<typeof DESCRIPTORS["terminalCopyOnSelect"]>;
|
||||
@observable terminalConfig!: StoreType<typeof DESCRIPTORS["terminalConfig"]>;
|
||||
@observable extensionRegistryUrl!: StoreType<typeof DESCRIPTORS["extensionRegistryUrl"]>;
|
||||
@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<typeof DESCRIPTORS["downloadKubectlBinaries"]>;
|
||||
@observable downloadKubectlBinaries!: StoreType<PreferenceDescriptors["downloadKubectlBinaries"]>;
|
||||
|
||||
/**
|
||||
* Whether the application should open itself at login.
|
||||
*/
|
||||
@observable openAtLogin!: StoreType<typeof DESCRIPTORS["openAtLogin"]>;
|
||||
@observable openAtLogin!: StoreType<PreferenceDescriptors["openAtLogin"]>;
|
||||
|
||||
/**
|
||||
* The column IDs under each configurable table ID that have been configured
|
||||
* to not be shown
|
||||
*/
|
||||
@observable hiddenTableColumns!: StoreType<typeof DESCRIPTORS["hiddenTableColumns"]>;
|
||||
@observable hiddenTableColumns!: StoreType<PreferenceDescriptors["hiddenTableColumns"]>;
|
||||
|
||||
/**
|
||||
* Monaco editor configs
|
||||
*/
|
||||
@observable editorConfiguration!: StoreType<typeof DESCRIPTORS["editorConfiguration"]>;
|
||||
@observable editorConfiguration!: StoreType<PreferenceDescriptors["editorConfiguration"]>;
|
||||
|
||||
/**
|
||||
* The set of file/folder paths to be synced
|
||||
*/
|
||||
@observable syncKubeconfigEntries!: StoreType<typeof DESCRIPTORS["syncKubeconfigEntries"]>;
|
||||
@observable syncKubeconfigEntries!: StoreType<PreferenceDescriptors["syncKubeconfigEntries"]>;
|
||||
|
||||
/**
|
||||
* Checks if a column (by ID) for a table (by ID) is configured to be hidden
|
||||
@ -112,14 +113,14 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
|
||||
|
||||
@action
|
||||
resetTheme() {
|
||||
this.colorTheme = DESCRIPTORS.colorTheme.fromStore(undefined);
|
||||
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(DESCRIPTORS)) {
|
||||
for (const [key, { fromStore }] of object.entries(this.dependencies.preferenceDescriptors)) {
|
||||
const curVal = this[key];
|
||||
const newVal = fromStore((preferences)?.[key] as never) as never;
|
||||
|
||||
@ -140,7 +141,7 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
|
||||
|
||||
toJSON(): UserStoreModel {
|
||||
const preferences = object.fromEntries(
|
||||
object.entries(DESCRIPTORS)
|
||||
object.entries(this.dependencies.preferenceDescriptors)
|
||||
.map(([key, { toStore }]) => [key, toStore(this[key] as never)]),
|
||||
) as UserPreferencesModel;
|
||||
|
||||
|
||||
@ -2524,12 +2524,40 @@ exports[`remove helm repository from list of active repositories in preferences
|
||||
Synced Items
|
||||
|
||||
</div>
|
||||
<div
|
||||
class="loading-spinner"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="Spinner singleColor"
|
||||
/>
|
||||
class="item flex gaps align-center justify-space-between mt-3"
|
||||
>
|
||||
<i
|
||||
class="Icon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="folder"
|
||||
>
|
||||
folder
|
||||
</span>
|
||||
</i>
|
||||
<div
|
||||
class="flex-grow break-all"
|
||||
>
|
||||
/some-home-dir/.kube
|
||||
</div>
|
||||
<i
|
||||
class="Icon material interactive focusable"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="delete"
|
||||
>
|
||||
delete
|
||||
</span>
|
||||
</i>
|
||||
<div>
|
||||
Remove
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@ -8,12 +8,13 @@ import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import type { UserStore } from "../../../../../../common/user-store";
|
||||
import userStoreInjectable from "../../../../../../common/user-store/user-store.injectable";
|
||||
import { Select } from "../../../../../../renderer/components/select";
|
||||
import { defaultLocaleTimezone } from "../../../../../../common/user-store/preferences-helpers";
|
||||
import moment from "moment-timezone";
|
||||
import { observer } from "mobx-react";
|
||||
import currentTimezoneInjectable from "../../../../../../common/user-store/current-timezone.injectable";
|
||||
|
||||
interface Dependencies {
|
||||
userStore: UserStore;
|
||||
currentTimezone: string;
|
||||
}
|
||||
|
||||
const timezoneOptions = moment.tz.names()
|
||||
@ -23,26 +24,26 @@ const timezoneOptions = moment.tz.names()
|
||||
}));
|
||||
|
||||
|
||||
const NonInjectedTimezone = observer(({ userStore }: Dependencies) => (
|
||||
const NonInjectedTimezone = observer(({
|
||||
userStore,
|
||||
currentTimezone,
|
||||
}: Dependencies) => (
|
||||
<section id="locale">
|
||||
<SubTitle title="Locale Timezone" />
|
||||
<Select
|
||||
id="timezone-input"
|
||||
options={timezoneOptions}
|
||||
value={userStore.localeTimezone}
|
||||
onChange={value => userStore.localeTimezone = value?.value ?? defaultLocaleTimezone}
|
||||
onChange={value => userStore.localeTimezone = value?.value ?? currentTimezone}
|
||||
themeName="lens"
|
||||
/>
|
||||
</section>
|
||||
|
||||
));
|
||||
|
||||
export const Timezone = withInjectables<Dependencies>(
|
||||
NonInjectedTimezone,
|
||||
|
||||
{
|
||||
getProps: (di) => ({
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
export const Timezone = withInjectables<Dependencies>(NonInjectedTimezone, {
|
||||
getProps: (di) => ({
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
currentTimezone: di.inject(currentTimezoneInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
@ -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 type { SyncKind } from "./discover-sync-kind.injectable";
|
||||
import discoverKubeconfigSyncKindInjectable from "./discover-sync-kind.injectable";
|
||||
|
||||
export type DiscoverAllKubeconfigSyncKinds = (filePaths: string[]) => Promise<[string, SyncKind][]>;
|
||||
|
||||
const discoverAllKubeconfigSyncKindsInjectable = getInjectable({
|
||||
id: "discover-all-kubeconfig-sync-kinds",
|
||||
instantiate: (di): DiscoverAllKubeconfigSyncKinds => {
|
||||
const discoverKubeconfigSyncKind = di.inject(discoverKubeconfigSyncKindInjectable);
|
||||
|
||||
return filePaths => Promise.all(filePaths.map(discoverKubeconfigSyncKind));
|
||||
},
|
||||
});
|
||||
|
||||
export default discoverAllKubeconfigSyncKindsInjectable;
|
||||
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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 statInjectable from "../../../../../../common/fs/stat.injectable";
|
||||
import loggerInjectable from "../../../../../../common/logger.injectable";
|
||||
|
||||
export interface SyncKind {
|
||||
type: "file" | "folder" | "unknown";
|
||||
}
|
||||
|
||||
export type DiscoverKubeconfigSyncKind = (path: string) => Promise<[string, SyncKind]>;
|
||||
|
||||
const discoverKubeconfigSyncKindInjectable = getInjectable({
|
||||
id: "discover-kubeconfig-sync-kind",
|
||||
instantiate: (di): DiscoverKubeconfigSyncKind => {
|
||||
const stat = di.inject(statInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return async (path) => {
|
||||
try {
|
||||
// stat follows the stat(2) linux syscall spec, namely it follows symlinks
|
||||
const stats = await stat(path);
|
||||
|
||||
if (stats.isFile()) {
|
||||
return [path, { type: "file" }];
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
return [path, { type: "folder" }];
|
||||
}
|
||||
|
||||
logger.warn("[KUBECONFIG-SYNCS]: unknown stat entry", { stats });
|
||||
|
||||
return [path, { type: "unknown" }];
|
||||
} catch (error) {
|
||||
logger.warn(`[KUBECONFIG-SYNCS]: failed to stat entry: ${error}`, { error });
|
||||
|
||||
return [path, { type: "unknown" }];
|
||||
}
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default discoverKubeconfigSyncKindInjectable;
|
||||
@ -3,12 +3,11 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import fse from "fs-extra";
|
||||
import { computed, makeObservable, observable, reaction } from "mobx";
|
||||
import { action, computed, makeObservable, observable, reaction } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import React from "react";
|
||||
import { Notice } from "../../../../../../renderer/components/+extensions/notice";
|
||||
import type { KubeconfigSyncEntry, KubeconfigSyncValue, UserStore } from "../../../../../../common/user-store";
|
||||
import type { UserStore } from "../../../../../../common/user-store";
|
||||
import { iter, tuple } from "../../../../../../renderer/utils";
|
||||
import { SubTitle } from "../../../../../../renderer/components/layout/sub-title";
|
||||
import { PathPicker } from "../../../../../../renderer/components/path-picker/path-picker";
|
||||
@ -18,56 +17,26 @@ import userStoreInjectable from "../../../../../../common/user-store/user-store.
|
||||
import isWindowsInjectable from "../../../../../../common/vars/is-windows.injectable";
|
||||
import loggerInjectable from "../../../../../../common/logger.injectable";
|
||||
import type { Logger } from "../../../../../../common/logger";
|
||||
import type { DiscoverAllKubeconfigSyncKinds } from "./discover-all-sync-kinds.injectable";
|
||||
import type { DiscoverKubeconfigSyncKind, SyncKind } from "./discover-sync-kind.injectable";
|
||||
import discoverKubeconfigSyncKindInjectable from "./discover-sync-kind.injectable";
|
||||
import discoverAllKubeconfigSyncKindsInjectable from "./discover-all-sync-kinds.injectable";
|
||||
|
||||
interface SyncInfo {
|
||||
type: "file" | "folder" | "unknown";
|
||||
}
|
||||
|
||||
interface Entry extends Value {
|
||||
interface Entry extends SyncKind {
|
||||
filePath: string;
|
||||
}
|
||||
|
||||
interface Value {
|
||||
data: KubeconfigSyncValue;
|
||||
info: SyncInfo;
|
||||
}
|
||||
|
||||
async function getMapEntry({ filePath, ...data }: KubeconfigSyncEntry, logger: Logger): Promise<[string, Value]> {
|
||||
try {
|
||||
// stat follows the stat(2) linux syscall spec, namely it follows symlinks
|
||||
const stats = await fse.stat(filePath);
|
||||
|
||||
if (stats.isFile()) {
|
||||
return [filePath, { info: { type: "file" }, data }];
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
return [filePath, { info: { type: "folder" }, data }];
|
||||
}
|
||||
|
||||
logger.warn("[KubeconfigSyncs]: unknown stat entry", { stats });
|
||||
|
||||
return [filePath, { info: { type: "unknown" }, data }];
|
||||
} catch (error) {
|
||||
logger.warn(`[KubeconfigSyncs]: failed to stat entry: ${error}`, { error });
|
||||
|
||||
return [filePath, { info: { type: "unknown" }, data }];
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAllEntries(filePaths: string[], logger: Logger): Promise<[string, Value][]> {
|
||||
return Promise.all(filePaths.map(filePath => getMapEntry({ filePath }, logger)));
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
userStore: UserStore;
|
||||
isWindows: boolean;
|
||||
logger: Logger;
|
||||
discoverAllKubeconfigSyncKinds: DiscoverAllKubeconfigSyncKinds;
|
||||
discoverKubeconfigSyncKind: DiscoverKubeconfigSyncKind;
|
||||
}
|
||||
|
||||
@observer
|
||||
class NonInjectedKubeconfigSync extends React.Component<Dependencies> {
|
||||
syncs = observable.map<string, Value>();
|
||||
readonly syncs = observable.map<string, SyncKind>();
|
||||
@observable loaded = false;
|
||||
|
||||
constructor(props: Dependencies) {
|
||||
@ -79,7 +48,7 @@ class NonInjectedKubeconfigSync extends React.Component<Dependencies> {
|
||||
const mapEntries = await Promise.all(
|
||||
iter.map(
|
||||
this.props.userStore.syncKubeconfigEntries,
|
||||
([filePath, ...value]) => getMapEntry({ filePath, ...value }, this.props.logger),
|
||||
([filePath]) => this.props.discoverKubeconfigSyncKind(filePath),
|
||||
),
|
||||
);
|
||||
|
||||
@ -88,9 +57,13 @@ class NonInjectedKubeconfigSync extends React.Component<Dependencies> {
|
||||
|
||||
disposeOnUnmount(this, [
|
||||
reaction(
|
||||
() => Array.from(this.syncs.entries(), ([filePath, { data }]) => tuple.from(filePath, data)),
|
||||
() => Array.from(this.syncs.entries(), ([filePath, kind]) => tuple.from(filePath, kind)),
|
||||
syncs => {
|
||||
this.props.userStore.syncKubeconfigEntries.replace(syncs);
|
||||
action(() => {
|
||||
for (const [path] of syncs) {
|
||||
this.props.userStore.syncKubeconfigEntries.set(path, {});
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
]);
|
||||
@ -105,11 +78,11 @@ class NonInjectedKubeconfigSync extends React.Component<Dependencies> {
|
||||
}
|
||||
|
||||
onPick = async (filePaths: string[]) => {
|
||||
this.syncs.merge(await getAllEntries(filePaths, this.props.logger));
|
||||
this.syncs.merge(await this.props.discoverAllKubeconfigSyncKinds(filePaths));
|
||||
};
|
||||
|
||||
getIconName(entry: Entry) {
|
||||
switch (entry.info.type) {
|
||||
switch (entry.type) {
|
||||
case "file":
|
||||
return "description";
|
||||
case "folder":
|
||||
@ -206,14 +179,12 @@ class NonInjectedKubeconfigSync extends React.Component<Dependencies> {
|
||||
}
|
||||
}
|
||||
|
||||
export const KubeconfigSync = withInjectables<Dependencies>(
|
||||
NonInjectedKubeconfigSync,
|
||||
|
||||
{
|
||||
getProps: (di) => ({
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
isWindows: di.inject(isWindowsInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
}),
|
||||
},
|
||||
);
|
||||
export const KubeconfigSync = withInjectables<Dependencies>(NonInjectedKubeconfigSync, {
|
||||
getProps: (di) => ({
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
isWindows: di.inject(isWindowsInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
discoverAllKubeconfigSyncKinds: di.inject(discoverAllKubeconfigSyncKindsInjectable),
|
||||
discoverKubeconfigSyncKind: di.inject(discoverKubeconfigSyncKindInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
@ -22,9 +22,9 @@ import kubeconfigSyncsInjectable from "../../../common/user-store/kubeconfig-syn
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import type { AsyncFnMock } from "@async-fn/jest";
|
||||
import type { Stat } from "../../../common/fs/stat/stat.injectable";
|
||||
import type { Stat } from "../../../common/fs/stat.injectable";
|
||||
import asyncFn from "@async-fn/jest";
|
||||
import statInjectable from "../../../common/fs/stat/stat.injectable";
|
||||
import statInjectable from "../../../common/fs/stat.injectable";
|
||||
import type { Watcher } from "../../../common/fs/watch/watch.injectable";
|
||||
import watchInjectable from "../../../common/fs/watch/watch.injectable";
|
||||
import EventEmitter from "events";
|
||||
|
||||
@ -10,7 +10,7 @@ import path from "path";
|
||||
import { inspect } from "util";
|
||||
import type { CatalogEntity } from "../../../common/catalog";
|
||||
import type { Cluster } from "../../../common/cluster/cluster";
|
||||
import statInjectable from "../../../common/fs/stat/stat.injectable";
|
||||
import statInjectable from "../../../common/fs/stat.injectable";
|
||||
import type { Watcher } from "../../../common/fs/watch/watch.injectable";
|
||||
import watchInjectable from "../../../common/fs/watch/watch.injectable";
|
||||
import type { Disposer } from "../../../common/utils";
|
||||
|
||||
@ -9,7 +9,7 @@ import helmChartManagerCacheInjectable from "./helm-chart-manager-cache.injectab
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import execHelmInjectable from "./exec-helm/exec-helm.injectable";
|
||||
import readFileInjectable from "../../common/fs/read-file.injectable";
|
||||
import statInjectable from "../../common/fs/stat/stat.injectable";
|
||||
import statInjectable from "../../common/fs/stat.injectable";
|
||||
|
||||
const helmChartManagerInjectable = getInjectable({
|
||||
id: "helm-chart-manager",
|
||||
|
||||
@ -11,7 +11,7 @@ import type { Logger } from "../../common/logger";
|
||||
import type { RepoHelmChartList } from "../../common/k8s-api/endpoints/helm-charts.api/request-charts.injectable";
|
||||
import type { ExecHelm } from "./exec-helm/exec-helm.injectable";
|
||||
import type { ReadFile } from "../../common/fs/read-file.injectable";
|
||||
import type { Stat } from "../../common/fs/stat/stat.injectable";
|
||||
import type { Stat } from "../../common/fs/stat.injectable";
|
||||
|
||||
export interface HelmCacheFile {
|
||||
apiVersion: string;
|
||||
|
||||
@ -23,7 +23,7 @@ import userShellSettingInjectable from "../../../common/user-store/shell-setting
|
||||
import appNameInjectable from "../../../common/vars/app-name.injectable";
|
||||
import buildVersionInjectable from "../../vars/build-version/build-version.injectable";
|
||||
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||
import statInjectable from "../../../common/fs/stat/stat.injectable";
|
||||
import statInjectable from "../../../common/fs/stat.injectable";
|
||||
|
||||
export interface OpenLocalShellSessionArgs {
|
||||
websocket: WebSocket;
|
||||
|
||||
@ -18,7 +18,7 @@ import userShellSettingInjectable from "../../../common/user-store/shell-setting
|
||||
import appNameInjectable from "../../../common/vars/app-name.injectable";
|
||||
import buildVersionInjectable from "../../vars/build-version/build-version.injectable";
|
||||
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||
import statInjectable from "../../../common/fs/stat/stat.injectable";
|
||||
import statInjectable from "../../../common/fs/stat.injectable";
|
||||
|
||||
export interface NodeShellSessionArgs {
|
||||
websocket: WebSocket;
|
||||
|
||||
@ -17,7 +17,7 @@ import type { ComputeShellEnvironment } from "../../features/shell-sync/main/com
|
||||
import type { SpawnPty } from "./spawn-pty.injectable";
|
||||
import type { InitializableState } from "../../common/initializable-state/create";
|
||||
import type { EmitAppEvent } from "../../common/app-event-bus/emit-event.injectable";
|
||||
import type { Stat } from "../../common/fs/stat/stat.injectable";
|
||||
import type { Stat } from "../../common/fs/stat.injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
|
||||
export class ShellOpenError extends Error {
|
||||
|
||||
@ -13,7 +13,7 @@ import { getDiForUnitTesting } from "../../../getDiForUnitTesting";
|
||||
import type { DiRender } from "../../test-utils/renderFor";
|
||||
import { renderFor } from "../../test-utils/renderFor";
|
||||
import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable";
|
||||
import statInjectable from "../../../../common/fs/stat/stat.injectable";
|
||||
import statInjectable from "../../../../common/fs/stat.injectable";
|
||||
|
||||
describe("ClusterLocalTerminalSettings", () => {
|
||||
let render: DiRender;
|
||||
|
||||
@ -69,6 +69,9 @@ import { getCompositePaths } from "../../../common/utils/composite/get-composite
|
||||
import { discoverFor } from "./discovery-of-html-elements";
|
||||
import { findComposite } from "../../../common/utils/composite/find-composite/find-composite";
|
||||
import shouldStartHiddenInjectable from "../../../main/electron-app/features/should-start-hidden.injectable";
|
||||
import fsInjectable from "../../../common/fs/fs.injectable";
|
||||
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
||||
import homeDirectoryPathInjectable from "../../../common/os/home-directory-path.injectable";
|
||||
|
||||
type Callback = (di: DiContainer) => void | Promise<void>;
|
||||
|
||||
@ -179,6 +182,15 @@ export const getApplicationBuilder = () => {
|
||||
|
||||
overrideFsWithFakes(mainDi);
|
||||
|
||||
// Set up ~/.kube as existing as a folder
|
||||
{
|
||||
const { ensureDirSync } = mainDi.inject(fsInjectable);
|
||||
const joinPaths = mainDi.inject(joinPathsInjectable);
|
||||
const homeDirectoryPath = mainDi.inject(homeDirectoryPathInjectable);
|
||||
|
||||
ensureDirSync(joinPaths(homeDirectoryPath, ".kube"));
|
||||
}
|
||||
|
||||
let environment = environments.application;
|
||||
|
||||
mainDi.override(mainExtensionsInjectable, (di) => {
|
||||
|
||||
@ -2,13 +2,13 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getAllEntries } from "../../features/preferences/renderer/preference-items/kubernetes/kubeconfig-sync/kubeconfig-sync";
|
||||
import { Notifications } from "../components/notifications";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
||||
import React from "react";
|
||||
import navigateToKubernetesPreferencesInjectable from "../../features/preferences/common/navigate-to-kubernetes-preferences.injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import discoverAllKubeconfigSyncKindsInjectable from "../../features/preferences/renderer/preference-items/kubernetes/kubeconfig-sync/discover-all-sync-kinds.injectable";
|
||||
import { action } from "mobx";
|
||||
|
||||
const addSyncEntriesInjectable = getInjectable({
|
||||
id: "add-sync-entries",
|
||||
@ -16,12 +16,16 @@ const addSyncEntriesInjectable = getInjectable({
|
||||
instantiate: (di) => {
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
const navigateToKubernetesPreferences = di.inject(navigateToKubernetesPreferencesInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
const discoverAllKubeconfigSyncKinds = di.inject(discoverAllKubeconfigSyncKindsInjectable);
|
||||
|
||||
return async (filePaths: string[]) => {
|
||||
userStore.syncKubeconfigEntries.merge(
|
||||
await getAllEntries(filePaths, logger),
|
||||
);
|
||||
const kinds = await discoverAllKubeconfigSyncKinds(filePaths);
|
||||
|
||||
action(() => {
|
||||
for (const [path] of kinds) {
|
||||
userStore.syncKubeconfigEntries.set(path, {});
|
||||
}
|
||||
});
|
||||
|
||||
Notifications.ok((
|
||||
<div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user