From ca4a1bb2de4b47e6d1cb5bf30df3f7193d1971c8 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 15 Jul 2021 13:42:06 +0200 Subject: [PATCH] Update workflow instances view with localization keys --- .../elsa-workflows-studio/src/components.d.ts | 6 ++ .../controls/elsa-pager/elsa-pager.tsx | 25 ++++--- .../controls/elsa-pager/localizations.ts | 24 +++++++ .../elsa-studio-workflow-instances-list.tsx | 3 +- .../elsa-workflow-instance-list-screen.tsx | 68 +++++++++++------- .../localizations.ts | 70 +++++++++++++++++++ 6 files changed, 159 insertions(+), 37 deletions(-) create mode 100644 src/designer/elsa-workflows-studio/src/components/controls/elsa-pager/localizations.ts create mode 100644 src/designer/elsa-workflows-studio/src/components/screens/workflow-instance-list/elsa-workflow-instance-list-screen/localizations.ts diff --git a/src/designer/elsa-workflows-studio/src/components.d.ts b/src/designer/elsa-workflows-studio/src/components.d.ts index 4f75557cd..992d6a0af 100644 --- a/src/designer/elsa-workflows-studio/src/components.d.ts +++ b/src/designer/elsa-workflows-studio/src/components.d.ts @@ -128,6 +128,7 @@ export namespace Components { "serverUrl": string; } interface ElsaPager { + "culture": string; "history"?: RouterHistory; "location": LocationSegments; "page": number; @@ -195,6 +196,7 @@ export namespace Components { "serverUrl": string; } interface ElsaStudioWorkflowInstancesList { + "culture": string; "history": RouterHistory; "serverUrl": string; } @@ -261,6 +263,7 @@ export namespace Components { "workflowModel": WorkflowModel; } interface ElsaWorkflowInstanceListScreen { + "culture": string; "history"?: RouterHistory; "orderBy"?: OrderBy; "serverUrl": string; @@ -748,6 +751,7 @@ declare namespace LocalJSX { "serverUrl"?: string; } interface ElsaPager { + "culture"?: string; "history"?: RouterHistory; "location"?: LocationSegments; "onPaged"?: (event: CustomEvent) => void; @@ -817,6 +821,7 @@ declare namespace LocalJSX { "serverUrl"?: string; } interface ElsaStudioWorkflowInstancesList { + "culture"?: string; "history"?: RouterHistory; "serverUrl"?: string; } @@ -873,6 +878,7 @@ declare namespace LocalJSX { "workflowModel"?: WorkflowModel; } interface ElsaWorkflowInstanceListScreen { + "culture"?: string; "history"?: RouterHistory; "orderBy"?: OrderBy; "serverUrl"?: string; diff --git a/src/designer/elsa-workflows-studio/src/components/controls/elsa-pager/elsa-pager.tsx b/src/designer/elsa-workflows-studio/src/components/controls/elsa-pager/elsa-pager.tsx index c754efd85..58522e8ea 100644 --- a/src/designer/elsa-workflows-studio/src/components/controls/elsa-pager/elsa-pager.tsx +++ b/src/designer/elsa-workflows-studio/src/components/controls/elsa-pager/elsa-pager.tsx @@ -1,6 +1,10 @@ import {Component, Event, EventEmitter, h, Prop} from '@stencil/core'; import {LocationSegments, RouterHistory, injectHistory} from "@stencil/router"; import {parseQuery, queryToString} from "../../../utils/utils"; +import {i18n} from "i18next"; +import {resources} from "./localizations"; +import {loadTranslations} from "../../i18n/i18n-loader"; +import {GetIntlMessage} from "../../i18n/intl-message"; export interface PagerData { page: number; @@ -19,15 +23,20 @@ export class ElsaPager { @Prop() totalCount: number; @Prop() location: LocationSegments; @Prop() history?: RouterHistory; + @Prop() culture: string; @Event() paged: EventEmitter + i18next: i18n; basePath: string; - componentWillLoad() { + async componentWillLoad() { + this.i18next = await loadTranslations(this.culture, resources); this.basePath = !!this.location ? this.location.pathname : document.location.pathname; } + t = (key: string, options?: any) => this.i18next.t(key, options); + navigate(path: string, page: number) { if (this.history) { @@ -61,6 +70,8 @@ export class ElsaPager { const toPage = Math.min(pageCount, fromPage + maxPageButtons); const self = this; const currentQuery = !!this.history ? parseQuery(this.history.location.search) : {page, pageSize}; + const t = this.t; + const IntlMessage = GetIntlMessage(this.i18next); currentQuery['pageSize'] = pageSize; @@ -76,7 +87,7 @@ export class ElsaPager { return self.onNavigateClick(e, page - 1)} class="elsa-relative elsa-inline-flex elsa-items-center elsa-px-4 elsa-py-2 elsa-border elsa-border-gray-300 elsa-text-sm elsa-leading-5 elsa-font-medium elsa-rounded-md elsa-text-gray-700 elsa-bg-white hover:elsa-text-gray-500 focus:elsa-outline-none focus:elsa-shadow-outline-blue focus:elsa-border-blue-300 active:elsa-bg-gray-100 active:elsa-text-gray-700 elsa-transition elsa-ease-in-out elsa-duration-150"> - Previous + {t('Previous')} } @@ -87,7 +98,7 @@ export class ElsaPager { return self.onNavigateClick(e, page + 1)} class="elsa-ml-3 elsa-relative elsa-inline-flex elsa-items-center elsa-px-4 elsa-py-2 elsa-border elsa-border-gray-300 elsa-text-sm elsa-leading-5 elsa-font-medium elsa-rounded-md elsa-text-gray-700 elsa-bg-white hover:elsa-text-gray-500 focus:elsa-outline-none focus:elsa-shadow-outline-blue focus:elsa-border-blue-300 active:elsa-bg-gray-100 active:elsa-text-gray-700 elsa-transition elsa-ease-in-out elsa-duration-150"> - Next + {t('Next')} } @@ -158,13 +169,7 @@ export class ElsaPager { - + ); } diff --git a/src/designer/elsa-workflows-studio/src/components/screens/workflow-instance-list/elsa-workflow-instance-list-screen/elsa-workflow-instance-list-screen.tsx b/src/designer/elsa-workflows-studio/src/components/screens/workflow-instance-list/elsa-workflow-instance-list-screen/elsa-workflow-instance-list-screen.tsx index 23bc22af5..f48ad30a8 100644 --- a/src/designer/elsa-workflows-studio/src/components/screens/workflow-instance-list/elsa-workflow-instance-list-screen/elsa-workflow-instance-list-screen.tsx +++ b/src/designer/elsa-workflows-studio/src/components/screens/workflow-instance-list/elsa-workflow-instance-list-screen/elsa-workflow-instance-list-screen.tsx @@ -8,6 +8,9 @@ import {DropdownButtonItem, DropdownButtonOrigin} from "../../../controls/elsa-d import {Map, parseQuery} from '../../../../utils/utils'; import moment from "moment"; import {PagerData} from "../../../controls/elsa-pager/elsa-pager"; +import {i18n} from "i18next"; +import {resources} from "./localizations"; +import {loadTranslations} from "../../../i18n/i18n-loader"; @Component({ tag: 'elsa-workflow-instance-list-screen', @@ -19,6 +22,7 @@ export class ElsaWorkflowInstanceListScreen { @Prop() workflowId?: string; @Prop() workflowStatus?: WorkflowStatus; @Prop() orderBy?: OrderBy = OrderBy.Started; + @Prop() culture: string; @State() workflowBlueprints: Array = []; @State() workflowInstances: PagedList = {items: [], page: 1, pageSize: 50, totalCount: 0}; @State() selectedWorkflowId?: string; @@ -30,10 +34,12 @@ export class ElsaWorkflowInstanceListScreen { @State() currentPageSize: number = 15; @State() currentSearchTerm?: string; + i18next: i18n; confirmDialog: HTMLElsaConfirmDialogElement; async componentWillLoad() { - + this.i18next = await loadTranslations(this.culture, resources); + if (!!this.history) { this.history.listen(e => this.routeChanged(e)); this.applyQueryString(this.history.location.search); @@ -61,6 +67,8 @@ export class ElsaWorkflowInstanceListScreen { await this.loadWorkflowInstances(); } + t = (key: string, options?: any) => this.i18next.t(key, options); + applyQueryString(queryString?: string) { const query = parseQuery(queryString); @@ -169,7 +177,8 @@ export class ElsaWorkflowInstanceListScreen { } async onDeleteClick(e: Event, workflowInstance: WorkflowInstanceSummary) { - const result = await this.confirmDialog.show('Delete Workflow Instance', 'Are you sure you wish to permanently delete this workflow instance?'); + const t = this.t; + const result = await this.confirmDialog.show(t('DeleteDialog.Title'), t('DeleteDialog.Message')); if (!result) return; @@ -180,7 +189,8 @@ export class ElsaWorkflowInstanceListScreen { } async onBulkDelete() { - const result = await this.confirmDialog.show('Delete Selected Workflow Instances', 'Are you sure you wish to permanently delete all selected workflow instances?'); + const t = this.t; + const result = await this.confirmDialog.show(t('BulkDeleteDialog.Title'), t('BulkDeleteDialog.Message')); if (!result) return; @@ -220,6 +230,7 @@ export class ElsaWorkflowInstanceListScreen { render() { const workflowInstances = this.workflowInstances.items; const workflowBlueprints = this.workflowBlueprints; + const t= this.t; const renderViewIcon = function () { return ( @@ -258,7 +269,7 @@ export class ElsaWorkflowInstanceListScreen { @@ -287,34 +298,34 @@ export class ElsaWorkflowInstanceListScreen { this.onSelectAllCheckChange(e)} class="focus:elsa-ring-blue-500 elsa-h-4 elsa-w-4 elsa-text-blue-600 elsa-border-gray-300 elsa-rounded"/> - ID + {t('Table.Id')} - Correlation ID + {t('Table.CorrelationId')} - Workflow + {t('Table.Workflow')} - Version + {t('Table.Version')} - Instance Name + {t('Table.InstanceName')} - Status + {t('Table.Status')} - Created + {t('Table.Created')} - Finished + {t('Table.Finished')} - Last Executed + {t('Table.LastExecuted')} - Faulted + {t('Table.Faulted')} @@ -374,17 +385,17 @@ export class ElsaWorkflowInstanceListScreen { this.onDeleteClick(e, workflowInstance), icon: renderDeleteIcon()} + {text: t('Table.ContextMenu.View'), anchorUrl: viewUrl, icon: renderViewIcon()}, + {text: t('Table.ContextMenu.Delete'), clickHandler: e => this.onDeleteClick(e, workflowInstance), icon: renderDeleteIcon()} ]}/> })} - + - this.confirmDialog = el}/> + this.confirmDialog = el} culture={this.culture}/> ); @@ -394,26 +405,29 @@ export class ElsaWorkflowInstanceListScreen { const bulkActionIcon = ; + + const t = this.t; const actions: Array = [{ - text: 'Delete', + text: t('BulkActions.Actions.Delete'), name: 'Delete', }]; - return this.onBulkActionSelected(e)}/> + return this.onBulkActionSelected(e)}/> } renderWorkflowFilter() { + const t = this.t; const latestWorkflowBlueprints = this.getLatestWorkflowBlueprintVersions(); const selectedWorkflowId = this.selectedWorkflowId; const selectedWorkflow = latestWorkflowBlueprints.find(x => x.id == selectedWorkflowId); - const selectedWorkflowText = !selectedWorkflowId ? "Workflow" : !!selectedWorkflow && (selectedWorkflow.name || selectedWorkflow.displayName) ? (selectedWorkflow.displayName || selectedWorkflow.name) : "Untitled"; + const selectedWorkflowText = !selectedWorkflowId ? t('Filters.Workflow.Label') : !!selectedWorkflow && (selectedWorkflow.name || selectedWorkflow.displayName) ? (selectedWorkflow.displayName || selectedWorkflow.name) : t('Untitled'); const selectedWorkflowStatus = this.selectedWorkflowStatus; const selectedOrderBy = this.selectedOrderByState; const history = this.history; let items: Array = latestWorkflowBlueprints.map(x => { - const displayName = !!x.displayName && x.displayName.length > 0 ? x.displayName : x.name || 'Untitled'; + const displayName = !!x.displayName && x.displayName.length > 0 ? x.displayName : x.name || t('Untitled'); const item: DropdownButtonItem = {text: displayName, value: x.id, isSelected: x.id == selectedWorkflowId}; if (!!history) @@ -422,7 +436,7 @@ export class ElsaWorkflowInstanceListScreen { return item; }); - const allItem: DropdownButtonItem = {text: 'All', value: null, isSelected: !selectedWorkflowId}; + const allItem: DropdownButtonItem = {text: t('Filters.Workflow.All'), value: null, isSelected: !selectedWorkflowId}; if (!!history) allItem.url = this.buildFilterUrl(null, selectedWorkflowStatus, selectedOrderBy); @@ -443,13 +457,14 @@ export class ElsaWorkflowInstanceListScreen { } renderStatusFilter() { + const t = this.t; const selectedWorkflowStatus = this.selectedWorkflowStatus; - const selectedWorkflowStatusText = !!selectedWorkflowStatus ? selectedWorkflowStatus : 'Status'; + const selectedWorkflowStatusText = !!selectedWorkflowStatus ? selectedWorkflowStatus : t('Filters.Status.Label'); const statuses: Array = [null, WorkflowStatus.Running, WorkflowStatus.Suspended, WorkflowStatus.Finished, WorkflowStatus.Faulted, WorkflowStatus.Cancelled, WorkflowStatus.Idle]; const history = this.history; const items: Array = statuses.map(x => { - const text = x ?? 'All'; + const text = x ?? t('Filters.Status.All'); const item: DropdownButtonItem = {text: text, isSelected: x == selectedWorkflowStatus, value: x}; if (!!history) @@ -469,8 +484,9 @@ export class ElsaWorkflowInstanceListScreen { } renderOrderByFilter() { + const t = this.t; const selectedOrderBy = this.selectedOrderByState; - const selectedOrderByText = !!selectedOrderBy ? `Sort by: ${selectedOrderBy}` : 'Sort'; + const selectedOrderByText = !!selectedOrderBy ? t('Filters.Sort.SelectedLabel', {Key: selectedOrderBy}) : t('Filters.Sort.Label'); const orderByValues: Array = [OrderBy.Finished, OrderBy.LastExecuted, OrderBy.Started]; const history = this.history; diff --git a/src/designer/elsa-workflows-studio/src/components/screens/workflow-instance-list/elsa-workflow-instance-list-screen/localizations.ts b/src/designer/elsa-workflows-studio/src/components/screens/workflow-instance-list/elsa-workflow-instance-list-screen/localizations.ts new file mode 100644 index 000000000..5f97fa97d --- /dev/null +++ b/src/designer/elsa-workflows-studio/src/components/screens/workflow-instance-list/elsa-workflow-instance-list-screen/localizations.ts @@ -0,0 +1,70 @@ +export const resources = { + 'en': { + 'default': { + 'Title': 'Workflow Instances', + 'Search': 'Search', + 'Untitled': 'Untitled', + 'Table': { + 'Id': 'ID', + 'CorrelationId': 'Correlation ID', + 'Workflow': 'Workflow', + 'Version': 'Version', + 'InstanceName': 'Instance Name', + 'Status': 'Status', + 'Created': 'Created', + 'Finished': 'Finished', + 'LastExecuted': 'Last Executed', + 'Faulted': 'Faulted', + 'ContextMenu':{ + 'View': 'View', + 'Delete': 'Delete' + } + }, + 'DeleteDialog':{ + 'Title': 'Delete Workflow Instance', + 'Message': 'Are you sure you wish to permanently delete this workflow instance?' + }, + 'BulkDeleteDialog':{ + 'Title': 'Delete Selected Workflow Instances', + 'Message': 'Are you sure you wish to permanently delete all selected workflow instances?' + }, + 'Pager': { + 'Display': 'Showing {{Start}} to {{End}} of {{Results}} results' + }, + 'BulkActions': { + 'Title': 'Bulk Actions', + 'Actions': { + 'Delete': 'Delete' + } + }, + 'Filters': { + 'Workflow': { + 'Label': 'Workflow', + 'All': 'All' + }, + 'Status': { + 'All': 'All', + 'Label': 'Status', + 'Running': 'Running', + 'Idle': 'Idle', + 'Suspended': 'Suspended', + 'Faulted': 'Faulted', + 'Finished': 'Finished', + 'Cancelled': 'Cancelled' + }, + 'Sort': { + 'Label': 'Sort', + 'SelectedLabel': 'Sort by: {{Key}}', + 'Finished': 'Finished', + 'LastExecuted': 'Last Executed', + 'Started': 'Started' + } + } + } + }, + 'nl-NL': { + 'default': { + + } + } +}; \ No newline at end of file