1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

responding to comments / clean up

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2021-10-27 11:25:21 +03:00
parent a33165044e
commit a02538999a
6 changed files with 38 additions and 53 deletions

View File

@ -24,16 +24,14 @@ import glob from "glob";
import path from "path";
import os from "os";
import { promisify } from "util";
import { action, makeObservable, observable } from "mobx";
import { action, makeObservable, observable, ObservableMap } from "mobx";
import logger from "../../../common/logger";
import { DockTabStore } from "./dock-tab.store";
import { dockStore, DockTabCreateSpecific, TabKind } from "./dock.store";
export interface TemplatesGroup {
label: string;
templates: {
[filepath: string]: string; // filepath is relative to templates folder
};
templates: ObservableMap<string/*filepath*/, string>;
}
export class CreateResourceStore extends DockTabStore<string> {
@ -42,16 +40,16 @@ export class CreateResourceStore extends DockTabStore<string> {
makeObservable(this);
}
readonly templateGroups: Record<string, TemplatesGroup> = observable({
readonly templateGroups: Record<string, TemplatesGroup> = {
[this.appTemplatesFolder]: {
label: "Lens Templates",
templates: {},
templates: observable.map(),
},
[this.userTemplatesFolder]: {
label: "Custom templates",
templates: {},
templates: observable.map(),
},
});
};
get appTemplatesFolder(): string {
// production: declare files to copy in "package.json" -> "build.extraResources"
@ -80,9 +78,7 @@ export class CreateResourceStore extends DockTabStore<string> {
await fs.ensureDir(sourceFolder);
const files = await promisify(glob)("**/*.@(yaml|yml|json)", { cwd: sourceFolder });
templatesGroup.templates = Object.fromEntries(
files.map(filePath => [filePath, "" /* empty: content not loaded yet */])
);
templatesGroup.templates.replace(files.map(filePath => [filePath, "" /*content*/]));
} catch (error) {
logger.error(`[CREATE-RESOURCE]: scanning template folders error: ${error}`);
}
@ -98,9 +94,11 @@ export class CreateResourceStore extends DockTabStore<string> {
return ""; // unknown group, exit
}
const template = templatesGroup.templates[filePath];
const template = templatesGroup.templates.get(filePath);
if (template) return template; // return cache, preloaded already
if (template) {
return template; // return cache, preloaded already
}
try {
const templatePath = path.resolve(sourceFolder, filePath);
@ -110,7 +108,7 @@ export class CreateResourceStore extends DockTabStore<string> {
const textContent = await fs.readFile(templatePath, { encoding: "utf-8" });
templatesGroup.templates[filePath] = textContent; // save cache
templatesGroup.templates.set(filePath, textContent); // save cache
return textContent;
} catch (error) {

View File

@ -41,7 +41,6 @@ type SelectOptionTemplate = SelectOption<SelectOptionTemplateValue>;
interface SelectOptionTemplateValue {
sourceFolder: string;
filePath: string; // relative to `sourceFolder`
content?: string; // available after loading (template selection)
}
@observer
@ -115,11 +114,10 @@ export class CreateResource extends React.Component<Props> {
return Object.entries(createResourceStore.templateGroups).map(([sourceFolder, group]) => {
return {
label: group.label,
options: Object.entries(group.templates).map(([filePath, content]) => {
options: Array.from(group.templates.keys()).map(filePath => {
return {
label: filePath,
value: { filePath, sourceFolder },
content,
};
}),
};
@ -127,8 +125,8 @@ export class CreateResource extends React.Component<Props> {
}
onSelectTemplate = async ({ value }: SelectOptionTemplate) => {
const { filePath, sourceFolder, content } = value;
const templateContent = content ?? await createResourceStore.loadTemplate({ filePath, sourceFolder });
const { filePath, sourceFolder } = value;
const templateContent = await createResourceStore.loadTemplate({ filePath, sourceFolder });
createResourceStore.setData(this.tabId, templateContent); // update draft
};

View File

@ -89,8 +89,8 @@ export interface DockStorageState {
}
export interface DockTabChangeEvent {
tabId?: TabId;
tab?: DockTab;
tab: DockTab;
tabId: TabId;
prevTab?: DockTab;
}
@ -212,11 +212,11 @@ export class DockStore implements DockStorageState {
});
}
onTabChange(callback?: (evt: DockTabChangeEvent) => void, options: DockTabChangeEventOptions = {}) {
onTabChange(callback: (evt: DockTabChangeEvent) => void, options: DockTabChangeEventOptions = {}) {
const { tabKind, dockIsVisible = true, ...reactionOpts } = options;
return reaction(() => this.selectedTab, ((tab, prevTab) => {
if (!tab) return; // skip
if (!tab) return; // skip when dock is empty
if (tabKind && tabKind !== tab.kind) return; // handle specific tab.kind only
if (dockIsVisible && !this.isOpen) return;

View File

@ -26,7 +26,7 @@ import { observer } from "mobx-react";
import { editor, Uri } from "monaco-editor";
import { MonacoTheme, registerCustomThemes } from "./monaco-themes";
import { MonacoValidator, monacoValidators } from "./monaco-validators";
import { cssNames, disposer, toJS } from "../../utils";
import { cssNames, disposer, noop, toJS } from "../../utils";
import { UserStore } from "../../../common/user-store";
import { ThemeStore } from "../../theme.store";
import debounce from "lodash/debounce";
@ -71,6 +71,10 @@ export class MonacoEditor extends React.Component<MonacoEditorProps> {
public staticId = `editor-id#${Math.round(1e7 * Math.random())}`;
public dispose = disposer();
// TODO: investigate why replacing console.* to common/logger.* calls leads for stucking UI / infinite loop..
// e.g. happens on tab change/create, maybe some other cases too.
logger = { info: noop, error: noop } as Console;
@observable.ref containerElem: HTMLElement;
@observable.ref editor: editor.IStandaloneCodeEditor;
@observable dimensions: { width?: number, height?: number } = {};
@ -121,10 +125,8 @@ export class MonacoEditor extends React.Component<MonacoEditorProps> {
return () => resizeObserver.unobserve(containerElem);
}
// TODO: investigate why replacing console.* to common logger.* calls in a file leads for stucking UI / infinite loop.
// e.g. happens on tab change/create, maybe some other cases
onModelChange = (model: editor.ITextModel, oldModel?: editor.ITextModel) => {
console.info("[MONACO]: model change", { model, oldModel });
this.logger.info("[MONACO]: model change", { model, oldModel });
this.saveViewState(oldModel);
this.editor.setModel(model);
@ -157,9 +159,9 @@ export class MonacoEditor extends React.Component<MonacoEditorProps> {
componentDidMount() {
try {
this.createEditor();
console.info(`[MONACO]: editor did mount`);
this.logger.info(`[MONACO]: editor did mount`);
} catch (error) {
console.error(`[MONACO]: mounting failed: ${error}`, this);
this.logger.error(`[MONACO]: mounting failed: ${error}`, this);
}
}
@ -185,7 +187,7 @@ export class MonacoEditor extends React.Component<MonacoEditorProps> {
...this.options,
});
console.info(`[MONACO]: editor created for language=${language}, theme=${theme}`);
this.logger.info(`[MONACO]: editor created for language=${language}, theme=${theme}`);
this.validateLazy(); // validate initial value
this.restoreViewState(); // restore previous state if any
@ -231,7 +233,6 @@ export class MonacoEditor extends React.Component<MonacoEditorProps> {
@action
setDimensions(width: number, height: number) {
console.info(`[MONACO]: refreshing dimensions to width=${width} and height=${height}`);
this.dimensions.width = width;
this.dimensions.height = height;
this.editor?.layout({ width, height });

View File

@ -31,7 +31,7 @@ export interface MonacoThemeData extends editor.IStandaloneThemeData {
}
// Registered names could be then used in "themes/*.json" in "{monacoTheme: [name]}"
export const customThemes: Partial<Record<MonacoTheme, MonacoThemeData>> = {
export const customThemes: Partial<Record<MonacoCustomTheme, MonacoThemeData>> = {
"clouds-midnight": cloudsMidnight as MonacoThemeData,
};

View File

@ -23,15 +23,14 @@ import { computed, makeObservable, observable, reaction } from "mobx";
import { autoBind, Singleton } from "./utils";
import { UserStore } from "../common/user-store";
import logger from "../main/logger";
import lensDarkTheme from "./themes/lens-dark.json";
import lensLightTheme from "./themes/lens-light.json";
import lensDarkThemeJson from "./themes/lens-dark.json";
import lensLightThemeJson from "./themes/lens-light.json";
import type { SelectOption } from "./components/select";
import type { MonacoEditorProps } from "./components/monaco-editor";
export type ThemeId = string;
export interface Theme {
id?: ThemeId;
name: string;
type: "dark" | "light";
colors: Record<string, string>;
@ -45,34 +44,23 @@ export class ThemeStore extends Singleton {
protected styles: HTMLStyleElement;
// bundled themes from `themes/${themeId}.json`
private allThemes = observable.map<string, Theme>({
"lens-dark": lensDarkTheme as Theme,
"lens-light": lensLightTheme as Theme,
private themes = observable.map<ThemeId, Theme>({
"lens-dark": lensDarkThemeJson as Theme,
"lens-light": lensLightThemeJson as Theme,
});
@computed get themes() {
return Array.from(this.allThemes.entries()).map(([themeId, themeOriginal]) => {
const theme: Required<Theme> = {
id: themeId, // take id from map's key
...themeOriginal,
};
return theme;
});
}
@computed get activeThemeId(): string {
return UserStore.getInstance().colorTheme;
}
@computed get activeTheme(): Theme {
return this.allThemes.get(this.activeThemeId) ?? this.allThemes.get(ThemeStore.defaultTheme);
return this.themes.get(this.activeThemeId) ?? this.themes.get(ThemeStore.defaultTheme);
}
@computed get themeOptions(): SelectOption<string>[] {
return this.themes.map(theme => ({
return Array.from(this.themes).map(([themeId, theme]) => ({
label: theme.name,
value: theme.id,
value: themeId,
}));
}
@ -96,7 +84,7 @@ export class ThemeStore extends Singleton {
}
getThemeById(themeId: ThemeId): Theme {
return this.allThemes.get(themeId);
return this.themes.get(themeId);
}
protected applyTheme(theme: Theme) {