diff --git a/src/stores/resources.ts b/src/stores/resources.ts index 815e5cc68c1b634a47d261ebd96abc7ffa5d5057..ee419a29020337957bbe9e866e777e4fc1148186 100644 --- a/src/stores/resources.ts +++ b/src/stores/resources.ts @@ -17,6 +17,21 @@ import { import { useAuthStore } from "@/stores/users"; import { useNameStore } from "@/stores/names"; +function parseFileTree(parent: string, tree?: FileTree | null): string[] { + if (tree == undefined || tree.contents == undefined) { + return []; + } + let files: string[] = []; + const currentName = parent.length > 0 ? parent + tree.name + "/" : "/"; + for (const dir of tree.contents) { + files.push(currentName + dir.name); + if (dir.type === "directory") { + files = files.concat(parseFileTree(currentName, dir)); + } + } + return files; +} + export const useResourceStore = defineStore({ id: "resources", state: () => @@ -26,6 +41,7 @@ export const useResourceStore = defineStore({ reviewableResourceMapping: {}, syncRequestMapping: {}, resourceTree: {}, + resourceTreeList: {}, __syncRequestsFetched: false, }) as { resourceMapping: Record<string, ResourceOut>; @@ -33,6 +49,7 @@ export const useResourceStore = defineStore({ reviewableResourceMapping: Record<string, ResourceOut>; syncRequestMapping: Record<string, UserSynchronizationRequestOut>; resourceTree: Record<string, FileTree | null>; + resourceTreeList: Record<string, string[]>; __syncRequestsFetched: boolean; }, getters: { @@ -126,6 +143,10 @@ export const useResourceStore = defineStore({ ) .then((tree) => { this.resourceTree[resource_version_id] = tree[0]; + this.resourceTreeList[resource_version_id] = parseFileTree( + "", + tree[0], + ); return tree; }) .catch((err) => { diff --git a/src/views/workflows/CreateParameterTranslationView.vue b/src/views/workflows/CreateParameterTranslationView.vue index 05c93392a6f16f8232d92889dcd0e5795a7f6730..6c025bb454eaec78f55c3d399a1850c65d5b9c2e 100644 --- a/src/views/workflows/CreateParameterTranslationView.vue +++ b/src/views/workflows/CreateParameterTranslationView.vue @@ -9,7 +9,7 @@ import { } from "@/client/workflow"; import type { ClowmInfo } from "@/types/ClowmInfo"; import { useResourceStore } from "@/stores/resources"; -import { type FileTree, Status } from "@/client/resource"; +import { Status } from "@/client/resource"; const props = defineProps<{ versionId: string; @@ -19,12 +19,10 @@ const props = defineProps<{ const parameterState = reactive<{ extension: ParameterExtension_Input; resourceParameters: Set<string>; - resourceTreeMapped: Record<string, string[]>; formValidated: boolean; }>({ extension: {}, resourceParameters: new Set(), - resourceTreeMapped: {}, formValidated: false, }); @@ -191,33 +189,10 @@ function updateDefaultResourceVersionParam( (parameterState.extension.defaults[param] as ResourcePath_Input) .resource_id, resource_version_id, - () => { - if (resourceRepository.resourceTree[resource_version_id] != null) { - parameterState.resourceTreeMapped[resource_version_id] = - parseFileTree( - resourceRepository.resourceTree[resource_version_id], - "", - ); - } - }, ); } } -function parseFileTree(tree: FileTree | null, parent: string): string[] { - if (tree === null) { - return []; - } - const currentName = parent.length > 0 ? parent + tree.name : ""; - const files = parent.length > 0 ? [currentName] : []; - if (tree.contents) { - for (const dir of tree.contents) { - files.push(...parseFileTree(dir, currentName + "/")); - } - } - return files; -} - function isResource( param: ResourcePath_Input | string | number | boolean | undefined, ): param is ResourcePath_Input { @@ -303,18 +278,22 @@ onMounted(() => { </div> <h3>Instance specific default parameters</h3> <div - class="d-flex flex-wrap overflow-y-auto p-1 border rounded border-dashed mb-2" + class="d-flex flex-wrap overflow-y-auto p-1 border border-bottom-0 rounded-top border-dashed" style="max-height: 30vh" - v-if="parameterPools.defaults.length > 0" > <b class="ms-1 w-100">Workflow parameters:</b> - <div - class="w-fit border px-2 rounded cursor-pointer m-1 parameter-container" - v-for="(param, index) in parameterPools.defaults" - :key="param" - @click="addDefaultParameter(param, index)" - > - {{ param }} + <template v-if="parameterPools.defaults.length > 0"> + <div + class="w-fit border px-2 rounded cursor-pointer m-1 parameter-container" + v-for="(param, index) in parameterPools.defaults" + :key="param" + @click="addDefaultParameter(param, index)" + > + {{ param }} + </div> + </template> + <div v-else class="px-2 text-secondary m-1"> + <i>Empty</i> </div> </div> <form @@ -484,7 +463,7 @@ onMounted(() => { <input type="text" class="form-control rounded-end form-control-sm" - placeholder="/path/in/resource/..." + placeholder="/optional/path/in/resource/..." minlength="2" maxlength="256" pattern="\/\S*" @@ -499,13 +478,13 @@ onMounted(() => { /> <datalist :id="'datalistOptions-' + index"> <option - v-for="file in parameterState.resourceTreeMapped[ + v-for="file in resourceRepository.resourceTreeList[ ( parameterState.extension.defaults[ param ] as ResourcePath_Input ).resource_version_id - ]" + ] ?? []" :value="file" :key="file" /> @@ -552,8 +531,10 @@ onMounted(() => { <pre><code>{{ parameterState.extension }}</code></pre> - <h6>Resource Tree</h6> - <pre><code>{{ parameterState.resourceTreeMapped }}</code></pre> + <h6>Resource Tree processed</h6> + <pre><code>{{ resourceRepository.resourceTreeList }}</code></pre> + <h6>Resource Tree raw</h6> + <pre><code>{{ resourceRepository.resourceTree }}</code></pre> <h6>Parameter Pools</h6> <pre><code>{{ parameterPools }}</code></pre> <h6>Resource Parameters</h6> diff --git a/src/views/workflows/MyWorkflowsView.vue b/src/views/workflows/MyWorkflowsView.vue index 34fb0c0f219fcbc87098098d20cfe6bc410e3764..513a18d61612882987b6f3cdf133fe6522bd26be 100644 --- a/src/views/workflows/MyWorkflowsView.vue +++ b/src/views/workflows/MyWorkflowsView.vue @@ -1,5 +1,5 @@ <script setup lang="ts"> -import { onMounted, reactive } from "vue"; +import { computed, onMounted, reactive } from "vue"; import type { WorkflowOut, WorkflowVersion } from "@/client/workflow"; import { Status } from "@/client/workflow"; import WorkflowWithVersionsCard from "@/components/workflows/WorkflowWithVersionsCard.vue"; @@ -53,6 +53,12 @@ const workflowsState = reactive<{ }, }); +const sortedWorkflows = computed<WorkflowOut[]>(() => { + const temp = [...workflowRepository.ownWorkflows]; + temp.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)); + return temp; +}); + function workflowUpdateClicked(workflow: WorkflowOut) { workflowsState.updateWorkflow = workflow; } @@ -127,11 +133,11 @@ onMounted(() => { </div> <div v-if="!workflowsState.loading"> <card-transition-group - v-if="workflowRepository.ownWorkflows.length > 0" + v-if="sortedWorkflows.length > 0" class="d-flex flex-wrap align-items-center justify-content-between mt-5" > <workflow-with-versions-card - v-for="workflow in workflowRepository.ownWorkflows" + v-for="workflow in sortedWorkflows" :key="workflow.workflow_id" :workflow="workflow" :loading="false"