mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
add a new PageDisplayToolbar only used in preview mode so far
This commit is contained in:
@@ -8,6 +8,9 @@
|
||||
*
|
||||
* Change strings here to rename across the entire UI.
|
||||
*/
|
||||
import type { IconDefinition } from "@fortawesome/fontawesome-svg-core";
|
||||
import { faBook, faFileContract } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
import type { PageEditorMode } from "@/stores/pageEditorStore";
|
||||
|
||||
/** Per-mode labels used by the page editor, history page list, chat panel, etc. */
|
||||
@@ -16,6 +19,7 @@ export const PAGE_LABELS: Record<
|
||||
{
|
||||
entityName: string;
|
||||
entityNamePlural: string;
|
||||
titleIcon: IconDefinition;
|
||||
defaultTitle: string;
|
||||
editorBackLabel: string;
|
||||
newButton: string;
|
||||
@@ -30,6 +34,7 @@ export const PAGE_LABELS: Record<
|
||||
history: {
|
||||
entityName: "Galaxy Notebook",
|
||||
entityNamePlural: "Galaxy Notebooks",
|
||||
titleIcon: faBook,
|
||||
defaultTitle: "Untitled Notebook",
|
||||
editorBackLabel: "This History's Notebooks",
|
||||
newButton: "New Notebook",
|
||||
@@ -44,6 +49,7 @@ export const PAGE_LABELS: Record<
|
||||
standalone: {
|
||||
entityName: "Report",
|
||||
entityNamePlural: "Reports",
|
||||
titleIcon: faFileContract,
|
||||
defaultTitle: "Untitled Report",
|
||||
editorBackLabel: "Back to Reports",
|
||||
newButton: "Create Report",
|
||||
@@ -56,6 +62,7 @@ export const PAGE_LABELS: Record<
|
||||
invocation: {
|
||||
entityName: "Invocation Report",
|
||||
entityNamePlural: "Invocation Reports",
|
||||
titleIcon: faFileContract,
|
||||
defaultTitle: "Untitled Invocation Report",
|
||||
editorBackLabel: "This Invocation's Reports",
|
||||
newButton: "New Invocation Report",
|
||||
|
||||
@@ -159,7 +159,6 @@ function handleBack() {
|
||||
<PageDisplayOnly
|
||||
v-else-if="store.hasCurrentPage && displayOnly"
|
||||
:labels="labels"
|
||||
:current-title="store.currentTitle"
|
||||
:markdown-config="markdownConfig || undefined"
|
||||
@back="handleBack"
|
||||
@edit="handleEdit(props.pageId)" />
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { faArrowLeft, faEdit } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
|
||||
import type { PAGE_LABELS } from "@/components/Page/constants";
|
||||
|
||||
import type { MarkdownConfig } from "../Markdown/types.js";
|
||||
|
||||
import GButton from "../BaseComponents/GButton.vue";
|
||||
import Markdown from "../Markdown/Markdown.vue";
|
||||
import PageDisplayToolbar from "./PageDisplayToolbar.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
labels: (typeof PAGE_LABELS)[keyof typeof PAGE_LABELS];
|
||||
currentTitle?: string;
|
||||
markdownConfig?: MarkdownConfig;
|
||||
}>();
|
||||
|
||||
@@ -23,21 +19,7 @@ const emit = defineEmits<{
|
||||
|
||||
<template>
|
||||
<div class="d-flex flex-column">
|
||||
<div
|
||||
class="page-display-toolbar d-flex align-items-center p-2 border-bottom"
|
||||
data-description="page display toolbar">
|
||||
<GButton color="blue" transparent size="small" data-description="page back button" @click="emit('back')">
|
||||
<FontAwesomeIcon :icon="faArrowLeft" />
|
||||
{{ props.labels.editorBackLabel }}
|
||||
</GButton>
|
||||
<span class="flex-grow-1 text-center font-weight-bold">
|
||||
{{ props.currentTitle || props.labels.defaultTitle }}
|
||||
</span>
|
||||
<GButton color="blue" outline size="small" data-description="page edit button" @click="emit('edit')">
|
||||
<FontAwesomeIcon :icon="faEdit" />
|
||||
Edit
|
||||
</GButton>
|
||||
</div>
|
||||
<PageDisplayToolbar :labels="props.labels" mode="display" @edit="emit('edit')" @back="emit('back')" />
|
||||
<div class="page-display-content" data-description="page rendered view">
|
||||
<Markdown
|
||||
v-if="markdownConfig"
|
||||
@@ -51,10 +33,6 @@ const emit = defineEmits<{
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.page-display-toolbar {
|
||||
background: var(--color-grey-100);
|
||||
}
|
||||
|
||||
.page-display-content {
|
||||
overflow: auto;
|
||||
flex: 1 1 0;
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
faArrowLeft,
|
||||
faEdit,
|
||||
faEye,
|
||||
faHistory,
|
||||
faInfo,
|
||||
faPen,
|
||||
faSave,
|
||||
faSpinner,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import { BBadge } from "bootstrap-vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { computed, ref } from "vue";
|
||||
|
||||
import type { PAGE_LABELS } from "@/components/Page/constants";
|
||||
import { usePageEditorStore } from "@/stores/pageEditorStore.js";
|
||||
|
||||
import GButton from "../BaseComponents/GButton.vue";
|
||||
import GButtonGroup from "../BaseComponents/GButtonGroup.vue";
|
||||
import RenameModal from "../Common/RenameModal.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
labels: (typeof PAGE_LABELS)[keyof typeof PAGE_LABELS];
|
||||
mode: "editor" | "display";
|
||||
}>();
|
||||
|
||||
const pageEditorStore = usePageEditorStore();
|
||||
const { canSave, currentTitle, revisionCount, showRevisions, isDirty, isSaving } = storeToRefs(pageEditorStore);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "back"): void;
|
||||
(e: "edit"): void;
|
||||
(e: "preview"): void;
|
||||
}>();
|
||||
|
||||
const showRename = ref(false);
|
||||
|
||||
const saveDisabledTitle = computed(() => {
|
||||
const entity = props.labels.entityName.toLowerCase();
|
||||
if (props.mode === "display") {
|
||||
return `Currently previewing this ${entity}. Click 'Edit' to make changes and enable saving.`;
|
||||
}
|
||||
if (isSaving.value) {
|
||||
return `This ${entity} is being saved`;
|
||||
}
|
||||
if (!canSave.value) {
|
||||
return `There are no changes to save to this ${entity}`;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
|
||||
async function handleSave() {
|
||||
await pageEditorStore.savePage();
|
||||
}
|
||||
|
||||
function handleTitleChange(newTitle: string): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
pageEditorStore.updateTitle(newTitle);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="page-display-toolbar d-flex align-items-center py-2 px-3 border-bottom flex-gapx-1 justify-content-between"
|
||||
:data-description="`page ${props.mode} toolbar`">
|
||||
<div class="d-flex align-items-center flex-gapx-1 title-section">
|
||||
<FontAwesomeIcon :icon="props.labels.titleIcon" fixed-width />
|
||||
<b class="page-title" :data-description="`page ${props.mode} title`">
|
||||
{{ currentTitle || props.labels.defaultTitle }}
|
||||
</b>
|
||||
<GButton
|
||||
v-if="props.mode === 'editor'"
|
||||
inline
|
||||
transparent
|
||||
data-description="page rename button"
|
||||
:title="`Rename this ${props.labels.entityName.toLowerCase()}`"
|
||||
@click="showRename = true">
|
||||
<FontAwesomeIcon :icon="faPen" />
|
||||
</GButton>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center flex-gapx-1 flex-shrink-0">
|
||||
<span
|
||||
v-if="isDirty"
|
||||
class="d-flex align-items-center flex-gapx-1 text-warning small"
|
||||
data-description="page unsaved indicator">
|
||||
<BBadge variant="warning" class="text-light">
|
||||
<FontAwesomeIcon :icon="faInfo" />
|
||||
</BBadge>
|
||||
Unsaved
|
||||
</span>
|
||||
|
||||
<GButton color="blue" transparent size="small" data-description="page back button" @click="emit('back')">
|
||||
<FontAwesomeIcon :icon="faArrowLeft" />
|
||||
{{ props.labels.editorBackLabel }}
|
||||
</GButton>
|
||||
|
||||
<slot name="extra-actions" />
|
||||
|
||||
<GButton
|
||||
v-if="props.mode === 'editor'"
|
||||
color="blue"
|
||||
outline
|
||||
:pressed="showRevisions"
|
||||
data-description="page revisions button"
|
||||
size="small"
|
||||
@click="pageEditorStore.toggleRevisions">
|
||||
<FontAwesomeIcon :icon="faHistory" />
|
||||
Revisions
|
||||
<BBadge v-if="revisionCount > 0" variant="light" class="ml-1">
|
||||
{{ revisionCount }}
|
||||
</BBadge>
|
||||
</GButton>
|
||||
|
||||
<GButtonGroup data-description="revision view mode toggle">
|
||||
<GButton
|
||||
color="blue"
|
||||
outline
|
||||
:pressed="props.mode === 'editor'"
|
||||
data-description="page edit button"
|
||||
size="small"
|
||||
@click="emit('edit')">
|
||||
<FontAwesomeIcon :icon="faEdit" />
|
||||
Edit
|
||||
</GButton>
|
||||
<GButton
|
||||
color="blue"
|
||||
outline
|
||||
:pressed="props.mode === 'display'"
|
||||
data-description="page preview button"
|
||||
size="small"
|
||||
@click="emit('preview')">
|
||||
<FontAwesomeIcon :icon="faEye" />
|
||||
Preview
|
||||
</GButton>
|
||||
</GButtonGroup>
|
||||
|
||||
<GButton
|
||||
color="blue"
|
||||
data-description="page save button"
|
||||
:title="`Save ${props.labels.entityName}`"
|
||||
tooltip
|
||||
:disabled="props.mode === 'display' || !canSave"
|
||||
:disabled-title="saveDisabledTitle"
|
||||
size="small"
|
||||
@click="handleSave">
|
||||
<FontAwesomeIcon :icon="isSaving ? faSpinner : faSave" :spin="isSaving" />
|
||||
Save
|
||||
</GButton>
|
||||
</div>
|
||||
|
||||
<RenameModal
|
||||
v-if="showRename"
|
||||
:item-type="props.labels.entityName"
|
||||
:name="currentTitle || props.labels.defaultTitle"
|
||||
:rename-action="handleTitleChange"
|
||||
@close="showRename = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.page-display-toolbar {
|
||||
background: var(--color-grey-100);
|
||||
}
|
||||
.title-section {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.page-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
@@ -187,7 +187,6 @@ function handleRevisionRestore(revisionId: string) {
|
||||
<PageDisplayOnly
|
||||
v-else-if="store.hasCurrentPage && displayOnly"
|
||||
:labels="labels"
|
||||
:current-title="store.currentTitle"
|
||||
:markdown-config="markdownConfig || undefined"
|
||||
@back="handleBack"
|
||||
@edit="handleEdit" />
|
||||
@@ -209,9 +208,7 @@ function handleRevisionRestore(revisionId: string) {
|
||||
|
||||
<!-- Edit mode: toolbar + editor + optional chat/revision panels -->
|
||||
<template v-else-if="store.hasCurrentPage">
|
||||
<div
|
||||
class="page-toolbar d-flex align-items-center p-2 border-bottom"
|
||||
data-description="page editor toolbar">
|
||||
<div class="d-flex align-items-center p-2 border-bottom" data-description="page editor toolbar">
|
||||
<BButton variant="link" size="sm" data-description="page back button" @click="handleBack">
|
||||
<FontAwesomeIcon :icon="faArrowLeft" />
|
||||
{{ labels.editorBackLabel }}
|
||||
@@ -310,9 +307,6 @@ function handleRevisionRestore(revisionId: string) {
|
||||
.page-editor-view {
|
||||
background: var(--body-bg);
|
||||
}
|
||||
.page-toolbar {
|
||||
background: var(--panel-header-bg);
|
||||
}
|
||||
.page-revision-panel {
|
||||
width: 300px;
|
||||
min-width: 300px;
|
||||
|
||||
Reference in New Issue
Block a user