Commit d88c812b authored by wuzekai's avatar wuzekai

feat: 汉化 /histories 与 /datasets 路由页面

- /histories 列表/查看/归档/导出页面汉化
- /datasets 列表/查看/复制/详情页面汉化
- 历史卡片操作、数据集操作、状态提示等界面文本中文化
parent 3932f929
......@@ -77,7 +77,7 @@ async function loadHistories() {
await loadContents();
}
} else {
errorMessage.value = "No Histories found.";
errorMessage.value = "未找到历史记录。";
}
loading.value = false;
}
......@@ -145,7 +145,7 @@ async function onCopy() {
}
loading.value = false;
} else {
errorMessage.value = "Please select datasets and collections.";
errorMessage.value = "请选择数据集和集合。";
}
}
......@@ -162,7 +162,7 @@ defineExpose({
<div>
<BAlert v-if="errorMessage" variant="danger" show>{{ errorMessage }}</BAlert>
<BAlert v-else-if="successTargetIds.length > 0 && successTargetIds[0]" variant="success" show>
{{ successItemCount }} item{{ successItemCount === 1 ? "" : "s" }} copied to:
{{ successItemCount }} 个项目已复制到:
<span v-if="successHistoryName">
<RouterLink
:to="`/histories/view?id=${successTargetIds[0]}`"
......@@ -214,9 +214,9 @@ defineExpose({
</div>
<div class="d-flex mt-2">
<BButton class="mr-2" size="sm" variant="outline-primary" @click="toggleAll(true)">
Select All
全选
</BButton>
<BButton size="sm" variant="outline-primary" @click="toggleAll(false)"> Unselect All </BButton>
<BButton size="sm" variant="outline-primary" @click="toggleAll(false)"> 取消全选 </BButton>
</div>
</div>
......@@ -239,7 +239,7 @@ defineExpose({
newHistoryName = '';
targetMultiSelections = {};
" />
<span class="text-sm mt-1"><b>OR</b> Select Multiple Target Histories:</span>
<span class="text-sm mt-1"><b>或</b> 选择多个目标历史记录:</span>
<div class="dataset-copy-contents flex-grow-1 overflow-auto border rounded p-2">
<div v-if="histories.length === 0" class="text-muted">没有历史。</div>
<div v-for="h in histories" :key="h.id" class="d-flex align-items-center mb-1">
......@@ -253,7 +253,7 @@ defineExpose({
</BFormCheckbox>
</div>
</div>
<span class="text-sm mt-1"><b>OR</b> Provide a New History Name:</span>
<span class="text-sm mt-1"><b>或</b> 提供新的历史记录名称:</span>
<BFormInput
v-model="newHistoryName"
data-description="copy history name"
......
......@@ -77,14 +77,14 @@ watch(
<BAlert v-if="errorMessage" variant="danger" show>
{{ errorMessage }}
</BAlert>
<LoadingSpan v-else-if="isLoading || !dataset" message="Loading dataset content" />
<LoadingSpan v-else-if="isLoading || !dataset" message="正在加载数据集内容" />
<BAlert v-else-if="STATES.PENDING_STATES.includes(dataset.state)" show variant="warning">
<FontAwesomeIcon :icon="faSpinner" spin />
<span>Waiting for dataset to become available. Please check the history panel for details.</span>
<span>正在等待数据集变为可用。请查看历史记录面板以获取详细信息。</span>
</BAlert>
<BAlert v-else-if="!STATES.OK_STATES.includes(dataset.state)" show variant="danger">
<FontAwesomeIcon :icon="faExclamationTriangle" />
<span>Dataset is unavailable. Please check the history panel for details.</span>
<span>数据集不可用。请查看历史记录面板以获取详细信息。</span>
</BAlert>
<div v-else class="dataset-display h-100">
<Alert v-if="sanitizedMessage" :dismissible="true" variant="warning" data-description="sanitization warning">
......
......@@ -24,32 +24,32 @@ import LoadingSpan from "@/components/LoadingSpan.vue";
import StatelessTags from "@/components/TagsMultiselect/StatelessTags.vue";
import UtcDate from "@/components/UtcDate.vue";
const breadcrumbItems = [{ title: "Datasets", to: "/datasets/list" }];
const breadcrumbItems = [{ title: "数据集", to: "/datasets/list" }];
const allFields = [
{
key: "name",
label: "Name",
label: "名称",
sortable: true,
},
{
key: "tags",
label: "Tags",
label: "标签",
sortable: false,
},
{
key: "history_id",
label: "History",
label: "历史记录",
sortable: true,
},
{
key: "extension",
label: "Extension",
label: "扩展名",
sortable: true,
},
{
key: "update_time",
label: "Updated",
label: "更新于",
sortable: true,
},
];
......@@ -112,7 +112,7 @@ async function load(showOverlay = false) {
rows.value = data;
totalDatasets.value = totalMatches;
} catch (e: any) {
Toast.error(`Failed to load datasets: ${e}`);
Toast.error(`无法加载数据集:${e}`);
} finally {
loading.value = false;
overlay.value = false;
......@@ -129,7 +129,7 @@ async function onTags(tags: string[], index: number) {
try {
await updateTags(item?.id as string, "HistoryDatasetAssociation", tags);
} catch (e: any) {
Toast.error(`Failed to update tags: ${e}`);
Toast.error(`无法更新标签:${e}`);
}
}
......@@ -189,10 +189,10 @@ function onToggleColumn(key: string) {
async function onBulkDelete() {
const totalSelected = selectedItemIds.value.length;
const confirmed = await confirm(`Are you sure you want to delete ${totalSelected} datasets?`, {
const confirmed = await confirm(`确定要删除 ${totalSelected} 个数据集吗?`, {
id: "bulk-delete-datasets-confirmation",
title: "Delete datasets",
okTitle: "Delete datasets",
title: "删除数据集",
okTitle: "删除数据集",
okVariant: "danger",
cancelVariant: "outline-primary",
centered: true,
......@@ -215,11 +215,11 @@ async function onBulkDelete() {
);
}
Toast.success(`Deleted ${totalSelected} dataset${totalSelected > 1 ? "s" : ""}.`);
Toast.success(`已删除 ${totalSelected} 个数据集。`);
selectedItemIds.value = [];
} catch (e: any) {
Toast.error(`Failed to delete some datasets: ${e}`);
Toast.error(`无法删除部分数据集:${e}`);
} finally {
overlay.value = false;
bulkDeleteOrRestoreLoading.value = false;
......@@ -231,13 +231,13 @@ async function onBulkDelete() {
function getDatasetStatusIcon(item: HDASummary): RowIcon | undefined {
if (item.purged) {
return { icon: faBurn, class: "text-danger", title: "Purged" };
return { icon: faBurn, class: "text-danger", title: "已清除" };
}
if (item.deleted) {
return { icon: faTrash, class: "text-muted", title: "Deleted" };
return { icon: faTrash, class: "text-muted", title: "已删除" };
}
if (item.state === "ok") {
return { icon: faCheckCircle, class: "text-success", title: "Success" };
return { icon: faCheckCircle, class: "text-success", title: "成功" };
}
const state = item.state && STATES[item.state];
if (state?.icon) {
......@@ -260,7 +260,7 @@ onMounted(() => {
<div class="dataset-list-container h-100 d-flex flex-column">
<BreadcrumbHeading :items="breadcrumbItems" />
<div class="dataset-list-header">
<DelayedInput class="m-2 mb-3" placeholder="Search Datasets" @change="onQuery" />
<DelayedInput class="m-2 mb-3" placeholder="搜索数据集" @change="onQuery" />
<ListHeader
list-id="datasets"
......@@ -276,17 +276,17 @@ onMounted(() => {
<div v-if="loading" class="dataset-list-content">
<BAlert variant="info" show>
<LoadingSpan message="Loading datasets" />
<LoadingSpan message="正在加载数据集" />
</BAlert>
</div>
<div v-else-if="showNotAvailable" class="dataset-list-content">
<BAlert id="dataset-list-empty" variant="info" show>
No datasets found. You may upload new datasets using the button above.
未找到数据集。您可以使用上方按钮上传新的数据集。
</BAlert>
</div>
<div v-else-if="showNotFound" class="dataset-list-content">
<BAlert id="no-dataset-found" variant="info" show>
No matching entries found for: <span class="font-weight-bold">{{ query }}</span>
未找到匹配的条目:<span class="font-weight-bold">{{ query }}</span>
</BAlert>
</div>
<div v-else class="dataset-list-content overflow-auto">
......@@ -342,7 +342,7 @@ onMounted(() => {
size="sm"
variant="primary"
:disabled="bulkDeleteOrRestoreLoading"
:title="bulkDeleteOrRestoreLoading ? 'Deleting datasets' : 'Delete selected datasets'"
:title="bulkDeleteOrRestoreLoading ? '正在删除数据集' : '删除选中的数据集'"
@click="onBulkDelete">
<FontAwesomeIcon :icon="faTrash" />
{{ localize("Delete Selected") }} ({{ selectedItemIds.length }})
......
......@@ -37,7 +37,7 @@ watch(props, () => {
<template>
<div>
<LoadingSpan v-if="loading" message="Loading permission information" />
<LoadingSpan v-if="loading" message="正在加载权限信息" />
<div v-else-if="simplePermissions && !selectedAdvancedForm">
<PortletSection :icon="faUsers" :title="title">
<div class="mb-3">
......
......@@ -73,7 +73,7 @@ watch(props, fetch, { immediate: true });
<div v-if="errorMessage" class="error">{{ errorMessage }}</div>
<LoadingSpan v-else-if="storageInfo == null"> </LoadingSpan>
<div v-else-if="discarded">
<p>This dataset has been discarded and its files are not available to Galaxy.</p>
<p>此数据集已被弃用,其文件对 Galaxy 不可用。</p>
</div>
<div v-else-if="deferred">
<p>
......
......@@ -92,7 +92,7 @@ async function relocate(objectStoreId: string) {
<template>
<span class="storage-relocate-link">
<SelectModal v-if="currentObjectStore" v-model="showModal" title="Relocate Dataset">
<SelectModal v-if="currentObjectStore" v-model="showModal" title="迁移数据集">
<RelocateDialog
:from-object-store="currentObjectStore"
:target-object-stores="validTargets"
......
......@@ -117,7 +117,7 @@ watch(
}}
</p>
</div>
<LoadingSpan v-else-if="isLoading || !dataset" message="Loading dataset details" />
<LoadingSpan v-else-if="isLoading || !dataset" message="正在加载数据集详情" />
<div v-else class="dataset-view d-flex flex-column">
<header v-if="!displayOnly" :key="`dataset-header-${dataset.id}`" class="dataset-header flex-shrink-0">
<div class="d-flex">
......@@ -168,43 +168,43 @@ watch(
<BNav v-if="!displayOnly" pills class="my-2 p-2 bg-light border-bottom">
<BNavItem
v-if="showOk"
title="View a preview of the dataset contents"
title="查看数据集内容的预览"
:active="tab === 'preview'"
:to="`/datasets/${datasetId}/preview`">
<FontAwesomeIcon :icon="faEye" class="mr-1" /> Preview
<FontAwesomeIcon :icon="faEye" class="mr-1" /> 预览
</BNavItem>
<BNavItem
v-if="showOk && preferredVisualization"
title="View raw dataset contents"
title="查看数据集原始内容"
:active="tab === 'raw'"
:to="`/datasets/${datasetId}/raw`">
<FontAwesomeIcon :icon="faFileAlt" class="mr-1" /> Raw
<FontAwesomeIcon :icon="faFileAlt" class="mr-1" /> 原始
</BNavItem>
<BNavItem
v-if="showOk"
title="Explore available visualizations for this dataset"
title="探索此数据集可用的可视化"
:active="tab === 'visualize'"
:to="`/datasets/${datasetId}/visualize`">
<FontAwesomeIcon :icon="faChartBar" class="mr-1" /> Visualize
<FontAwesomeIcon :icon="faChartBar" class="mr-1" /> 可视化
</BNavItem>
<BNavItem
title="View detailed information about this dataset"
title="查看此数据集的详细信息"
:active="tab === 'details'"
:to="`/datasets/${datasetId}/details`">
<FontAwesomeIcon :icon="faInfoCircle" class="mr-1" /> Details
<FontAwesomeIcon :icon="faInfoCircle" class="mr-1" /> 详情
</BNavItem>
<BNavItem
title="Edit dataset attributes and metadata"
title="编辑数据集属性和元数据"
:active="tab === 'edit'"
:to="`/datasets/${datasetId}/edit`">
<FontAwesomeIcon :icon="faPen" class="mr-1" /> Edit
<FontAwesomeIcon :icon="faPen" class="mr-1" /> 编辑
</BNavItem>
<BNavItem
v-if="showError"
title="View error information for this dataset"
title="查看此数据集的错误信息"
:active="tab === 'error'"
:to="`/datasets/${datasetId}/error`">
<FontAwesomeIcon :icon="faBug" class="mr-1" /> Error
<FontAwesomeIcon :icon="faBug" class="mr-1" /> 错误
</BNavItem>
</BNav>
<div v-if="tab === 'preview'" class="tab-content-panel">
......@@ -216,7 +216,7 @@ watch(
<div v-else-if="isAutoDownloadType && !isPdfDataset" class="auto-download-message p-4">
<div class="alert alert-info">
<h4>{{ localize("Download Required") }}</h4>
<p>This file type ({{ dataset.file_ext }}) will download automatically when accessed directly.</p>
<p>此文件类型({{ dataset.file_ext }})在直接访问时会自动下载。</p>
<p>{{ localize("File size:") }} <strong v-html="bytesToString(dataset.file_size || 0, false)" /></p>
<a :href="downloadUrl" class="btn btn-primary mt-2" download>
<FontAwesomeIcon :icon="faFileAlt" class="mr-1" /> {{ localize("Download File") }}
......@@ -234,7 +234,7 @@ watch(
<div v-if="isAutoDownloadType && !isPdfDataset" class="auto-download-message p-4">
<div class="alert alert-info">
<h4>{{ localize("Download Required") }}</h4>
<p>This file type ({{ dataset.file_ext }}) will download automatically when accessed directly.</p>
<p>此文件类型({{ dataset.file_ext }})在直接访问时会自动下载。</p>
<p>{{ localize("File size:") }} <strong v-html="bytesToString(dataset.file_size || 0, false)" /></p>
<a :href="downloadUrl" class="btn btn-primary mt-2" download>
<FontAwesomeIcon :icon="faFileAlt" class="mr-1" /> {{ localize("Download File") }}
......
......@@ -25,7 +25,7 @@ export function useDatasetTableActions(refreshList: () => Promise<void>) {
try {
await historyStore.applyFilters(history_id, filters);
} catch (error) {
Toast.error("Failed to show dataset in history");
Toast.error("无法在历史记录中显示数据集");
}
}
......@@ -34,25 +34,25 @@ export function useDatasetTableActions(refreshList: () => Promise<void>) {
try {
if (!currentHistoryId.value) {
throw new Error("No current history found.");
throw new Error("未找到当前历史记录。");
}
await copyDataset(dataset_id, currentHistoryId.value);
historyStore.loadCurrentHistory();
await refreshList();
Toast.success(`Dataset "${item.name}" copied to current history.`);
Toast.success(`数据集“${item.name}”已复制到当前历史记录。`);
} catch (error) {
Toast.error("Failed to copy dataset");
Toast.error("无法复制数据集");
}
}
async function confirmDeleteDataset(item: HDASummary, purge: boolean) {
const confirmed = await confirm(
`Are you sure you want to ${purge ? "purge" : "delete"} the dataset "${item.name}"?`,
`确定要${purge ? "永久删除" : "删除"}数据集“${item.name}”吗?`,
{
title: purge ? "Purge Dataset" : "Delete Dataset",
okTitle: purge ? "Purge" : "Delete",
title: purge ? "永久删除数据集" : "删除数据集",
okTitle: purge ? "永久删除" : "删除",
okVariant: "danger",
},
);
......@@ -61,11 +61,11 @@ export function useDatasetTableActions(refreshList: () => Promise<void>) {
try {
await deleteDataset(item.id, purge);
Toast.success(`Dataset "${item.name}" ${purge ? "purged" : "deleted"}.`);
Toast.success(`数据集“${item.name}”已${purge ? "永久删除" : "删除"}。`);
historyStore.loadCurrentHistory();
await refreshList();
} catch (error) {
Toast.error(`Failed to ${purge ? "purge" : "delete"} dataset.`);
Toast.error(`无法${purge ? "永久删除" : "删除"}数据集。`);
}
}
}
......@@ -81,29 +81,29 @@ export function useDatasetTableActions(refreshList: () => Promise<void>) {
const datasetTableActions: TableAction[] = [
{
id: "copy-dataset",
label: "Copy to current history",
title: "Copy Dataset to current history",
label: "复制到当前历史记录",
title: "将数据集复制到当前历史记录",
icon: faCopy,
handler: onCopyDataset,
},
{
id: "show-dataset",
label: "Show in history",
title: "Show dataset in history panel",
label: "在历史记录中显示",
title: "在历史记录面板中显示数据集",
icon: faEye,
handler: onShowDataset,
},
{
id: "delete-dataset",
label: "Delete",
title: "Delete dataset",
label: "删除",
title: "删除数据集",
icon: faTrash,
handler: onDeleteDataset,
},
{
id: "purge-dataset",
label: "Purge",
title: "Purge dataset",
label: "永久删除",
title: "永久删除数据集",
icon: faFire,
handler: onPurgeDataset,
},
......
......@@ -126,7 +126,7 @@ onUnmounted(() => {
</span>
<div v-if="dataset.peek">
<Heading id="dataset-peek-heading" h2 separator inline size="md"> Dataset Peek </Heading>
<Heading id="dataset-peek-heading" h2 separator inline size="md"> 数据集预览 </Heading>
<div class="dataset-peek" v-html="dataset.peek" />
</div>
......@@ -141,8 +141,7 @@ onUnmounted(() => {
<h2 class="h-md">未找到作业</h2>
<p>
No job associated with this dataset is recorded in Galaxy. Galaxy cannot determine full dataset
provenance and history for this dataset.
Galaxy 中没有记录与此数据集关联的作业。Galaxy 无法确定此数据集的完整来源和历史记录。
</p>
</div>
</div>
......
......@@ -93,14 +93,14 @@ async function updateExports() {
waitForTask(mostUpToDateExport.value.taskUUID);
}
if (taskMonitorRequestFailed.value) {
exportErrorMessage.value = "The request to get the export progress failed. Please check back later.";
exportErrorMessage.value = "获取导出进度的请求失败,请稍后查看。";
}
if (taskHasFailed.value) {
exportErrorMessage.value = "The history export request failed. Please try again later.";
exportErrorMessage.value = "历史记录导出请求失败,请稍后重试。";
}
}
} catch (e) {
exportErrorMessage.value = "The request to get your history exports records failed. Please check back later.";
exportErrorMessage.value = "获取您历史记录导出记录列表的请求失败,请稍后查看。";
}
}
......@@ -122,7 +122,7 @@ async function doExportToFileSource(exportDirectory: string, fileName: string) {
try {
await exportHistoryToFileSource(props.history.id, exportDirectory, fileName, DEFAULT_EXPORT_PARAMS);
} catch (error) {
exportErrorMessage.value = "The history export request failed. Please try again later.";
exportErrorMessage.value = "历史记录导出请求失败,请稍后重试。";
}
updateExports();
}
......@@ -137,15 +137,14 @@ function onArchiveHistoryWithExport() {
<template>
<div>
<p>
If you are not planning to use this history in the near future, you can
<b>archive and delete its contents to free up disk space</b>.
如果您近期不打算使用此历史记录,可以
<b>归档并删除其内容以释放磁盘空间</b>。
</p>
<p>
To be able to recreate your archived history later, you need to export it first to a permanent remote
location. Then you will be able to import it back to Galaxy from the remote source, as a new copy.
为了日后能重建已归档的历史记录,您需要先将其导出到永久远程位置。之后您可以从远程来源将历史记录作为新副本重新导入 Galaxy。
</p>
<BAlert v-if="isLoading" show variant="info">
<LoadingSpan message="Retrieving export records..." />
<LoadingSpan message="正在获取导出记录…" />
</BAlert>
<BAlert v-else-if="exportErrorMessage" show variant="danger">
<p>
......@@ -159,44 +158,39 @@ function onArchiveHistoryWithExport() {
<b>此历史已有最新的导出记录可用。</b>
</p>
<p>
This export record will be associated with your archived history so you can recreate it later by
importing it.
此导出记录将与您的已归档历史记录关联,以便您之后通过导入来重建它。
</p>
<ExportRecordCard id="export-record-ready" class="mt-3" :export-record="mostUpToDateExport" />
</BAlert>
</div>
<div v-else>
<BAlert v-if="isExportingRecord" id="generating-export-record-alert" show variant="info">
<LoadingSpan message="Generating export record. This may take a while..." />
<LoadingSpan message="正在生成导出记录,这可能需要一些时间…" />
</BAlert>
<BAlert v-else show variant="info">
<p>
<b>
There is no up-to-date export record of this history. You need to create a new export record to
be able to recreate the history later.
此历史记录没有最新的导出记录。您需要创建新的导出记录,以便之后能重建历史记录。
</b>
</p>
<p>Use the button below to create a new export record before archiving the history.</p>
<p>在归档历史记录之前,请使用下方按钮创建新的导出记录。</p>
<BButton
id="create-export-record-btn"
:disabled="!canCreateExportRecord"
variant="primary"
@click="onCreateExportRecord">
Create export record
创建导出记录
</BButton>
</BAlert>
</div>
<p v-if="!isDeleteContentsConfirmed" class="mt-3 mb-0">
To continue, you need to confirm that you want to delete the contents of the original history before you can
archive it using the checkbox below. If you created an export record above, you will be able to recreate the
history later by importing it from the export record.
要继续,您需要使用下方复选框确认您希望删除原始历史记录的内容,然后才能归档它。如果您在上方创建了导出记录,之后可以通过从导出记录导入来重建历史记录。
</p>
<BFormCheckbox id="confirm-delete-checkbox" v-model="isDeleteContentsConfirmed" class="my-3">
<b>I am aware that the contents of the original history will be permanently deleted.</b>
<b>我已知晓原始历史记录的内容将被永久删除。</b>
</BFormCheckbox>
<BAlert show variant="warning">
Remember that you cannot undo this action. Once you archive and delete the history, you can only recover it
by importing it as a new copy from the export record.
请注意,您无法撤销此操作。一旦归档并删除历史记录,您只能通过从导出记录中导入新副本的方式来恢复它。
</BAlert>
<BButton
id="archive-history-btn"
......@@ -204,37 +198,30 @@ function onArchiveHistoryWithExport() {
:disabled="!canArchiveHistory"
variant="primary"
@click="onArchiveHistoryWithExport">
Archive (and purge) history
归档(并清除)历史记录
</BButton>
<BModal v-model="isExportDialogOpen" title="Export history to permanent storage" size="lg" hide-footer>
<BModal v-model="isExportDialogOpen" title="将历史记录导出到永久存储" size="lg" hide-footer>
<GTabs card vertical lazy class="export-option-tabs">
<GTab id="to-remote-file-tab" title="To Repository" active>
<GTab id="to-remote-file-tab" title="导出到仓库" active>
<p>
<b>正在导出到仓库</b> will create a compressed archive of the history contents, copy
it to a remote location (e.g. an FTP server) and create an export record with this information
that will be associated with the archived history. You will be able to recreate the history
later by importing it from the export record.
<b>正在导出到仓库</b> 将创建历史记录内容的压缩归档,将其复制到远程位置(例如 FTP 服务器),并创建包含这些信息的导出记录,该记录将与已归档的历史记录关联。之后您可以通过从导出记录导入来重建历史记录。
</p>
<ExportToFileSourceForm what="history" @export="doExportToFileSourceWithPrefix" />
</GTab>
<GTab id="to-rdm-repository-tab" title="To RDM Repository">
<GTab id="to-rdm-repository-tab" title="导出到 RDM 仓库">
<p>
<b>正在导出到 RDM 仓库</b> (e.g. any
<b>正在导出到 RDM 仓库</b>(例如任何
<ExternalLink href="https://inveniosoftware.org/products/rdm/"> Invenio RDM </ExternalLink>
compatible repository) will require to create or select an existing record in the repository
where the history archive will be uploaded. The export record will be associated with the
archived history and you will be able to recreate the history later by importing it from the
export record.
兼容的仓库)将要求在仓库中创建或选择一个现有记录,用于上传历史归档。导出记录将与已归档的历史记录关联,之后您可以通过从导出记录导入来重建历史记录。
</p>
<p>
You may need to setup your credentials for the selected repository in your
<RouterLink to="/user/information" target="_blank">settings page</RouterLink> to be able to
export.
您可能需要先在您的
<RouterLink to="/user/information" target="_blank">设置页面</RouterLink> 中为所选仓库配置凭据,才能导出。
</p>
<ExportToRDMRepositoryForm
what="history"
:default-filename="historyName + ' (Galaxy History)'"
:default-filename="historyName + ' (Galaxy 历史记录)'"
:default-record-name="historyName"
@export="doExportToFileSource" />
</GTab>
......
......@@ -11,20 +11,18 @@ function onArchiveHistory() {
<template>
<div>
<p>
If you want to remove the history from your <i>active</i> histories but keep it around for reference, you
can move it to the <b>{{ localize("Archived Histories") }}</b> section, by clicking the button below.
如果您想将历史记录从您的<i>活动</i>历史记录中移除但保留以便参考,可以点击下方按钮将其移动到
<b>{{ localize("Archived Histories") }}</b> 部分。
</p>
<p>
This is particularly useful if you have a lot of histories and want to keep the list of
<i>active</i> histories short or if you publish a history and want to avoid accidental changes to it.
如果您有很多历史记录、希望保持<i>活动</i>历史记录列表简洁,或者发布了一个历史记录并希望避免对其产生意外更改,此功能尤其有用。
</p>
<p>
You can undo this action at any time, and the history will be moved back to your
<i>active</i> histories.
您可以随时撤销此操作,历史记录将被移回您的<i>活动</i>历史记录。
</p>
<BButton class="archive-history-btn mt-3" variant="primary" @click="onArchiveHistory">
Archive history
归档历史记录
</BButton>
</div>
</template>
......@@ -90,18 +90,18 @@ const breadcrumbItems = computed(() => [
</BAlert>
<div v-else-if="history">
<BAlert show variant="info">
Archiving a history will remove it from your <i>active histories</i>. You can still access it from the
<RouterLink :to="archivedHistoriesRoute">{{ localize("Archived Histories") }}</RouterLink> section.
归档历史记录会将其从您的<i>活动历史记录</i>中移除。您仍可从
<RouterLink :to="archivedHistoriesRoute">{{ localize("Archived Histories") }}</RouterLink> 部分访问它。
</BAlert>
<div v-if="canFreeStorage">
<h2 class="h-md">How do you want to archive this history?</h2>
<h2 class="h-md">您希望如何归档此历史记录?</h2>
<BCard no-body class="mt-3">
<GTabs pills card vertical lazy class="archival-option-tabs">
<GTab id="keep-storage-tab" title="Keep storage space" active>
<GTab id="keep-storage-tab" title="保留存储空间" active>
<HistoryArchiveSimple :history="history" @onArchive="onArchiveHistory" />
</GTab>
<GTab id="free-storage-tab" title="Free storage space">
<GTab id="free-storage-tab" title="释放存储空间">
<HistoryArchiveExportSelector :history="history" @onArchive="onArchiveHistory" />
</GTab>
</GTabs>
......
......@@ -347,7 +347,7 @@ function unexpandedClick(event: Event) {
v-b-tooltip.hover
variant="link"
class="p-0"
title="Input"
title="输入"
@click.stop="toggleHighlights">
<FontAwesomeIcon class="text-info" :icon="faArrowCircleUp" />
</BButton>
......@@ -356,7 +356,7 @@ function unexpandedClick(event: Event) {
v-b-tooltip.hover
variant="link"
class="p-0"
title="Inputs/Outputs highlighted for this item"
title="为此项目高亮显示输入/输出"
@click.stop="toggleHighlights"
@keypress="toggleHighlights">
<FontAwesomeIcon :icon="faCheckCircle" />
......@@ -366,7 +366,7 @@ function unexpandedClick(event: Event) {
v-b-tooltip.hover
variant="link"
class="p-0"
title="Output"
title="输出"
@click.stop="toggleHighlights">
<FontAwesomeIcon class="text-info" :icon="faArrowCircleDown" />
</BButton>
......@@ -381,15 +381,15 @@ function unexpandedClick(event: Event) {
<span class="content-title name font-weight-bold">{{ name }}</span>
</span>
<span v-if="item.purged" class="ml-auto align-self-start btn-group p-1">
<BBadge variant="secondary" title="This dataset has been permanently deleted">
<FontAwesomeIcon :icon="faBurn" /> Purged
<BBadge variant="secondary" title="此数据集已被永久删除">
<FontAwesomeIcon :icon="faBurn" /> 已清除
</BBadge>
</span>
<span class="align-self-start btn-group">
<BButton
v-if="item.sub_items?.length && !isSubItem"
v-b-tooltip.hover
title="Show converted items"
title="显示已转换的项目"
tabindex="0"
class="display-btn px-1 align-items-center"
size="sm"
......
......@@ -170,13 +170,13 @@ function onDisplay($event: MouseEvent) {
<template v-slot:button-content>
<FontAwesomeIcon :icon="faTrash" />
</template>
<b-dropdown-item title="Delete collection only" @click.prevent.stop="onDeleteItem">
<b-dropdown-item title="仅删除集合" @click.prevent.stop="onDeleteItem">
<FontAwesomeIcon :icon="faFile" />
Collection only
仅集合
</b-dropdown-item>
<b-dropdown-item title="Delete collection and elements" @click.prevent.stop="onDeleteItemRecursively">
<b-dropdown-item title="删除集合及其元素" @click.prevent.stop="onDeleteItemRecursively">
<FontAwesomeIcon :icon="faCopy" />
Collection and elements
集合及其元素
</b-dropdown-item>
</BDropdown>
</BButton>
......
......@@ -99,7 +99,7 @@ function onRerun() {
v-if="showError"
v-b-tooltip.hover
class="px-1"
title="Error"
title="错误"
size="sm"
variant="link"
:href="reportErrorUrl"
......@@ -113,7 +113,7 @@ function onRerun() {
v-if="showDownloads"
v-b-tooltip.hover
class="px-1"
title="Copy Link"
title="复制链接"
size="sm"
variant="link"
@click.stop="onCopyLink">
......@@ -124,7 +124,7 @@ function onRerun() {
v-if="showInfo"
v-b-tooltip.hover
class="info-btn px-1"
title="Dataset Details"
title="数据集详情"
size="sm"
variant="link"
:href="showDetailsUrl"
......@@ -136,7 +136,7 @@ function onRerun() {
v-if="showVisualizations"
v-b-tooltip.hover
class="visualize-btn px-1"
title="Visualize"
title="可视化"
size="sm"
variant="link"
:href="visualizeUrl"
......@@ -148,7 +148,7 @@ function onRerun() {
v-if="showHighlight"
v-b-tooltip.hover
class="highlight-btn px-1"
title="Show Related Items"
title="显示相关项目"
size="sm"
variant="link"
@click.stop="onHighlight">
......@@ -159,7 +159,7 @@ function onRerun() {
v-if="writable && showRerun"
v-b-tooltip.hover
class="rerun-btn px-1"
title="Run Job Again"
title="重新运行作业"
size="sm"
variant="link"
:href="rerunUrl"
......
......@@ -60,7 +60,7 @@ function onDownload(resource: string, extension = "") {
:data-description="`download ${metaFile.file_type}`"
:href="metaDownloadUrl + metaFile.file_type"
@click.prevent.stop="onDownload(metaDownloadUrl, metaFile.file_type)">
Download {{ metaFile.file_type }}
下载 {{ metaFile.file_type }}
</BDropdownItem>
</BDropdown>
......@@ -68,7 +68,7 @@ function onDownload(resource: string, extension = "") {
v-else
v-b-tooltip.hover
class="download-btn px-1"
title="Download"
title="下载"
size="sm"
variant="link"
:href="downloadUrl"
......
......@@ -37,26 +37,20 @@ function showHelp() {
<template>
<div class="info">
<b-modal v-if="sharingError" v-model="showErrorHelp" title="Dataset Sharing Misconfigured" ok-only>
<b-modal v-if="sharingError" v-model="showErrorHelp" title="数据集共享配置错误" ok-only>
<p>
This error message indicates that your history is setup to allow sharing but your job was run in a
configuration to target a Galaxy storage that explicitly disables sharing.
此错误消息表示您的历史记录设置为允许共享,但您的作业运行在目标 Galaxy 存储显式禁用共享的配置下。
</p>
<p>
To fix this configure your history so that new datasets are private or target a different storage
location.
要修复此问题,请将历史记录配置为新数据集为私有,或指定不同的存储位置。
</p>
<p>
To re-configure your history, click the history menu and go to the "Set Permissions" option in the
dropdown. This should result in a toggle that allows you to configure the history so that new datasets
are created as private datasets.
要重新配置历史记录,请点击历史记录菜单,在下拉菜单中选择“设置权限”选项。这应出现一个开关,允许您将历史记录配置为将新数据集创建为私有数据集。
</p>
<p>
There are many ways to instead target different storage for your job. This can be selected in the tool
or workflow form right before you execute your job or a different default for your history or user can
be chosen that allows for sharing.
有多种方式可以为您的作业指定不同的存储。您可以在执行作业前的工具或工作流表单中选择,或为历史记录或用户选择允许共享的不同默认值。
</p>
</b-modal>
<span class="value">{{ miscInfo }} <a v-if="fixable" href="#" @click="showHelp">How do I fix this?</a></span>
<span class="value">{{ miscInfo }} <a v-if="fixable" href="#" @click="showHelp">如何修复此问题?</a></span>
</div>
</template>
......@@ -6,7 +6,7 @@
v-slot="{ result: item, loading }"
:view="view"
auto-refresh>
<LoadingSpan v-if="loading" message="Loading dataset" />
<LoadingSpan v-if="loading" message="正在加载数据集" />
<div v-else>
<ContentItem
:id="item.hid ?? item.element_index + 1"
......
......@@ -421,7 +421,7 @@ const {
:key="props.history.id"
class="content-operations-filters mx-3"
name="History Items"
placeholder="search datasets"
placeholder="搜索数据集"
:filter-class="filterClass"
:filter-text.sync="filterText"
:loading="isLoading"
......@@ -489,22 +489,22 @@ const {
<div class="h-100">
<div v-if="isLoading && historyItems && historyItems.length === 0">
<BAlert class="m-2" variant="info" show>
<LoadingSpan message="Loading History" />
<LoadingSpan message="正在加载历史记录" />
</BAlert>
</div>
<BAlert v-else-if="isProcessing" class="m-2" variant="info" show>
<LoadingSpan message="Processing operation" />
<LoadingSpan message="正在处理操作" />
</BAlert>
<div v-else-if="historyItems.length === 0">
<HistoryEmpty v-if="queryDefault" :writable="canEditHistory" class="m-2" />
<BAlert v-else-if="formattedSearchError" class="m-2" variant="danger" show>
Error in filter:
筛选出错:
<a href="javascript:void(0)" @click="showAdvanced = true">
{{ formattedSearchError.filter }}'{{ formattedSearchError.value }}'
</a>
</BAlert>
<BAlert v-else class="m-2" variant="info" show> No data found for selected filter. </BAlert>
<BAlert v-else class="m-2" variant="info" show> 所选筛选条件下未找到数据。 </BAlert>
</div>
<ListingLayout
v-else
......
......@@ -194,7 +194,7 @@ function downloadFromRecord(record: ExportRecord) {
function copyDownloadLinkFromRecord(record: ExportRecord) {
if (record.canDownload) {
const relativeLink = getDownloadObjectUrl(record.stsDownloadId!);
sendToClipboard(absPath(relativeLink), "Download link copied to your clipboard");
sendToClipboard(absPath(relativeLink), "下载链接已复制到剪贴板");
}
}
......@@ -206,8 +206,7 @@ async function reimportFromRecord(record: ExportRecord) {
try {
await reimportHistoryFromRecord(record);
actionMessageVariant.value = "info";
actionMessage.value =
"The history is being imported in the background. Check your histories after a while to find it.";
actionMessage.value = "历史记录正在后台导入。请稍后在您的历史记录中查找它。";
} catch (error) {
actionMessageVariant.value = "danger";
actionMessage.value = errorMessageAsString(error);
......@@ -236,7 +235,7 @@ const breadcrumbItems = computed(() => [
to: `/histories/view?id=${props.historyId}`,
superText: historyStore.currentHistoryId === props.historyId ? "current" : undefined,
},
{ title: "Export", icon: faFileExport },
{ title: "导出", icon: faFileExport },
]);
</script>
......@@ -287,7 +286,7 @@ const breadcrumbItems = computed(() => [
<GModal
:show.sync="showOldRecords"
:title="`Previous Export Records for ${historyName}`"
:title="`${historyName} 的先前导出记录`"
size="medium"
hide-header
fixed-height
......
......@@ -81,20 +81,20 @@ const emit = defineEmits<{
const errorMessage = ref<string>();
const exportData: HistoryExportData = reactive(initializeExportData());
const defaultFileName = computed(() => `(Galaxy History) ${props.historyName}`);
const defaultFileName = computed(() => `(Galaxy 历史记录) ${props.historyName}`);
const exportButtonLabel = computed(() => {
switch (exportData.destination) {
case "download":
return "Generate Download Link";
return "生成下载链接";
case "remote-source":
return "Export to Remote Source";
return "导出到远程源";
case "rdm-repository":
return "Export to RDM Repository";
return "导出到 RDM 仓库";
case "zenodo-repository":
return "Export to Zenodo";
return "导出到 Zenodo";
default:
return "Export";
return "导出";
}
});
......@@ -126,42 +126,42 @@ const zenodoSource = computed(() => getZenodoSource());
const wizard = useWizard({
"select-format": {
label: "Select output format",
label: "选择输出格式",
instructions: computed(() => {
return `Select the format you would like to export the ${resource} to and click Next to continue.`;
return `选择要将 ${resource} 导出成的格式,然后点击下一步继续。`;
}),
isValid: () => true,
isSkippable: () => false,
},
"select-destination": {
label: "Select destination",
label: "选择目的地",
instructions: computed(() => {
return `Select where you would like to export the ${resource} ${exportFormatName.value} to and click Next to continue.`;
return `选择要将 ${resource} ${exportFormatName.value} 导出到的位置,然后点击下一步继续。`;
}),
isValid: () => true,
isSkippable: () => false,
},
"setup-remote": {
label: "Select remote source",
instructions: "Select remote source directory",
label: "选择远程源",
instructions: "选择远程源目录",
isValid: () => Boolean(exportData.remoteUri),
isSkippable: () => exportData.destination !== "remote-source",
},
"setup-rdm": {
label: "Select RDM repository",
instructions: "Select RDM repository and provide a draft record to export to",
label: "选择 RDM 仓库",
instructions: "选择 RDM 仓库并提供用于导出的草稿记录",
isValid: () => Boolean(exportData.remoteUri),
isSkippable: () => exportData.destination !== "rdm-repository",
},
"setup-zenodo": {
label: "Select draft record",
instructions: "Select or create a draft record to export to",
label: "选择草稿记录",
instructions: "选择或创建一个用于导出的草稿记录",
isValid: () => Boolean(exportData.remoteUri),
isSkippable: () => exportData.destination !== "zenodo-repository",
},
"export-summary": {
label: "Export",
instructions: "Summary",
label: "导出",
instructions: "摘要",
isValid: () => Boolean(exportData.outputFileName) || exportData.destination === "download",
isSkippable: () => false,
},
......@@ -201,31 +201,31 @@ function initializeExportDestinations(): ExportDestinationInfo[] {
const destinations: ExportDestinationInfo[] = [
{
destination: "download",
label: "Temporary Direct Download",
markdownDescription: `Generate a link to the export file and download it directly to your computer.
label: "临时直接下载",
markdownDescription: `生成导出文件的链接并直接下载到您的计算机。
**Please note that the link will expire after 24 hours.**`,
**请注意,链接将在 24 小时后过期。**`,
},
];
if (hasWritableFileSources.value) {
destinations.push({
destination: "remote-source",
label: "Repository",
markdownDescription: `If you need a **more permanent** way of storing your ${resource} you can export it directly to one of the available repositories. You will be able to re-import it later as long as it remains available on the remote server.
label: "仓库",
markdownDescription: `如果您需要**更持久**的方式来存储 ${resource},可以将其直接导出到可用的仓库之一。只要在远程服务器上仍可用,您之后就可以重新导入它。
Examples of remote sources include Amazon S3, Azure Storage, Google Drive... and other public or personal file sources that you have setup access to.`,
远程源的示例包括 Amazon S3、Azure 存储、Google Drive……以及您已配置访问权限的其他公共或个人文件源。`,
});
}
if (hasWritableRDMFileSources.value) {
destinations.push({
destination: "rdm-repository",
label: "RDM Repository",
markdownDescription: `You can upload your ${resource} to one of the available **Research Data Management repositories** here.
This will allow you to easily associate your ${resource} with your research project or publication.
label: "RDM 仓库",
markdownDescription: `您可以在此将 ${resource} 上传到可用的**研究数据管理仓库**之一。
这样您可以轻松地将 ${resource} 与您的研究项目或出版物关联。
Examples of RDM repositories include [Invenio RDM](https://inveniosoftware.org/products/rdm/) instances, [RSpace](https://www.researchspace.com/), and other public or personal repositories that you have setup access to.`,
RDM 仓库的示例包括 [Invenio RDM](https://inveniosoftware.org/products/rdm/) 实例、[RSpace](https://www.researchspace.com/),以及您已配置访问权限的其他公共或个人仓库。`,
});
}
......@@ -235,7 +235,7 @@ Examples of RDM repositories include [Invenio RDM](https://inveniosoftware.org/p
label: `${zenodoSource.value.label}`,
markdownDescription: `![Zenodo Logo](https://raw.githubusercontent.com/zenodo/zenodo/master/zenodo/modules/theme/static/img/logos/zenodo-gradient-square.svg)
[Zenodo](https://zenodo.org/) is a general-purpose open repository developed under the [European OpenAIRE](https://www.openaire.eu/) program and operated by [CERN](https://home.cern/). It allows researchers to deposit research papers, data sets, research software, reports, and any other research related digital artefacts. For each submission, a persistent **digital object identifier (DOI)** is minted, which makes the stored items easily citeable.`,
[Zenodo](https://zenodo.org/) 是在 [European OpenAIRE](https://www.openaire.eu/) 计划下开发、由 [CERN](https://home.cern/) 运营的通用开放仓库。它允许研究人员存放研究论文、数据集、研究软件、报告以及任何其他与研究相关的数字制品。每次提交都会生成持久的**数字对象标识符(DOI)**,使存储的项目易于引用。`,
});
}
......@@ -332,7 +332,7 @@ function resetWizard() {
<BFormGroup
v-if="needsFileName"
label-for="exported-file-name"
:description="`Give the exported file a name.`"
:description="`为导出的文件命名。`"
class="mt-3">
<BFormInput
id="exported-file-name"
......@@ -352,11 +352,11 @@ function resetWizard() {
<br />
<div>
Format <b>{{ exportFormatName }}</b>
格式 <b>{{ exportFormatName }}</b>
</div>
<div>
Destination
目的地
<b>{{ exportDestinationSummary }}</b>
<b v-if="exportData.destination !== 'download' && exportData.remoteUri">
<FileSourceNameSpan :uri="exportData.remoteUri" class="text-primary" />
......@@ -364,7 +364,7 @@ function resetWizard() {
</div>
<div v-if="needsFileName && exportData.outputFileName">
File Name <b>{{ exportData.outputFileName }}.{{ exportData.modelStoreFormat }}</b>
文件名 <b>{{ exportData.outputFileName }}.{{ exportData.modelStoreFormat }}</b>
</div>
</div>
</GenericWizard>
......
......@@ -70,7 +70,7 @@ async function getCounts() {
contentsActive.value = counts.contents_active;
contentsStates.value = counts.contents_states;
} catch (e) {
Toast.error(`Failed to load history counts: ${errorMessageAsString(e)}`);
Toast.error(`无法加载历史记录统计:${errorMessageAsString(e)}`);
} finally {
loading.value = false;
}
......@@ -86,14 +86,14 @@ onMounted(async () => {
v-b-tooltip.hover.top.noninteractive
class="history-datasets d-flex flex-gapx-1 flex-gapy-1 align-items-center outline-badge cursor-pointer font-size-small"
pill
:title="`View history storage overview`"
:title="`查看历史记录存储概览`"
variant="light"
:to="`/storage/history/${historyId}`">
<FontAwesomeIcon v-if="loading" :icon="faSpinner" fixed-width spin />
<template v-else>
<small v-if="props.count">
<FontAwesomeIcon :icon="faDatabase" fixed-width />
<template v-if="props.count"> {{ props.count }} <span class="items">items</span> </template>
<template v-if="props.count"> {{ props.count }} <span class="items">项</span> </template>
</small>
<template v-if="props.count && niceSize"> | </template>
......
......@@ -82,7 +82,7 @@ const props = withDefaults(defineProps<Props>(), {
activeList: "my",
});
const breadcrumbItems = [{ title: "Histories", to: "/histories/list" }];
const breadcrumbItems = [{ title: "历史记录", to: "/histories/list" }];
const router = useRouter();
const userStore = useUserStore();
......@@ -117,19 +117,19 @@ const archivedView = computed(() => props.activeList === "archived");
* @returns {string} Contextual placeholder text for the search input
*/
const searchPlaceHolder = computed(() => {
let placeHolder = "Search my histories";
let placeHolder = "搜索我的历史记录";
if (sharedView.value) {
placeHolder = "Search shared histories";
placeHolder = "搜索与我共享的历史记录";
}
if (publishedView.value) {
placeHolder = "Search published histories";
placeHolder = "搜索公开的历史记录";
}
if (archivedView.value) {
placeHolder = "Search archived histories";
placeHolder = "搜索已归档的历史记录";
}
placeHolder += " by query or use the advanced filtering options";
placeHolder += ",可按条件查询或使用高级筛选选项";
return placeHolder;
});
......@@ -141,7 +141,7 @@ const sortDesc = computed(() => (listHeader.value && listHeader.value.sortDesc)
const sortBy = computed(() => (listHeader.value && listHeader.value.sortBy) || "update_time");
const noItems = computed(() => !loading.value && historiesLoaded.value.length === 0 && !filterText.value);
const noResults = computed(() => !loading.value && historiesLoaded.value.length === 0 && Boolean(filterText.value));
const deleteButtonTitle = computed(() => (showDeleted.value ? "Hide deleted histories" : "Show deleted histories"));
const deleteButtonTitle = computed(() => (showDeleted.value ? "隐藏已删除的历史记录" : "显示已删除的历史记录"));
const showBulkPurge = computed(() => selectedHistories.value.some((h) => !h.purged));
const showBulkMultiview = computed(() => selectedHistories.value.length > 1);
......@@ -265,7 +265,7 @@ async function load(overlayLoading: boolean = false, silent: boolean = false) {
totalHistories.value = total;
}
} catch (error) {
Toast.error(`Failed to load histories: ${errorMessageAsString(error)}`);
Toast.error(`无法加载历史记录:${errorMessageAsString(error)}`);
} finally {
loading.value = false;
overlay.value = false;
......@@ -327,12 +327,12 @@ async function onBulkDeleteOrPurge(purge: boolean = false) {
const hasPublished = selectedHistories.value.some((h) => h.published);
const confirmed = await confirm(
`${hasPublished ? "Some of the selected histories are published and will be removed from public view. " : ""}
Are you sure you want to ${purge ? "purge" : "delete"} ${totalSelected} histories?`,
`${hasPublished ? "所选历史记录中部分已公开,将从公共视图移除。 " : ""}
确定要${purge ? "永久删除" : "删除"} ${totalSelected} 个历史记录吗?`,
{
id: "bulk-delete-histories",
title: purge ? "Purge histories" : "Delete histories",
okTitle: purge ? "Purge histories" : "Delete histories",
title: purge ? "永久删除历史记录" : "删除历史记录",
okTitle: purge ? "永久删除历史记录" : "删除历史记录",
okVariant: "danger",
cancelVariant: "outline-primary",
centered: true,
......@@ -360,11 +360,11 @@ async function onBulkDeleteOrPurge(purge: boolean = false) {
);
}
Toast.success(`${purge ? "Purged" : "Deleted"} ${totalSelected} histories.`);
Toast.success(`${purge ? "已永久删除" : "已删除"} ${totalSelected} 个历史记录。`);
resetSelection();
} catch (e) {
Toast.error(`Failed to ${purge ? "purge" : "delete"} some histories.`);
Toast.error(`无法${purge ? "永久删除" : "删除"}部分历史记录。`);
} finally {
bulkPurgeLoading.value = false;
bulkDeleteOrRestoreLoading.value = false;
......@@ -381,10 +381,10 @@ async function onBulkDeleteOrPurge(purge: boolean = false) {
async function onBulkRestore() {
const totalSelected = selectedHistories.value.length;
const confirmed = await confirm(`Are you sure you want to restore ${totalSelected} histories?`, {
const confirmed = await confirm(`确定要恢复 ${totalSelected} 个历史记录吗?`, {
id: "bulk-restore-histories",
title: "Restore histories",
okTitle: "Restore histories",
title: "恢复历史记录",
okTitle: "恢复历史记录",
okVariant: "primary",
cancelVariant: "outline-primary",
centered: true,
......@@ -449,9 +449,9 @@ async function onBulkTagsAdd(tags: string[]) {
);
}
Toast.success(`Added tag(s) to ${totalSelected} histories.`);
Toast.success(`已为 ${totalSelected} 个历史记录添加标签。`);
} catch (e) {
Toast.error(`Failed to add tag(s) to some histories. ${e}`);
Toast.error(`无法为部分历史记录添加标签。 ${e}`);
} finally {
bulkTagsLoading.value = false;
......@@ -474,13 +474,13 @@ async function onBulkOpenInMultiview() {
if (selectedHistoriesCount > MULTIVIEW_MAX_HISTORIES) {
const confirmed = await confirm(
`You have selected ${selectedHistoriesCount} histories to open in multiview.
However, the maximum number of histories allowed in multiview is ${MULTIVIEW_MAX_HISTORIES}.
Do you want to proceed with opening the first ${MULTIVIEW_MAX_HISTORIES} histories?`,
`您已选择 ${selectedHistoriesCount} 个历史记录在多视图面板中打开。
但是,多视图面板最多允许 ${MULTIVIEW_MAX_HISTORIES} 个历史记录。
是否继续打开前 ${MULTIVIEW_MAX_HISTORIES} 个历史记录?`,
{
id: "bulk-open-multiview-histories",
title: `You can only open ${MULTIVIEW_MAX_HISTORIES} histories in multiview`,
okTitle: "Proceed",
title: `在多视图面板中最多只能打开 ${MULTIVIEW_MAX_HISTORIES} 个历史记录`,
okTitle: "继续",
okVariant: "primary",
cancelVariant: "outline-primary",
centered: true,
......@@ -503,9 +503,7 @@ async function onBulkOpenInMultiview() {
resetSelection();
Toast.success(
`Opened ${totalSelectedHistories} ${totalSelectedHistories === 1 ? "history" : "histories"} in multiview.`,
);
Toast.success(`已${totalSelectedHistories === 1 ? "在" : "在"}多视图面板中打开 ${totalSelectedHistories} 个历史记录。`);
}
/**
......@@ -541,50 +539,50 @@ onMounted(async () => {
to="/histories/import"
data-description="header action import new history">
<FontAwesomeIcon :icon="faPlus" />
Import History
导入历史记录
</GButton>
</BreadcrumbHeading>
<BNav pills justified class="mb-2">
<BNavItem id="histories-my-tab" :active="myView" :disabled="userStore.isAnonymous" to="/histories/list">
My Histories
我的历史记录
<LoginRequired
v-if="userStore.isAnonymous"
target="histories-my-tab"
title="Manage your Histories" />
title="管理您的历史记录" />
</BNavItem>
<BNavItem
id="histories-shared-tab"
:active="sharedView"
:disabled="userStore.isAnonymous"
to="/histories/list_shared">
Histories Shared with Me
与我共享的历史记录
<LoginRequired
v-if="userStore.isAnonymous"
target="histories-shared-tab"
title="View Shared Histories" />
title="查看共享的历史记录" />
</BNavItem>
<BNavItem
id="histories-published-tab"
:active="publishedView"
:disabled="userStore.isAnonymous"
to="/histories/list_published">
Public Histories
公开历史记录
<LoginRequired
v-if="userStore.isAnonymous"
target="histories-published-tab"
title="View Published Histories" />
title="查看公开的历史记录" />
</BNavItem>
<BNavItem
id="histories-archived-tab"
:active="archivedView"
:disabled="userStore.isAnonymous"
to="/histories/archived">
Archived Histories
已归档历史记录
<LoginRequired
v-if="userStore.isAnonymous"
target="histories-archived-tab"
title="View Archived Histories" />
title="查看已归档的历史记录" />
</BNavItem>
</BNav>
......@@ -612,7 +610,7 @@ onMounted(async () => {
@select-all="onSelectAllHistories">
<template v-slot:extra-filter>
<div v-if="activeList === 'my'">
Filter:
筛选:
<BButton
id="show-deleted"
v-b-tooltip.hover
......@@ -622,7 +620,7 @@ onMounted(async () => {
variant="outline-primary"
@click="onToggleDeleted">
<FontAwesomeIcon :icon="faTrash" fixed-width />
Show deleted
显示已删除
</BButton>
</div>
</template>
......@@ -631,17 +629,17 @@ onMounted(async () => {
<div v-if="loading" class="h-100">
<BAlert variant="info" show>
<LoadingSpan message="Loading histories" />
<LoadingSpan message="正在加载历史记录" />
</BAlert>
</div>
<div v-else-if="!loading && !overlay && noItems" class="h-100">
<BAlert id="history-list-empty" variant="info" show>
No histories found. You may create or import new histories using the buttons above.
未找到历史记录。您可以使用上方按钮创建或导入新的历史记录。
</BAlert>
</div>
<span v-else-if="!loading && !overlay && (noResults || hasInvalidFilters)" class="h-100">
<BAlert v-if="!hasInvalidFilters" id="no-history-found" variant="info" show>
No histories found matching: <span class="font-weight-bold">{{ filterText }}</span>
未找到匹配的历史记录:<span class="font-weight-bold">{{ filterText }}</span>
</BAlert>
<BAlert v-else id="no-history-found-invalid" variant="danger" show>
......@@ -652,13 +650,13 @@ onMounted(async () => {
: {{ value }}
</li>
</ul>
<GLink @click="filterText = validatedFilterText()"> Remove invalid filters from query </GLink>
or
<GLink @click="filterText = validatedFilterText()"> 从查询中移除无效筛选 </GLink>
或
<GLink
title="Note that this might produce inaccurate results"
title="请注意,这可能会产生不准确的结果"
tooltip
@click="filterText = `'${filterText}'`">
Match the exact query provided
精确匹配所提供的内容
</GLink>
</BAlert>
</span>
......@@ -692,75 +690,75 @@ onMounted(async () => {
v-if="!showDeleted"
id="history-list-footer-bulk-delete-button"
v-b-tooltip.hover
:title="bulkDeleteOrRestoreLoading ? 'Deleting histories' : 'Delete selected histories'"
:title="bulkDeleteOrRestoreLoading ? '正在删除历史记录' : '删除选中的历史记录'"
:disabled="bulkDeleteOrRestoreLoading"
size="sm"
variant="primary"
@click="() => onBulkDeleteOrPurge()">
<span v-if="!bulkDeleteOrRestoreLoading">
<FontAwesomeIcon :icon="faTrash" fixed-width />
Delete ({{ selectedHistories.length }})
删除({{ selectedHistories.length }})
</span>
<LoadingSpan v-else message="Deleting" />
<LoadingSpan v-else message="正在删除" />
</BButton>
<BButton
v-else
id="history-list-footer-bulk-restore-button"
v-b-tooltip.hover
:title="bulkDeleteOrRestoreLoading ? 'Restoring histories' : 'Restore selected histories'"
:title="bulkDeleteOrRestoreLoading ? '正在恢复历史记录' : '恢复选中的历史记录'"
:disabled="bulkDeleteOrRestoreLoading"
size="sm"
variant="primary"
@click="onBulkRestore">
<span v-if="!bulkDeleteOrRestoreLoading">
<FontAwesomeIcon :icon="faTrashRestore" fixed-width />
Restore ({{ selectedHistories.length }})
恢复({{ selectedHistories.length }})
</span>
<LoadingSpan v-else message="Restoring" />
<LoadingSpan v-else message="正在恢复" />
</BButton>
<BButton
v-if="showBulkPurge"
id="history-list-footer-bulk-purge-button"
v-b-tooltip.hover
:title="bulkPurgeLoading ? 'Purging histories' : 'Purge selected histories'"
:title="bulkPurgeLoading ? '正在永久删除历史记录' : '永久删除选中的历史记录'"
:disabled="bulkPurgeLoading"
size="sm"
variant="primary"
@click="() => onBulkDeleteOrPurge(true)">
<span v-if="!bulkPurgeLoading">
<FontAwesomeIcon :icon="faBurn" fixed-width />
Purge ({{ selectedHistories.length }})
永久删除({{ selectedHistories.length }})
</span>
<LoadingSpan v-else message="Purging" />
<LoadingSpan v-else message="正在永久删除" />
</BButton>
<BButton
v-if="!showDeleted"
id="history-list-footer-bulk-add-tags-button"
v-b-tooltip.hover
:title="bulkTagsLoading ? 'Adding tags' : 'Add tags to selected histories'"
:title="bulkTagsLoading ? '正在添加标签' : '为选中的历史记录添加标签'"
:disabled="bulkTagsLoading"
size="sm"
variant="primary"
@click="onToggleBulkTags">
<span v-if="!bulkTagsLoading">
<FontAwesomeIcon :icon="faTags" fixed-width />
Add tags ({{ selectedHistories.length }})
添加标签({{ selectedHistories.length }})
</span>
<LoadingSpan v-else message="Adding tags" />
<LoadingSpan v-else message="正在添加标签" />
</BButton>
<BButton
v-if="showBulkMultiview"
id="history-list-footer-bulk-open-multiview-button"
v-b-tooltip.hover
title="Open selected histories in multiview"
title="在多视图面板中打开选中的历史记录"
size="sm"
variant="primary"
@click="onBulkOpenInMultiview">
<FontAwesomeIcon :icon="faColumns" fixed-width />
Open in Multiview ({{ selectedHistories.length }})
在多视图面板中打开({{ selectedHistories.length }})
</BButton>
</div>
......@@ -778,9 +776,7 @@ onMounted(async () => {
<TagsSelectionDialog
:show="showBulkAddTagsModal"
:title="`Add tags to ${selectedHistories.length} selected history${
selectedHistories.length > 1 ? 's' : ''
}`"
:title="`为 ${selectedHistories.length} 个选中的历史记录添加标签`"
@cancel="onToggleBulkTags"
@ok="onBulkTagsAdd" />
</div>
......
......@@ -112,7 +112,7 @@ function onDelete() {
:variant="props.minimal ? 'outline-info' : 'link'"
toggle-class="text-decoration-none"
menu-class="history-options-button-menu"
title="History options"
title="历史选项"
right
data-description="history options">
<template v-slot:button-content>
......@@ -121,8 +121,8 @@ function onDelete() {
</template>
<BDropdownText>
<LoadingSpan v-if="historiesLoading" message="Fetching histories from server" />
<span v-else-if="!props.minimal">You have {{ totalHistoryCount }} histories.</span>
<LoadingSpan v-if="historiesLoading" message="正在从服务器获取历史记录" />
<span v-else-if="!props.minimal">您共有 {{ totalHistoryCount }} 个历史记录。</span>
<span v-else>管理历史</span>
</BDropdownText>
......@@ -139,8 +139,8 @@ function onDelete() {
<BDropdownDivider v-if="!props.minimal" />
<BDropdownText v-if="!canEditHistory">
This history has been <span class="font-weight-bold">{{ historyState }}</span
>.
该历史记录已被 <span class="font-weight-bold">{{ historyState }}</span
>。
<span v-localize>某些操作可能不可用。</span>
</BDropdownText>
......@@ -233,7 +233,7 @@ function onDelete() {
:title="userTitle('Share, Publish, or Set Permissions for this History')"
:to="`/histories/sharing?id=${history.id}`">
<FontAwesomeIcon fixed-width :icon="faUsersCog" />
<span v-localize>Share & Manage Access</span>
<span v-localize>共享并管理访问权限</span>
</BDropdownItem>
</BDropdown>
......@@ -242,15 +242,15 @@ function onDelete() {
<BModal
v-model="showDeleteModal"
centered
:title="isDeletedNotPurged ? 'Permanently Delete History?' : 'Delete History?'"
:title="isDeletedNotPurged ? '永久删除历史记录?' : '删除历史记录?'"
title-tag="h2"
:ok-title="isDeletedNotPurged ? 'Permanently Delete' : 'Delete'"
:ok-title="isDeletedNotPurged ? '永久删除' : '删除'"
ok-variant="danger"
cancel-variant="outline-primary"
@ok="onDelete"
@show="purgeHistory = isDeletedNotPurged">
<p v-localize>
Do you also want to permanently delete the history <i class="ml-1">{{ history.name }}</i>
<p>
是否也要永久删除历史记录 <i class="ml-1">{{ history.name }}</i>
</p>
<BFormCheckbox id="purge-history" v-model="purgeHistory" :disabled="isDeletedNotPurged">
......
......@@ -9,17 +9,17 @@
:disabled="isSetAsCurrentDisabled"
data-description="switch to history button"
@click="setCurrentHistory(history.id)">
Switch to this history
切换到该历史记录
</GButton>
<GButton
v-if="canImportHistory"
v-b-modal:copy-history-modal
color="blue"
title="Import this history"
title="导入此历史记录"
data-description="import history button">
<FontAwesomeIcon :icon="faFileImport" />
Import this history
导入此历史记录
</GButton>
<HistoryOptions :history="history" minimal />
......@@ -27,7 +27,7 @@
</BreadcrumbHeading>
<b-alert :show="copySuccess">
History imported and is now your active history. <b-link :to="importedHistoryLink">在此查看</b-link>.
历史记录已导入,现为您的活动历史。<b-link :to="importedHistoryLink">在此查看</b-link>。
</b-alert>
<CollectionPanel
......@@ -86,11 +86,11 @@ export default {
...mapState(useHistoryStore, ["getHistoryById", "currentHistory"]),
breadcrumbItems() {
return [
{ title: "Histories", to: "/histories/list" },
{ title: "历史记录", to: "/histories/list" },
{
title: this.history.name,
to: `/histories/view?id=${this.history.id}`,
superText: this.isCurrentHistory ? "current" : undefined,
superText: this.isCurrentHistory ? "当前" : undefined,
},
];
},
......@@ -108,9 +108,9 @@ export default {
},
setAsCurrentTitle() {
if (this.isCurrentHistory) {
return "This history is already your current history.";
return "此历史记录已经是您的当前历史。";
}
return "Switch to this history";
return "切换到该历史记录";
},
canImportHistory() {
return !this.userOwnsHistory && !this.history.purged;
......
......@@ -91,9 +91,9 @@ export function useHistoryCardActions(
try {
await historyStore.restoreHistory(history.value.id);
refreshCallBack();
Toast.success("History restored");
Toast.success("历史记录已恢复");
} catch (e) {
Toast.error(`Failed to restore history: ${errorMessageAsString(e)}`);
Toast.error(`无法恢复历史记录:${errorMessageAsString(e)}`);
}
}
......@@ -287,9 +287,9 @@ export function useHistoryCardActions(
(isMyHistory(history.value) || archivedView) && historyStore.currentHistoryId !== history.value.id,
},
{
title: "current history",
title: "当前历史记录",
id: "current",
label: "Current",
label: "当前",
variant: "outline-primary",
disabled: true,
visible:
......
......@@ -327,7 +327,7 @@ class QueryRouterAgent(BaseGalaxyAgent):
try:
dataset = target.dataset
object_store = app.object_store
max_lines = int(self._get_agent_config("max_dataset_preview_lines", 200))
max_lines = int(self._get_agent_config("max_dataset_preview_lines", 1000))
raw = object_store.get_data(dataset, start=0, count=max_lines)
text = raw if isinstance(raw, str) else (raw.decode("utf-8", errors="replace") if raw else "")
return text.strip() or "(数据集为空)"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment