Skip to content

Commit

Permalink
refactor WorkflowCard
Browse files Browse the repository at this point in the history
add types
fix type errors
remove redundant code
remove any
unify naming
  • Loading branch information
ElectronicBlueberry committed Sep 2, 2024
1 parent 5065668 commit af522d0
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 32 deletions.
19 changes: 9 additions & 10 deletions client/src/components/Common/DelayedInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import { faAngleDoubleDown, faAngleDoubleUp, faSpinner, faTimes } from "@fortawe
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { watchImmediate } from "@vueuse/core";
import { BButton, BFormInput, BInputGroup, BInputGroupAppend } from "bootstrap-vue";
import { computed, ref } from "vue";
import { ref, watch } from "vue";
import localize from "@/utils/localization";
library.add(faAngleDoubleDown, faAngleDoubleUp, faSpinner, faTimes);
interface Props {
modelValue?: string;
value?: string;
delay?: number;
loading?: boolean;
Expand All @@ -21,7 +20,6 @@ interface Props {
}
const props = withDefaults(defineProps<Props>(), {
modelValue: "",
value: "",
delay: 1000,
loading: false,
Expand All @@ -30,10 +28,8 @@ const props = withDefaults(defineProps<Props>(), {
enableAdvanced: false,
});
const currentValue = computed(() => props.modelValue ?? props.value ?? "");
const emit = defineEmits<{
(e: "update:modelValue", value: string): void;
(e: "input", value: string): void;
(e: "change", value: string): void;
(e: "onToggle", showAdvanced: boolean): void;
}>();
Expand Down Expand Up @@ -62,12 +58,16 @@ function delayQuery(query: string) {
}
function setQuery(queryNew: string) {
emit("update:modelValue", queryNew);
emit("input", queryNew);
emit("change", queryNew);
}
watch(
() => queryInput.value,
() => delayQuery(queryInput.value ?? "")
);
function clearBox() {
setQuery("");
queryInput.value = "";
toolInput.value?.focus();
}
Expand All @@ -77,7 +77,7 @@ function onToggle() {
}
watchImmediate(
() => currentValue.value,
() => props.value,
(newQuery) => {
queryInput.value = newQuery;
}
Expand All @@ -94,7 +94,6 @@ watchImmediate(
autocomplete="off"
:placeholder="placeholder"
data-description="filter text input"
@input="delayQuery"
@keydown.esc="clearBox" />

<BInputGroupAppend>
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Common/FilterMenu.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getLocalVue } from "@tests/jest/helpers";
import { mount, type Wrapper } from "@vue/test-utils";

import { HistoryFilters } from "@/components/History/HistoryFilters";
import { WorkflowFilters } from "@/components/Workflow/List/WorkflowFilters";
import { WorkflowFilters } from "@/components/Workflow/List/workflowFilters";
import Filtering, { compare, contains, equals, toBool, toDate } from "@/utils/filtering";

import FilterMenu from "./FilterMenu.vue";
Expand Down
21 changes: 13 additions & 8 deletions client/src/components/Workflow/List/WorkflowCard.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faEdit, faEye, faPen, faUpload } from "@fortawesome/free-solid-svg-icons";
import { faEdit, faPen, faUpload } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BButton, BLink } from "bootstrap-vue";
import { storeToRefs } from "pinia";
Expand All @@ -21,23 +20,25 @@ import WorkflowPublished from "@/components/Workflow/Published/WorkflowPublished
import WorkflowInvocationsCount from "@/components/Workflow/WorkflowInvocationsCount.vue";
import WorkflowRunButton from "@/components/Workflow/WorkflowRunButton.vue";
library.add(faEdit, faEye, faPen, faUpload);
interface Props {
workflow: any;
gridView?: boolean;
hideRuns?: boolean;
filterable?: boolean;
publishedView?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
gridView: false,
publishedView: false,
hideRuns: false,
filterable: true,
});
const emit = defineEmits<{
(e: "tagClick", tag: string): void;
(e: "refreshList", overlayLoading?: boolean, b?: boolean): void;
(e: "update-filter", key: string, value: any): void;
(e: "updateFilter", key: string, value: any): void;
}>();
const userStore = useUserStore();
Expand Down Expand Up @@ -95,7 +96,7 @@ async function onImport() {
Toast.success("Workflow imported successfully");
}
function onRenameClose(e: any) {
function onRenameClose() {
showRename.value = false;
emit("refreshList", true);
}
Expand Down Expand Up @@ -126,10 +127,14 @@ async function onTagClick(tag: string) {
<WorkflowIndicators
:workflow="workflow"
:published-view="publishedView"
@update-filter="(k, v) => emit('update-filter', k, v)" />
:filterable="props.filterable"
@update-filter="(k, v) => emit('updateFilter', k, v)" />

<div class="workflow-count-actions">
<WorkflowInvocationsCount v-if="!isAnonymous && !shared" class="mx-1" :workflow="workflow" />
<WorkflowInvocationsCount
v-if="!props.hideRuns && !isAnonymous && !shared"
class="mx-1"
:workflow="workflow" />

<WorkflowActions
:workflow="workflow"
Expand Down
14 changes: 10 additions & 4 deletions client/src/components/Workflow/List/WorkflowIndicators.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ library.add(faFileImport, faGlobe, faShieldAlt, faUsers, faUser);
interface Props {
workflow: any;
publishedView: boolean;
filterable?: boolean;
}
const props = defineProps<Props>();
Expand All @@ -29,10 +30,15 @@ const router = useRouter();
const userStore = useUserStore();
const publishedTitle = computed(() => {
if (userStore.matchesCurrentUsername(props.workflow.owner)) {
return "Published by you. Click to view all published workflows by you";
if (props.workflow.published && !props.publishedView) {
return "Published workflow" + (props.filterable ? ". Click to filter published workflows" : "");
} else if (userStore.matchesCurrentUsername(props.workflow.owner)) {
return "Published by you" + (props.filterable ? ". Click to view all published workflows by you" : "");
} else {
return `Published by '${props.workflow.owner}'. Click to view all published workflows by '${props.workflow.owner}'`;
return (
`Published by '${props.workflow.owner}'` +
(props.filterable ? `. Click to view all published workflows by '${props.workflow.owner}'` : "")
);
}
});
Expand Down Expand Up @@ -88,7 +94,7 @@ function onViewUserPublished() {
v-b-tooltip.noninteractive.hover
size="sm"
class="workflow-published-icon inline-icon-button"
title="Published workflow. Click to filter published workflows"
:title="publishedTitle"
@click="emit('update-filter', 'published', true)">
<FontAwesomeIcon :icon="faGlobe" fixed-width />
</BButton>
Expand Down
6 changes: 3 additions & 3 deletions client/src/components/Workflow/List/WorkflowList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { computed, onMounted, ref, watch } from "vue";
import { useRouter } from "vue-router/composables";
import { GalaxyApi } from "@/api";
import { helpHtml, WorkflowFilters } from "@/components/Workflow/List/WorkflowFilters";
import { getWorkflowFilters, helpHtml } from "@/components/Workflow/List/workflowFilters";
import { Toast } from "@/composables/toast";
import { useUserStore } from "@/stores/userStore";
import { rethrowSimple } from "@/utils/simple-error";
Expand Down Expand Up @@ -77,7 +77,7 @@ const bookmarkButtonTitle = computed(() =>
);
// Filtering computed refs
const workflowFilters = computed(() => WorkflowFilters(props.activeList));
const workflowFilters = computed(() => getWorkflowFilters(props.activeList));
const rawFilters = computed(() =>
Object.fromEntries(workflowFilters.value.getFiltersForText(filterText.value, true, false))
);
Expand Down Expand Up @@ -333,7 +333,7 @@ onMounted(() => {
:class="view === 'grid' ? 'grid-view' : 'list-view'"
@refreshList="load"
@tagClick="(tag) => updateFilterValue('tag', `'${tag}'`)"
@update-filter="updateFilterValue" />
@updateFilter="updateFilterValue" />

<BPagination
v-if="!loading && totalWorkflows > limit"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Filtering, { contains, equals, expandNameTag, toBool } from "utils/filtering";
import Filtering, { contains, equals, expandNameTag, toBool } from "@/utils/filtering";

export function helpHtml(activeList = "my") {
let extra = "";
Expand Down Expand Up @@ -71,7 +71,7 @@ export function helpHtml(activeList = "my") {
return conditionalHelpHtml;
}

export function WorkflowFilters(activeList = "my") {
export function getWorkflowFilters(activeList = "my") {
const commonFilters = {
name: { placeholder: "name", type: String, handler: contains("name"), menuItem: true },
n: { handler: contains("n"), menuItem: false },
Expand All @@ -82,7 +82,7 @@ export function WorkflowFilters(activeList = "my") {
menuItem: true,
},
t: { type: "MultiTags", handler: contains("t", "t", expandNameTag), menuItem: false },
};
} as const;

if (activeList === "my") {
return new Filtering(
Expand Down
34 changes: 33 additions & 1 deletion client/src/components/Workflow/workflows.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,39 @@ import axios from "axios";
import { useUserStore } from "@/stores/userStore";
import { withPrefix } from "@/utils/redirect";

type Workflow = Record<string, never>;
export type Workflow = Record<string, never>;

interface LoadWorkflowsOptions {
sortBy: SortBy;
sortDesc: boolean;
limit: number;
offset: number;
filterText: string;
showPublished: boolean;
skipStepCounts: boolean;
}

const getWorkflows = fetcher.path("/api/workflows").method("get").create();
export async function loadWorkflows({
sortBy = "update_time",
sortDesc = true,
limit = 20,
offset = 0,
filterText = "",
showPublished = false,
skipStepCounts = true,
}: LoadWorkflowsOptions): Promise<{ data: Workflow[]; headers: Headers }> {
const { data, headers } = await getWorkflows({
sort_by: sortBy,
sort_desc: sortDesc,
limit,
offset,
search: filterText,
show_published: showPublished,
skip_step_counts: skipStepCounts,
});
return { data, headers };
}

export async function updateWorkflow(id: string, changes: object): Promise<Workflow> {
const { data } = await axios.put(withPrefix(`/api/workflows/${id}`), changes);
Expand Down
7 changes: 5 additions & 2 deletions client/src/utils/filtering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,13 +525,16 @@ export default class Filtering<T> {
if (this.validFilters[key]?.type === "MultiTags" && Array.isArray(value)) {
const validValues = value
.map((v) => this.getConvertedValue(key, v, backendFormatted))
.filter((v) => v !== undefined);
.filter((v) => v !== undefined) as T[];

if (validValues.length > 0) {
validFilters[key] = validValues as T;
}

const invalidValues = value.filter(
(v) => !validValues.includes(this.getConvertedValue(key, v, backendFormatted))
(v) => !validValues.includes(this.getConvertedValue(key, v, backendFormatted) as T)
);

if (invalidValues.length > 0) {
invalidFilters[key] = invalidValues as T;
}
Expand Down

0 comments on commit af522d0

Please sign in to comment.