Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions client/src/components/modal/EditDetailsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { FlatConfigOption } from "../steps/Configs/SlideOut";
import OptionSelect from "../steps/Configs/OptionSelect";
import { useDebouncedCallback } from "use-debounce";
import { removeEmpty } from "../../utils/utils";
import { SystemTypeInterface, TemplateInterface } from "../../data/template";
import {
applyValueModifiers,
applyVisibilityModifiers,
Expand Down Expand Up @@ -243,18 +242,7 @@ const EditDetailsModal = observer(
// This removes all configs when saving project details.
// The reason for this is we don't want the user to use saved configs with
// changed project details as it will cause issues with evaluated values.
templateStore.systemTypes.forEach((systemType: SystemTypeInterface) => {
const templates = templateStore.getTemplatesForSystem(
systemType.modelicaPath,
);

templates.forEach((option: TemplateInterface) => {
configStore.removeAllForSystemTemplate(
systemType.modelicaPath,
option.modelicaPath,
);
});
});
configStore.removeAllForProject(projectStore.activeProjectId);
if (afterSubmit) afterSubmit();
}

Expand Down
91 changes: 68 additions & 23 deletions client/src/data/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface SelectionInterface {

export interface ConfigInterface {
id: string;
projectId: string;
name?: string;
isLocked: boolean;
selections?: ConfigValues;
Expand All @@ -22,28 +23,34 @@ export interface ConfigInterface {
[key: string]: string | number | undefined | boolean | ConfigValues;
}

export type ConfigProps = Omit<ConfigInterface, "id">;
export type ConfigProps = Omit<ConfigInterface, "id" | "projectId">;

export default class Config {
configs: ConfigInterface[] = [];
rootStore: RootStore;
/** Resolves once the store is loaded from local storage */
hydrated: Promise<unknown> = Promise.resolve();

constructor(rootStore: RootStore) {
this.rootStore = rootStore;

makeAutoObservable(this);
makeAutoObservable(this, { hydrated: false });

if (process.env.NODE_ENV !== "test") {
makePersistable(this, {
this.hydrated = makePersistable(this, {
name: this.rootStore.getStorageKey("config"),
properties: ["configs"],
});
}
}

/**
* Adds a configuration to the active project
*/
add(config: ConfigProps) {
const merged = {
id: uuid(),
projectId: this.activeProjectId,
name: "Default",
isLocked: false,
selections: {},
Expand Down Expand Up @@ -75,13 +82,15 @@ export default class Config {
if (config) config.isLocked = !config.isLocked;
}

hasSystemTemplateConfigs(systemPath: string, templatePath: string): boolean {
return this.configs.find(
(config) =>
config.systemPath == systemPath && config.templatePath === templatePath,
)
? true
: false;
hasSystemTemplateConfigs(
systemPath: string,
templatePath: string,
projectId = this.activeProjectId,
): boolean {
return (
this.getConfigsForSystemTemplate(systemPath, templatePath, projectId)
.length > 0
);
}

// Look in the config for the value of the first option that matches a given modelicaPath
Expand Down Expand Up @@ -122,29 +131,65 @@ export default class Config {
getConfigsForSystemTemplate(
systemPath: string | null,
templatePath: string | null,
projectId = this.activeProjectId,
): ConfigInterface[] {
return this.configs.filter(
(config) =>
config.projectId === projectId &&
config.systemPath === systemPath &&
config.templatePath === templatePath,
);
}

getConfigsForProject(
//TODO: need to connect project to configs
//projectId: string,
): ConfigInterface[] {
return toJS(this.configs);
/*return this.configs.filter(
(config) => config.projectId === projectId
);*/
getConfigsForProject(projectId = this.activeProjectId): ConfigInterface[] {
return toJS(
this.configs.filter((config) => config.projectId === projectId),
);
}

removeAllForSystemTemplate(
systemPath: string,
templatePath: string,
projectId = this.activeProjectId,
) {
this.configs = this.configs.filter(
(config) =>
!(
config.projectId === projectId &&
config.systemPath === systemPath &&
config.templatePath === templatePath
),
);
}

removeAllForProject(projectId: string) {
this.configs = this.configs.filter(
(config) => config.projectId !== projectId,
);
}

removeAllForSystemTemplate(systemPath: string, templatePath: string) {
this.configs = this.configs.filter((config) =>
config.systemPath === systemPath && config.templatePath === templatePath
? false
: true,
/**
* Attaches the configurations that belong to no existing project (stored
* before configurations were linked to projects, or whose project was not
* saved) to the project, if there is exactly one. Otherwise, reports them:
* configurations are never dropped.
*/
attachOrphans(projectIds: string[]) {
const orphans = this.configs.filter(
(config) => !projectIds.includes(config.projectId),
);
if (orphans.length === 0) return;
if (projectIds.length === 1) {
orphans.forEach((config) => (config.projectId = projectIds[0]));
} else {
console.error(
`${orphans.length} configuration(s) belong to no project`,
orphans.map((config) => config.id),
);
}
}

private get activeProjectId(): string {
return this.rootStore.projectStore.activeProjectId;
}
}
7 changes: 7 additions & 0 deletions client/src/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ class RootStore {
this.templateStore = new TemplateStore(this);
this.projectStore = new ProjectStore(this);
this.configStore = new ConfigStore(this);

Promise.all([this.projectStore.hydrated, this.configStore.hydrated]).then(
() =>
this.configStore.attachOrphans(
this.projectStore.projects.map((project) => project.id),
),
);
}

getStorageKey(suffix = ""): string {
Expand Down
26 changes: 17 additions & 9 deletions client/src/data/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface ProjectInterface {
projectDetails: ProjectDetailInterface;
}

const DEFAULT_PROJECT = {
const createDefaultProject = (): ProjectInterface => ({
id: uuid(),
projectDetails: {
name: "",
Expand All @@ -30,24 +30,32 @@ const DEFAULT_PROJECT = {
selections: {},
evaluatedValues: {},
},
};
});

export default class Project {
projects = [DEFAULT_PROJECT];
activeProjectId = DEFAULT_PROJECT.id;
projects = [createDefaultProject()];
activeProjectId = this.projects[0].id;
/** Resolves once the store is loaded from local storage */
hydrated: Promise<unknown> = Promise.resolve();

rootStore;

constructor(rootStore: RootStore) {
this.rootStore = rootStore;

makeAutoObservable(this);
makeAutoObservable(this, { hydrated: false });

if (process.env.NODE_ENV !== "test") {
makePersistable(this, {
name: this.rootStore.getStorageKey("projects"),
properties: ["projects", "activeProjectId"],
});
this.hydrated = makePersistable(
this,
{
name: this.rootStore.getStorageKey("projects"),
properties: ["projects", "activeProjectId"],
},
// Save the default project once hydrated: its id, generated at page
// load, must not change on reload as configurations refer to it
{ fireImmediately: true },
);
}
}

Expand Down
5 changes: 3 additions & 2 deletions client/src/interpreter/display-option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
OptionInstance,
constructSelectionPath,
} from "./interpreter";
import { enclosingName, lastIdent } from "../utils/names";

export interface FlatConfigOptionGroup {
groupName: string;
Expand Down Expand Up @@ -116,7 +117,7 @@ export function _formatDisplayGroup(
// class) to the first (the class itself).
const treeList = option.treeList ?? [];
const declaringClassRank = (path: string) =>
treeList.indexOf(path.split(".").slice(0, -1).join("."));
treeList.indexOf(enclosingName(path));
const orderedOptions = [...(option.options ?? [])].sort(
(a, b) => declaringClassRank(b) - declaringClassRank(a),
);
Expand Down Expand Up @@ -184,7 +185,7 @@ export function _formatDisplayGroup(
);
childItems = childGroup ? [childGroup] : [];
} else {
const paramName = o.split(".").pop();
const paramName = lastIdent(o);
const childInstancePath = [paramInstance.instancePath, paramName]
.filter((p) => p !== "")
.join(".");
Expand Down
Loading