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 21 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d72bd4b
Update WorkflowController.java
YohannParis Jun 18, 2024
8868486
Add projectId to the url
YohannParis Jun 18, 2024
a147e91
Tidy up
YohannParis Jun 18, 2024
1d308be
Update WorkflowNode.vue
YohannParis Jun 18, 2024
336c06d
have a standalone design for self window
YohannParis Jun 19, 2024
516f551
Merge branch 'main' into yohannparis/remove-open-in-a-new-window-option
YohannParis Jun 19, 2024
d523456
Save activeProjectId in localStorage
YohannParis Jun 19, 2024
a2e31aa
Update activeProject.ts
YohannParis Jun 20, 2024
5ed2251
Merge branch 'main' into yohannparis/remove-open-in-a-new-window-option
YohannParis Jul 17, 2024
96dd3b3
testing
YohannParis Jul 17, 2024
ecf9228
chore: lint and format server codebase
github-actions[bot] Jul 17, 2024
5cf5c7e
Merge branch 'main' into yohannparis/remove-open-in-a-new-window-option
YohannParis Jul 19, 2024
1265870
clean up
YohannParis Jul 19, 2024
15ea613
Merge branch 'main' into yohannparis/remove-open-in-a-new-window-option
YohannParis Jul 23, 2024
7379af8
chore: lint and format client codebase
github-actions[bot] Jul 23, 2024
cf7ab17
Merge branch 'main' into yohannparis/remove-open-in-a-new-window-option
YohannParis Sep 25, 2024
f39e688
Merge branch 'main' into yohannparis/remove-open-in-a-new-window-option
YohannParis Sep 25, 2024
3e5fcec
Merge branch 'main' into yohannparis/remove-open-in-a-new-window-option
YohannParis Nov 5, 2024
9860858
chore: update generated types
YohannParis Nov 5, 2024
feede61
Merge branch 'main' into yohannparis/remove-open-in-a-new-window-option
YohannParis Nov 5, 2024
ca2da48
chore: update generated types
YohannParis Nov 5, 2024
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
4 changes: 2 additions & 2 deletions packages/client/hmi-client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ 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));

/* 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-drilldown.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 @@ -22,7 +22,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 @@ -715,7 +715,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