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

Workflow Editor Activity Bar #18729

Draft
wants to merge 41 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
da99366
generalize activity bar
ElectronicBlueberry Aug 20, 2024
8702374
add activity bar to workflow editor
ElectronicBlueberry Aug 20, 2024
4eb85da
add activities to activity bar
ElectronicBlueberry Aug 21, 2024
c91f307
add save and exit activity
ElectronicBlueberry Aug 22, 2024
f5fb362
route to workflow list on exit
ElectronicBlueberry Aug 22, 2024
c96e0a5
move best practices to activity bar
ElectronicBlueberry Aug 22, 2024
5ea0f83
use ActivityPanel component for Lint
ElectronicBlueberry Aug 23, 2024
2c4e4eb
move UndoRedoStack to activity bar
ElectronicBlueberry Aug 23, 2024
db185c8
add placeholder activities
ElectronicBlueberry Aug 23, 2024
0cf9dc9
fix delayed input
ElectronicBlueberry Aug 28, 2024
bf88e65
make favorites button reusable
ElectronicBlueberry Aug 28, 2024
d2933da
refactor WorkflowCard
ElectronicBlueberry Aug 29, 2024
14f0043
improve performance of workflow card
ElectronicBlueberry Aug 29, 2024
efef225
add workflows panel
ElectronicBlueberry Sep 5, 2024
4fdb622
fix z-indexing for dropdown
ElectronicBlueberry Sep 6, 2024
ac239d1
connect insert and insert steps events
ElectronicBlueberry Sep 6, 2024
e3d8f32
move breakpoints to partial
ElectronicBlueberry Sep 6, 2024
d3b2c59
only occupy vertical space if invocations count is present
ElectronicBlueberry Sep 9, 2024
482bb96
rename Attributes to WorkflowAttributes
ElectronicBlueberry Sep 9, 2024
9ea5dab
make attributes an activity
ElectronicBlueberry Sep 9, 2024
2ad72a7
move MarkdownEditor to activity bar
ElectronicBlueberry Sep 9, 2024
d3d7275
move all options to activity bar
ElectronicBlueberry Sep 10, 2024
93c5d5d
add save button
ElectronicBlueberry Sep 23, 2024
4b4e794
remove unused attribute and unreachable code
ElectronicBlueberry Sep 23, 2024
474f93d
enable run and save
ElectronicBlueberry Sep 23, 2024
ec7433e
fix activity text centering on chrome
ElectronicBlueberry Sep 23, 2024
4fe0d94
fix text short property collision
ElectronicBlueberry Sep 24, 2024
8d4be70
decouple node inspector from right hand panel
ElectronicBlueberry Sep 27, 2024
ebeb5fe
modularize drag handle
ElectronicBlueberry Oct 8, 2024
fb9887a
correct appearance of drag handle
ElectronicBlueberry Oct 8, 2024
236e14e
show collapse button
ElectronicBlueberry Oct 8, 2024
7a3c79a
add tool form to node inspector
ElectronicBlueberry Oct 14, 2024
3914a20
add inspector heading
ElectronicBlueberry Oct 16, 2024
071178e
allow for saving default sizes for tools / steps
ElectronicBlueberry Oct 17, 2024
4e045c8
make double click maximize node inspector
ElectronicBlueberry Oct 18, 2024
d4e5b95
fix scroll height
ElectronicBlueberry Oct 18, 2024
a344b29
add form default to inspector
ElectronicBlueberry Oct 18, 2024
c6573a3
make form default full width
ElectronicBlueberry Oct 21, 2024
641258c
remove ability to sub-workflow own workflow
ElectronicBlueberry Oct 21, 2024
669e797
connect refresh list signal
ElectronicBlueberry Oct 21, 2024
68d333d
fix workflow creation
ElectronicBlueberry Oct 21, 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
2 changes: 1 addition & 1 deletion client/src/components/ActivityBar/ActivityBar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe("ActivityBar", () => {

beforeEach(async () => {
const pinia = createTestingPinia({ stubActions: false });
activityStore = useActivityStore();
activityStore = useActivityStore("default");
eventStore = useEventStore();
wrapper = shallowMount(mountTarget, {
localVue,
Expand Down
150 changes: 116 additions & 34 deletions client/src/components/ActivityBar/ActivityBar.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<script setup lang="ts">
import { faEllipsisH, type IconDefinition } from "@fortawesome/free-solid-svg-icons";
import { watchImmediate } from "@vueuse/core";
import { storeToRefs } from "pinia";
import { computed, type Ref, ref, watch } from "vue";
import { computed, type Ref, ref } from "vue";
import { useRoute } from "vue-router/composables";
import draggable from "vuedraggable";
import { useConfig } from "@/composables/config";
import { useHashedUserId } from "@/composables/hashedUserId";
import { convertDropData } from "@/stores/activitySetup";
import { type Activity, useActivityStore } from "@/stores/activityStore";
import { useEventStore } from "@/stores/eventStore";
Expand All @@ -24,6 +25,31 @@ import NotificationsPanel from "@/components/Panels/NotificationsPanel.vue";
import SettingsPanel from "@/components/Panels/SettingsPanel.vue";
import ToolPanel from "@/components/Panels/ToolPanel.vue";
const props = withDefaults(
defineProps<{
defaultActivities?: Activity[];
activityBarId?: string;
specialActivities?: Activity[];
showAdmin?: boolean;
optionsTitle?: string;
optionsTooltip?: string;
optionsHeading?: string;
optionsIcon?: IconDefinition;
optionsSearchPlaceholder?: string;
}>(),
{
defaultActivities: undefined,
activityBarId: "default",
specialActivities: () => [],
showAdmin: true,
optionsTitle: "More",
optionsHeading: "Additional Activities",
optionsIcon: () => faEllipsisH,
optionsSearchPlaceholder: "Search Activities",
optionsTooltip: "View additional activities",
}
);
// require user to long click before dragging
const DRAG_DELAY = 50;
Expand All @@ -32,13 +58,26 @@ const { config, isConfigLoaded } = useConfig();
const route = useRoute();
const userStore = useUserStore();
const { hashedUserId } = useHashedUserId();
const eventStore = useEventStore();
const activityStore = useActivityStore();
const activityStore = useActivityStore(props.activityBarId);
watchImmediate(
() => props.defaultActivities,
(defaults) => {
if (defaults) {
activityStore.overrideDefaultActivities(defaults);
} else {
activityStore.resetDefaultActivities();
}
}
);
const { isAdmin, isAnonymous } = storeToRefs(userStore);
const emit = defineEmits(["dragstart"]);
const emit = defineEmits<{
(e: "dragstart", dragItem: Activity | null): void;
(e: "activityClicked", activityId: string): void;
}>();
// activities from store
const { activities } = storeToRefs(activityStore);
Expand All @@ -50,30 +89,30 @@ const dragItem: Ref<Activity | null> = ref(null);
// drag state
const isDragging = ref(false);
// sync built-in activities with cached activities
activityStore.sync();
/**
* Checks if the route of an activity is currently being visited and panels are collapsed
*/
function isActiveRoute(activityTo: string) {
function isActiveRoute(activityTo?: string | null) {
return route.path === activityTo && isActiveSideBar("");
}
/**
* Checks if a panel has been expanded
*/
function isActiveSideBar(menuKey: string) {
return userStore.toggledSideBar === menuKey;
return activityStore.toggledSideBar === menuKey;
}
const isSideBarOpen = computed(() => userStore.toggledSideBar !== "");
const isSideBarOpen = computed(() => activityStore.toggledSideBar !== "");
/**
* Checks if an activity that has a panel should have the `is-active` prop
*/
function panelActivityIsActive(activity: Activity) {
return isActiveSideBar(activity.id) || (activity.to !== null && isActiveRoute(activity.to));
return (
isActiveSideBar(activity.id) ||
(activity.to !== undefined && activity.to !== null && isActiveRoute(activity.to))
);
}
/**
Expand Down Expand Up @@ -123,25 +162,37 @@ function onDragOver(evt: MouseEvent) {
/**
* Tracks the state of activities which expand or collapse the sidepanel
*/
function onToggleSidebar(toggle: string = "", to: string | null = null) {
function toggleSidebar(toggle: string = "", to: string | null = null) {
// if an activity's dedicated panel/sideBar is already active
// but the route is different, don't collapse
if (toggle && to && !(route.path === to) && isActiveSideBar(toggle)) {
return;
}
userStore.toggleSideBar(toggle);
activityStore.toggleSideBar(toggle);
}
watch(
() => hashedUserId.value,
() => {
activityStore.sync();
function onActivityClicked(activity: Activity) {
if (activity.click) {
emit("activityClicked", activity.id);
} else {
toggleSidebar();
}
);
}
function setActiveSideBar(key: string) {
activityStore.toggledSideBar = key;
}
defineExpose({
isActiveSideBar,
setActiveSideBar,
});
</script>

<template>
<div class="d-flex">
<!-- while this warning is correct, it is hiding too many other errors -->
<!-- eslint-disable-next-line vuejs-accessibility/no-static-element-interactions -->
<div
class="activity-bar d-flex flex-column no-highlight"
data-description="activity bar"
Expand Down Expand Up @@ -177,7 +228,7 @@ watch(
:title="activity.title"
:tooltip="activity.tooltip"
:to="activity.to"
@click="onToggleSidebar()" />
@click="toggleSidebar()" />
<ActivityItem
v-else-if="activity.id === 'admin' || activity.panel"
:id="`activity-${activity.id}`"
Expand All @@ -187,17 +238,18 @@ watch(
:title="activity.title"
:tooltip="activity.tooltip"
:to="activity.to || ''"
@click="onToggleSidebar(activity.id, activity.to)" />
@click="toggleSidebar(activity.id, activity.to)" />
<ActivityItem
v-else-if="activity.to"
v-else
:id="`activity-${activity.id}`"
:key="activity.id"
:icon="activity.icon"
:is-active="isActiveRoute(activity.to)"
:title="activity.title"
:tooltip="activity.tooltip"
:to="activity.to"
@click="onToggleSidebar()" />
:to="activity.to ?? undefined"
:variant="activity.variant"
@click="onActivityClicked(activity)" />
</div>
</div>
</draggable>
Expand All @@ -209,33 +261,63 @@ watch(
icon="bell"
:is-active="isActiveSideBar('notifications') || isActiveRoute('/user/notifications')"
title="Notifications"
@click="onToggleSidebar('notifications')" />
@click="toggleSidebar('notifications')" />
<ActivityItem
id="activity-settings"
icon="ellipsis-h"
:icon="props.optionsIcon"
:is-active="isActiveSideBar('settings')"
title="More"
tooltip="View additional activities"
@click="onToggleSidebar('settings')" />
:title="props.optionsTitle"
:tooltip="props.optionsTooltip"
@click="toggleSidebar('settings')" />
<ActivityItem
v-if="isAdmin"
v-if="isAdmin && showAdmin"
id="activity-admin"
icon="user-cog"
:is-active="isActiveSideBar('admin')"
title="Admin"
tooltip="Administer this Galaxy"
variant="danger"
@click="onToggleSidebar('admin')" />
@click="toggleSidebar('admin')" />
<template v-for="activity in props.specialActivities">
<ActivityItem
v-if="activity.panel"
:id="`activity-${activity.id}`"
:key="activity.id"
:icon="activity.icon"
:is-active="panelActivityIsActive(activity)"
:title="activity.title"
:tooltip="activity.tooltip"
:to="activity.to || ''"
:variant="activity.variant"
@click="toggleSidebar(activity.id, activity.to)" />
<ActivityItem
v-else
:id="`activity-${activity.id}`"
:key="activity.id"
:icon="activity.icon"
:is-active="isActiveRoute(activity.to)"
:title="activity.title"
:tooltip="activity.tooltip"
:to="activity.to ?? undefined"
:variant="activity.variant"
@click="onActivityClicked(activity)" />
</template>
</b-nav>
</div>
<FlexPanel v-if="isSideBarOpen" side="left" :collapsible="false">
<ToolPanel v-if="isActiveSideBar('tools')" />
<InvocationsPanel v-else-if="isActiveSideBar('invocation')" />
<InvocationsPanel v-else-if="isActiveSideBar('invocation')" :activity-bar-id="props.activityBarId" />
<VisualizationPanel v-else-if="isActiveSideBar('visualizations')" />
<MultiviewPanel v-else-if="isActiveSideBar('multiview')" />
<NotificationsPanel v-else-if="isActiveSideBar('notifications')" />
<SettingsPanel v-else-if="isActiveSideBar('settings')" />
<SettingsPanel
v-else-if="isActiveSideBar('settings')"
:activity-bar-id="props.activityBarId"
:heading="props.optionsHeading"
:search-placeholder="props.optionsSearchPlaceholder"
@activityClicked="(id) => emit('activityClicked', id)" />
<AdminPanel v-else-if="isActiveSideBar('admin')" />
<slot name="side-panel" :is-active-side-bar="isActiveSideBar"></slot>
</FlexPanel>
</div>
</template>
Expand Down
Loading