UNPKG

@orchestrator-ui/orchestrator-ui-components

Version:

Library of UI Components used to display the workflow orchestrator frontend

208 lines (178 loc) 6.06 kB
import { TranslationValues } from 'next-intl'; import { EuiSelectableOption, EuiThemeComputed } from '@elastic/eui'; import { FieldValue, ProcessStatus, ProductBlockDefinition, ProductBlockInstance, SortOrder, SubscriptionAction, SubscriptionDetailProcess, WorkflowTarget, } from '@/types'; const PRODUCT_BLOCK_NAME_FIELD: keyof ProductBlockDefinition = 'name'; export enum SubscriptionDetailTab { GENERAL_TAB = 'general', SERVICE_CONFIGURATION_TAB = 'service-configuration', PROCESSES_TAB = 'processes', RELATED_SUBSCRIPTIONS_TAB = 'related-subscriptions', } export const getFieldFromProductBlockInstanceValues = ( instanceValues: FieldValue[], field: string, ): string | number | boolean => { const nameValue = instanceValues.find( (instanceValue) => instanceValue.field === field, ); return nameValue?.value ?? ''; }; export const getProductBlockTitle = ( instanceValues: FieldValue[], ): string | number | boolean => { const title = getFieldFromProductBlockInstanceValues( instanceValues, 'title', ); if (!title) { return getFieldFromProductBlockInstanceValues(instanceValues, 'name'); } return title; }; export const flattenArrayProps = ( action: SubscriptionAction, ): TranslationValues => { const flatObject: TranslationValues = {}; for (const [key, value] of Object.entries(action)) { if (Array.isArray(value)) { flatObject[key] = value.join(', '); } else { flatObject[key] = value; } } return action ? flatObject : {}; }; export const getWorkflowTargetColor = ( workflowTarget: WorkflowTarget, theme: EuiThemeComputed, ) => { // Data returned from graphql can't always be depended on to be lowercase switch (workflowTarget.toLocaleLowerCase()) { case WorkflowTarget.CREATE: return theme.colors.successText; case WorkflowTarget.MODIFY: return theme.colors.primaryText; case WorkflowTarget.SYSTEM: case WorkflowTarget.VALIDATE: return theme.colors.warning; case WorkflowTarget.RECONCILE: return theme.colors.accent; case WorkflowTarget.TERMINATE: return theme.colors.danger; } return theme.colors.body; }; export const getWorkflowTargetIconContent = ( workflowTarget: WorkflowTarget, ) => { // Data returned from graphql can't always be depended on to be lowercase switch (workflowTarget.toLocaleLowerCase()) { case WorkflowTarget.CREATE: return 'C'; case WorkflowTarget.SYSTEM: case WorkflowTarget.VALIDATE: return 'T'; case WorkflowTarget.TERMINATE: return 'X'; case WorkflowTarget.RECONCILE: return 'R'; default: return 'M'; } }; export const getLastUncompletedProcess = ( processes?: SubscriptionDetailProcess[], ): SubscriptionDetailProcess | undefined => { if (!processes || processes.length === 0) { return; } const uncompletedProcesses = processes .filter((process) => process.lastStatus !== ProcessStatus.COMPLETED) .sort((a, b) => { const dateA = new Date(a.startedAt); const dateB = new Date(b.startedAt); return dateB.getTime() - dateA.getTime(); }); return (uncompletedProcesses && uncompletedProcesses.length) > 0 ? uncompletedProcesses[0] : undefined; }; const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; const extractUUIDsFromBrackets = (input: string) => { const start = input.indexOf('['); const end = input.indexOf(']', start); if (start === -1 || end === -1) return []; const content = input.slice(start + 1, end).trim(); if (!content) return []; return content .split(',') .map((s) => s.trim().replace(/^['"]|['"]$/g, '')) // remove surrounding ' or " .filter((s) => uuidRegex.test(s)); }; export function parseErrorDetail(errorDetail: string) { const failedIds = extractUUIDsFromBrackets(errorDetail); const filteredInput = errorDetail.split('[')[0].trim(); return { failedIds, filteredInput }; } export const getLatestTaskDate = (processes?: SubscriptionDetailProcess[]) => { if (!processes || processes.length === 0) { return ''; } const tasks = processes .filter((process) => process.isTask) .sort((a, b) => { const dateA = new Date(a.startedAt); const dateB = new Date(b.startedAt); return dateB.getTime() - dateA.getTime(); }); return tasks.length > 0 ? tasks[0].startedAt : ''; }; export const sortProcessesByDate = ( processList: SubscriptionDetailProcess[], sortOrder: SortOrder, ) => { return [...processList].sort((a, b) => { const dateA = new Date(a.startedAt).getTime(); const dateB = new Date(b.startedAt).getTime(); if (sortOrder === SortOrder.ASC) { return dateA - dateB; // Ascending order (oldest first) } else { return dateB - dateA; // Descending order (newest first) } }); }; export const mapProductBlockInstancesToEuiSelectableOptions = ( productBlockInstances: ProductBlockInstance[], ): EuiSelectableOption[] => { const items2Map = productBlockInstances.reduce((acc, curr) => { const name = getFieldFromProductBlockInstanceValues( curr.productBlockInstanceValues, PRODUCT_BLOCK_NAME_FIELD, ).toString(); if (!name) { console.error('Name field is missing', curr); } if (acc.has(name)) { acc.get(name)?.push(curr.id); } else { acc.set(name, [curr.id]); } return acc; }, new Map<string, number[]>()); return Array.from(items2Map).map(([label, ids]) => ({ label, data: { ids, }, })); };