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

Remove/Fix open in a new window option #4159

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft
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
12 changes: 7 additions & 5 deletions packages/client/hmi-client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
<Toast position="top-center" group="warn" />
<Toast position="top-center" group="info" />
<Toast position="top-center" group="success" />
<header>
<header v-if="!isStandalone">
<tera-navbar :active="displayNavBar" />
</header>
<main>
<main :class="{ standalone: isStandalone }">
<router-view v-slot="{ Component }">
<component class="page" :is="Component" />
</router-view>
<ConfirmDialog class="w-4" />
</main>
<footer>
<footer v-if="!isStandalone">
<tera-footer />
</footer>
<tera-common-modal-dialogs />
Expand All @@ -31,6 +31,7 @@ import TeraFooter from '@/components/navbar/tera-footer.vue';
import { useProjects } from '@/composables/project';
import { Project } from '@/types/Types';
import ConfirmDialog from 'primevue/confirmdialog';
import { RouteName } from '@/router/routes';
import TeraCommonModalDialogs from './components/widgets/tera-common-modal-dialogs.vue';
import { useCurrentRoute } from './router/index';

Expand All @@ -39,8 +40,9 @@ const toast = useToastService();
/* Router */
const route = useRoute();
const router = useRouter();
const currentRoute = useCurrentRoute();
const displayNavBar = computed(() => currentRoute.value.name !== 'unauthorized');
const currentRoute = (useCurrentRoute().value.name ?? '').toString();
const displayNavBar = computed(() => !['unauthorized', RouteName.WorkflowNode.toString()].includes(currentRoute));
const isStandalone = computed(() => [RouteName.WorkflowNode.toString()].includes(currentRoute));

