Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

task: add resource filtering and new asset buttons #1583

Merged
merged 12 commits into from
Jul 26, 2023
blanchco marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -160,30 +160,6 @@ export const convertToIGraph = (amr: Model) => {
const DUMMY_VALUE = -999;
export const convertToAMRModel = (g: IGraph<NodeData, EdgeData>) => g.amr;

export const newAMR = (modelName: string) => {
const amr: Model = {
id: '',
name: modelName,
description: '',
schema:
'https://raw.githubusercontent.com/DARPA-ASKEM/Model-Representations/petrinet_v0.5/petrinet/petrinet_schema.json',
schema_name: 'petrinet',
model_version: '0.1',
model: {
states: [],
transitions: []
},
semantics: {
ode: {
rates: [],
initials: [],
parameters: []
}
}
};
return amr;
};

export const addState = (amr: Model, id: string, name: string) => {
if (amr.model.states.find((s) => s.id === id)) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<template>
<Teleport to="body">
<tera-modal v-if="isVisible" class="modal" @modal-mask-clicked="emit('close-modal')">
<template #header>
<h4>New model</h4>
</template>
<template #default>
<form>
<label for="new-model">Enter a unique name for your model</label>
<InputText
v-bind:class="invalidInputStyle"
id="new-model"
type="text"
v-model="newModelName"
placeholder="new model"
/>
</form>
</template>
<template #footer>
<Button @click="createNewModel">Create model</Button>
<Button class="p-button-secondary" @click="emit('close-modal')"> Cancel </Button>
</template>
</tera-modal>
</Teleport>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import TeraModal from '@/components/widgets/tera-modal.vue';
import Button from 'primevue/button';
import InputText from 'primevue/inputtext';
import { IProject } from '@/types/Project';
import { logger } from '@/utils/logger';
import { addNewModelToProject } from '@/services/model';

const props = defineProps<{
project: IProject;
isVisible: boolean;
}>();
const emit = defineEmits(['close-modal']);

// New Model Modal
const newModelName = ref<string>('');
const isValidName = ref<boolean>(true);
const invalidInputStyle = computed(() => (!isValidName.value ? 'p-invalid' : ''));

const existingModelNames = computed(() => {
const modelNames: string[] = [];
props.project.assets?.models.forEach((item) => {
modelNames.push(item.name);
});
return modelNames;
});

async function createNewModel() {
if (newModelName.value.trim().length === 0) {
isValidName.value = false;
logger.info('Model name cannot be empty - please enter a different name');
return;
}
if (existingModelNames.value.includes(newModelName.value.trim())) {
isValidName.value = false;
logger.info('Duplicate model name - please enter a different name');
return;
}
isValidName.value = true;
await addNewModelToProject(newModelName.value.trim(), props.project);
emit('close-modal');
}
</script>

<style></style>
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@
size="large"
icon="pi pi-share-alt"
class="p-button p-button-secondary quick-link-button"
@click="isNewModelModalVisible = true"
@click="emit('open-new-asset', ProjectAssetTypes.MODELS)"
/>
<Button
size="large"
class="p-button p-button-secondary quick-link-button"
@click="emit('open-workflow')"
@click="emit('open-new-asset', ProjectAssetTypes.SIMULATION_WORKFLOW)"
>
<vue-feather
class="p-button-icon-left"
Expand Down Expand Up @@ -244,37 +244,6 @@
</tera-modal>
</section>
</section>

<!-- New model modal -->
<Teleport to="body">
<tera-modal
v-if="isNewModelModalVisible"
class="modal"
@modal-mask-clicked="isNewModelModalVisible = false"
>
<template #header>
<h4>New model</h4>
</template>
<template #default>
<form>
<label for="new-model">Enter a unique name for your model</label>
<InputText
v-bind:class="invalidInputStyle"
id="new-model"
type="text"
v-model="newModelName"
placeholder="new model"
/>
</form>
</template>
<template #footer>
<Button @click="createNewModel">Create model</Button>
<Button class="p-button-secondary" @click="isNewModelModalVisible = false">
Cancel
</Button>
</template>
</tera-modal>
</Teleport>
</main>
</template>

Expand Down Expand Up @@ -306,7 +275,7 @@ import { uploadArtifactToProject } from '@/services/artifact';
const props = defineProps<{
project: IProject;
}>();
const emit = defineEmits(['open-workflow', 'open-asset', 'new-model']);
const emit = defineEmits(['open-asset', 'open-new-asset']);
const router = useRouter();
const isRenamingProject = ref(false);
const inputElement = ref<HTMLInputElement | null>(null);
Expand All @@ -319,20 +288,6 @@ const selectedResources = ref();
const openedRow = ref(null);
const isNewModelModalVisible = ref<boolean>(false);
const newModelName = ref<string>('');
const isValidName = ref<boolean>(true);
const invalidInputStyle = computed(() => (!isValidName.value ? 'p-invalid' : ''));
const existingModelNames = computed(() => {
const modelNames: string[] = [];
props.project.assets?.models.forEach((item) => {
modelNames.push(item.name);
});
return modelNames;
});
const assets = computed(() => {
const tabs = new Map<ProjectAssetTypes, Set<Tab>>();
Expand Down Expand Up @@ -389,22 +344,6 @@ async function processFiles(files: File[], csvDescription: string) {
});
}
function createNewModel() {
if (newModelName.value.trim().length === 0) {
isValidName.value = false;
logger.info('Model name cannot be empty - please enter a different name');
return;
}
if (existingModelNames.value.includes(newModelName.value.trim())) {
isValidName.value = false;
logger.info('Duplicate model name - please enter a different name');
return;
}
isValidName.value = true;
emit('new-model', newModelName.value.trim());
isNewModelModalVisible.value = false;
}
async function openImportModal() {
isUploadResourcesModalVisible.value = true;
results.value = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
v-else-if="pageType === ProjectPages.OVERVIEW"
:project="project"
@vue:mounted="emit('asset-loaded')"
@open-workflow="openWorkflow"
@new-model="newModel"
@open-new-asset="(assetType) => emit('open-new-asset', assetType)"
/>
<tera-simulation-workflow
v-else-if="pageType === ProjectAssetTypes.SIMULATION_WORKFLOW"
Expand Down Expand Up @@ -78,11 +77,8 @@ import TeraModel from '@/components/models/tera-model.vue';
import CodeEditor from '@/page/project/components/code-editor.vue';
import TeraProjectOverview from '@/page/project/components/tera-project-overview.vue';
import TeraSimulationWorkflow from '@/components/workflow/tera-simulation-workflow.vue';
import { emptyWorkflow, createWorkflow } from '@/services/workflow';
import * as ProjectService from '@/services/project';
import { getArtifactArrayBuffer, getArtifactFileAsText } from '@/services/artifact';
import { newAMR } from '@/model-representation/petrinet/petrinet-service';
import { createModel } from '@/services/model';
import TeraPdfEmbed from '@/components/widgets/tera-pdf-embed.vue';

const props = defineProps<{
Expand All @@ -94,7 +90,13 @@ const props = defineProps<{
activeTabIndex?: number;
}>();

const emit = defineEmits(['update:tabs', 'asset-loaded', 'update-tab-name', 'close-current-tab']);
const emit = defineEmits([
'update:tabs',
'asset-loaded',
'update-tab-name',
'close-current-tab',
'open-new-asset'
]);

const router = useRouter();

Expand All @@ -106,57 +108,6 @@ const queuedCodeRequests: Ref<CodeRequest[]> = ref([]);
const getXDDuri = (assetId: Tab['assetId']): string =>
ProjectService.getDocumentAssetXddUri(props?.project, assetId) ?? '';

// These 3 open functions can potentially make use of openAssetFromSidebar in tera-project.vue
const openWorkflow = async () => {
// Create a new workflow
let wfName = 'workflow';
if (props.project && props.project.assets) {
wfName = `workflow ${props.project.assets[ProjectAssetTypes.SIMULATION_WORKFLOW].length + 1}`;
}
const wf = emptyWorkflow(wfName, '');

// Add the workflow to the project
const response = await createWorkflow(wf);
const workflowId = response.id;
await ProjectService.addAsset(
props.project.id,
ProjectAssetTypes.SIMULATION_WORKFLOW,
workflowId
);

router.push({
name: RouteName.ProjectRoute,
params: {
assetName: 'Workflow',
pageType: ProjectAssetTypes.SIMULATION_WORKFLOW,
assetId: workflowId
}
});
};

const newModel = async (modelName: string) => {
// 1. Load an empty AMR
const amr = newAMR(modelName);
(amr as any).id = undefined; // FIXME: id hack

const response = await createModel(amr);
const modelId = response?.id;

// 2. Add the model to the project
if (modelId) {
await ProjectService.addAsset(props.project.id, ProjectAssetTypes.MODELS, modelId);
// 3. Reroute
router.push({
name: RouteName.ProjectRoute,
params: {
assetName: 'Model',
pageType: ProjectAssetTypes.MODELS,
assetId: modelId
}
});
}
};

const openOverview = () => {
router.push({
name: RouteName.ProjectRoute,
Expand Down
Loading