/* Project */
API.interceptors.response.use(
Expand Down
7 changes: 6 additions & 1 deletion packages/client/hmi-client/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ function getProjectIdFromUrl(): string | null {
return match ? match[1] : null;
}

function getProjectId(): string | null {
return activeProjectId.value ?? localStorage.getItem('activeProjectId') ?? getProjectIdFromUrl() ?? null;
}

const API = axios.create({
baseURL: '/api',
headers: new AxiosHeaders()
Expand All @@ -27,7 +31,8 @@ API.interceptors.request.use(
const auth = useAuthStore();
config.headers.setAuthorization(`Bearer ${auth.getToken()}`);
// ActiveProjectId is often not available when the API is called from a global context or immediately after pages are hard refreshed, so we need to check the URL for the project id
const projectId = activeProjectId.value || getProjectIdFromUrl();
const projectId = getProjectId();
console.log('projectId', projectId);
if (projectId) {
if (config.params) {
config.params['project-id'] = projectId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import TeraOperatorInputs from '@/components/operator/tera-operator-inputs.vue';
import TeraOperatorOutputs from '@/components/operator/tera-operator-outputs.vue';
import TeraOperatorAnnotation from '@/components/operator/tera-operator-annotation.vue';
import { OperatorMenuItem } from '@/services/workflow';
import { activeProjectId } from '@/composables/activeProject';

const props = defineProps<{
node: WorkflowNode<any>;
Expand Down Expand Up @@ -92,7 +93,11 @@ let resizeObserver: ResizeObserver | null = null;
function openInNewWindow() {
const url = router.resolve({
name: RouteName.WorkflowNode,
params: { nodeId: props.node.id, workflowId: props.node.workflowId }
params: {
nodeId: props.node.id,
projectId: activeProjectId.value,
workflowId: props.node.workflowId
}
}).href;
floatingWindow.open(url);
}
Expand Down Expand Up @@ -193,7 +198,6 @@ main {
}

&:deep(li:hover .port) {
background-color: var(--primary-color);
background-color: var(--surface-border);
}

Expand Down
14 changes: 12 additions & 2 deletions packages/client/hmi-client/src/composables/activeProject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { computed, shallowRef } from 'vue';
import { computed, shallowRef, watch } from 'vue';
import type { Project } from '@/types/Types';

export const activeProject = shallowRef<Project | null>(null);
export const activeProjectId = computed<string>(() => activeProject.value?.id ?? '');
export const activeProjectId = computed<string>(
() => activeProject?.value?.id ?? localStorage.getItem('activeProjectId') ?? ''
);

watch(
activeProject,
(newProject) => {
localStorage.setItem('activeProjectId', newProject?.id ?? '');
},
{ immediate: true }
);
43 changes: 27 additions & 16 deletions packages/client/hmi-client/src/page/WorkflowNode.vue
Original file line number Diff line number Diff line change
@@ -1,47 +1,58 @@
<template>
{{ activeProjectId }}
<template v-if="node">
<tera-model-workflow-wrapper v-if="isNodeType(OperationType.MODEL)" :node="node" />
<tera-stratify-mira v-else-if="isNodeType(OperationType.STRATIFY_MIRA)" :node="node" />
<tera-dataset-transformer v-else-if="isNodeType(OperationType.DATASET_TRANSFORMER)" :node="node" />
<tera-dataset-drilldown v-else-if="isNodeType(OperationType.DATASET)" :node="node" />
<tera-regridding-drilldown v-else-if="isNodeType(OperationType.REGRIDDING)" :node="node" />
<tera-calibrate-ciemss v-else-if="isNodeType(OperationType.CALIBRATION_CIEMSS)" :node="node" />
<tera-model-workflow-wrapper v-if="isNodeOfOperationType(OperationType.MODEL)" :node="node" />
<tera-stratify-mira v-else-if="isNodeOfOperationType(OperationType.STRATIFY_MIRA)" :node="node" />
<tera-dataset-transformer v-else-if="isNodeOfOperationType(OperationType.DATASET_TRANSFORMER)" :node="node" />
<tera-dataset-drilldown v-else-if="isNodeOfOperationType(OperationType.DATASET)" :node="node" />
<tera-regridding-drilldown v-else-if="isNodeOfOperationType(OperationType.REGRIDDING)" :node="node" />
<tera-calibrate-ciemss-drilldown v-else-if="isNodeOfOperationType(OperationType.CALIBRATION_CIEMSS)" :node="node" />
<tera-calibrate-ensemble-ciemss-drilldown
v-else-if="isNodeType(OperationType.CALIBRATE_ENSEMBLE_CIEMSS)"
v-else-if="isNodeOfOperationType(OperationType.CALIBRATE_ENSEMBLE_CIEMSS)"
:node="node"
/>
<tera-simulate-ciemss-drilldown v-else-if="isNodeType(OperationType.SIMULATE_CIEMSS)" :node="node" />
<tera-simulate-ciemss-drilldown v-else-if="isNodeOfOperationType(OperationType.SIMULATE_CIEMSS)" :node="node" />
<tera-simulate-ensemble-ciemss-drilldown
v-else-if="isNodeType(OperationType.SIMULATE_ENSEMBLE_CIEMSS)"
v-else-if="isNodeOfOperationType(OperationType.SIMULATE_ENSEMBLE_CIEMSS)"
:node="node"
/>
<tera-funman v-else-if="isNodeType(OperationType.FUNMAN)" :node="node" />
<tera-code-asset-wrapper v-else-if="isNodeType(OperationType.CODE)" :node="node" />
<tera-funman v-else-if="isNodeOfOperationType(OperationType.FUNMAN)" :node="node" />
<tera-code-asset-wrapper v-else-if="isNodeOfOperationType(OperationType.CODE)" :node="node" />
<template v-else>
<p>This OperationType is not know!</p>
<pre>{{ node }}</pre>
</template>
</template>
<template v-else>{{ node }}</template>
<p v-else>Loading...</p>
</template>

<script setup lang="ts">
import { Project } from '@/types/Types';
import { watch, ref } from 'vue';
import { WorkflowNode, WorkflowOperationTypes as OperationType } from '@/types/workflow';
import { Workflow, WorkflowNode, WorkflowOperationTypes as OperationType } from '@/types/workflow';
import * as workflowService from '@/services/workflow';
import TeraModelWorkflowWrapper from '@/components/workflow/ops/model/tera-model-drilldown.vue';
import TeraDatasetDrilldown from '@/components/workflow/ops/dataset/tera-dataset-drilldown.vue';
import TeraRegriddingDrilldown from '@/components/workflow/ops/regridding/tera-regridding.vue';
import TeraDatasetTransformer from '@/components/workflow/ops/dataset-transformer/tera-dataset-transformer.vue';
import TeraCalibrateCiemss from '@/components/workflow/ops/calibrate-ciemss/tera-calibrate-ciemss-drilldown.vue';
import TeraCalibrateCiemssDrilldown from '@/components/workflow/ops/calibrate-ciemss/tera-calibrate-ciemss-drilldown.vue';
import TeraCalibrateEnsembleCiemssDrilldown from '@/components/workflow/ops/calibrate-ensemble-ciemss/tera-calibrate-ensemble-ciemss-drilldown.vue';
import TeraSimulateCiemssDrilldown from '@/components/workflow/ops/simulate-ciemss/tera-simulate-ciemss-drilldown.vue';
import TeraSimulateEnsembleCiemssDrilldown from '@/components/workflow/ops/simulate-ensemble-ciemss/tera-simulate-ensemble-ciemss-drilldown.vue';
import TeraFunman from '@/components/workflow/ops/funman/tera-funman-drilldown.vue';
import TeraStratifyMira from '@/components/workflow/ops/stratify-mira/tera-stratify-mira.vue';
import TeraCodeAssetWrapper from '@/components/workflow/ops/code-asset/tera-code-asset-wrapper.vue';
import { activeProjectId } from '@/composables/activeProject';

const props = defineProps<{ nodeId: string; workflowId: string }>();
const props = defineProps<{
nodeId: WorkflowNode<any>['id'];
projectId: Project['id'];
workflowId: Workflow['id'];
}>();

const node = ref<WorkflowNode<any>>();

function isNodeType(type: string): boolean {
function isNodeOfOperationType(type: string): boolean {
return node.value?.operationType === type;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/client/hmi-client/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { RouteName } from './routes';
export enum RoutePath {
Home = '/',
Project = `/projects/:projectId/:pageType?/:assetId?`,
WorkflowNode = `/${RouteName.WorkflowNode}/:workflowId/:nodeId`,
WorkflowNode = `/${RouteName.WorkflowNode}/:projectId/:workflowId/:nodeId`,
UserAdmin = '/user-admin',
Unauthorized = '/unauthorized',

Expand Down
6 changes: 5 additions & 1 deletion packages/client/hmi-client/src/services/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,11 @@ export const saveWorkflow = async (workflow: Workflow, projectId?: string) => {
};

// Get workflow
// Note that projectId is optional as projectId is assigned by the axios API interceptor if value is available from activeProjectId. If the method is call from place where activeProjectId is not available, projectId should be passed as an argument as all endpoints requires projectId as a parameter.
// Note that projectId is optional as projectId is assigned by the axios API
// interceptor if value is available from activeProjectId.
// If the method is call from place where activeProjectId is not available,
// projectId should be passed as an argument as all endpoints requires
// projectId as a parameter.
export const getWorkflow = async (id: string, projectId?: string) => {
const response = await API.get(`/workflows/${id}`, { params: { 'project-id': projectId } });
return response?.data ?? null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public class WorkflowController {
)
public ResponseEntity<Workflow> getWorkflow(
@PathVariable("id") final UUID id,
@RequestParam(name = "project-id", required = false) final UUID projectId
@RequestParam(name = "project-id") final UUID projectId
) {
final Schema.Permission permission = projectService.checkPermissionCanRead(
currentUserService.get().getId(),
Expand Down
Loading