Skip to content

Commit

Permalink
CIM Service Tickets page (#411)
Browse files Browse the repository at this point in the history
* Service ticket page with the new naming convention applied and pages moved to the wfo-surf-ui app

* Changed tab structure for service tickets page wip

* Added filtering for Active and Completed service tickets.

* linted

* 411: Last commit before files are moved to wfo-ui-surf app

* 411: Moved surf specific pages and components to the wfo-ui-surf

* 411: Removed surf package

* Service ticket page in wfo-ui-surf app, + new badge and color components

* 411: Some fixes and refactoring

* 411: Resolved comments

* 411: resolved some comments

* 411 Moves the status color column into the basic table

* 411 Resolved all comments

---------

Co-authored-by: Ricardo van der Heijden <[email protected]>
  • Loading branch information
Georgi2704 and ricardovdheijden authored Nov 8, 2023
1 parent 0dc959d commit 9b95edb
Show file tree
Hide file tree
Showing 29 changed files with 917 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { ServiceTicketProcessState } from '../../types';
import React, { FC } from 'react';
import {
useOrchestratorTheme,
WfoBadge,
} from '@orchestrator-ui/orchestrator-ui-components';

export type WfoProcessStatusBadgeProps = {
serviceTicketState: ServiceTicketProcessState;
};

export const WfoServiceTicketStatusBadge: FC<WfoProcessStatusBadgeProps> = ({
serviceTicketState,
}) => {
const { theme, toSecondaryColor } = useOrchestratorTheme();

const getBadgeColorFromServiceTicketState = () => {
const {
primary,
lightShade,
primaryText,
success,
successText,
text,
warning,
warningText,
} = theme.colors;

const {
NEW,
OPEN,
OPEN_RELATED,
OPEN_ACCEPTED,
UPDATED,
ABORTED,
CLOSED,
} = ServiceTicketProcessState;

switch (serviceTicketState) {
case OPEN:
case NEW:
return {
badgeColor: toSecondaryColor(success),
textColor: successText,
};
case OPEN_ACCEPTED:
case OPEN_RELATED:
return {
badgeColor: toSecondaryColor(warning),
textColor: warningText,
};
case UPDATED:
return {
badgeColor: toSecondaryColor(primary),
textColor: primaryText,
};
case CLOSED:
case ABORTED:
return {
badgeColor: toSecondaryColor(lightShade),
textColor: text,
};
default:
return {
badgeColor: toSecondaryColor(lightShade),
textColor: text,
};
}
};

const { badgeColor, textColor } = getBadgeColorFromServiceTicketState();

return (
<WfoBadge textColor={textColor} color={badgeColor}>
{serviceTicketState.toLowerCase()}
</WfoBadge>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import React, { useState } from 'react';
import { Criteria, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import {
ServiceTicketDefinition,
ServiceTicketProcessState,
} from '../../types';
import { useTranslations } from 'next-intl';
import {
DataDisplayParams,
DEFAULT_PAGE_SIZES,
FilterQuery,
getSortDirectionFromString,
parseDateToLocaleDateTimeString,
parseIsoString,
SortOrder,
TableColumnKeys,
useFilterQueryWithRest,
useOrchestratorTheme,
WfoBasicTable,
WfoDataSorting,
WfoDateTime,
WfoTableColumns,
} from '@orchestrator-ui/orchestrator-ui-components';
import { CIM_TICKETS_ENDPOINT } from '../../constants-surf';
import { WfoServiceTicketStatusBadge } from '../WfoBadges/WfoServiceTicketStatusBadge';
import { ColorMappings, getColorForState } from '../../utils/getColorForState';

const SERVICE_TICKET_FIELD_JIRA_ID: keyof ServiceTicketDefinition =
'jira_ticket_id';
const SERVICE_TICKET_FIELD_TITLE: keyof ServiceTicketDefinition = 'title_nl';
const SERVICE_TICKET_FIELD_PROCESS_STATE: keyof ServiceTicketDefinition =
'process_state';
const SERVICE_TICKET_FIELD_OPENED_BY: keyof ServiceTicketDefinition =
'opened_by';
const SERVICE_TICKET_FIELD_START_DATE: keyof ServiceTicketDefinition =
'start_date';
const SERVICE_TICKET_FIELD_CREATE_DATE: keyof ServiceTicketDefinition =
'create_date';
const SERVICE_TICKET_FIELD_LAST_UPDATE: keyof ServiceTicketDefinition =
'last_update_time';

const { NEW, OPEN, OPEN_RELATED, OPEN_ACCEPTED, UPDATED, ABORTED, CLOSED } =
ServiceTicketProcessState;

export type WfoServiceTicketsListProps = {
alwaysOnFilters?: FilterQuery<ServiceTicketDefinition>[];
defaultHiddenColumns: TableColumnKeys<ServiceTicketDefinition> | undefined;
localStorageKey: string;
dataDisplayParams: DataDisplayParams<ServiceTicketDefinition>;
setDataDisplayParam: <
DisplayParamKey extends
keyof DataDisplayParams<ServiceTicketDefinition>,
>(
prop: DisplayParamKey,
value: DataDisplayParams<ServiceTicketDefinition>[DisplayParamKey],
) => void;
overrideDefaultTableColumns?: (
defaultTableColumns: WfoTableColumns<ServiceTicketDefinition>,
) => WfoTableColumns<ServiceTicketDefinition>;
};

export const WfoServiceTicketsList = ({
alwaysOnFilters,
}: WfoServiceTicketsListProps) => {
const { theme } = useOrchestratorTheme();
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(5);
const [dataSorting, setDataSorting] = useState<
WfoDataSorting<ServiceTicketDefinition>
>({
field: SERVICE_TICKET_FIELD_LAST_UPDATE,
sortOrder: SortOrder.DESC,
});

const t = useTranslations('cim.serviceTickets');

const { data, isFetching } =
useFilterQueryWithRest<ServiceTicketDefinition>(
CIM_TICKETS_ENDPOINT,
'serviceTickets',
alwaysOnFilters,
);

const serviceTicketColorMappings: ColorMappings = {
[theme.colors.success]: [OPEN, NEW],
[theme.colors.warning]: [OPEN_ACCEPTED, OPEN_RELATED],
[theme.colors.primary]: [UPDATED],
[theme.colors.lightShade]: [CLOSED, ABORTED],
};

const tableColumns: WfoTableColumns<ServiceTicketDefinition> = {
jira_ticket_id: {
field: SERVICE_TICKET_FIELD_JIRA_ID,
name: t('jiraTicketId'),
width: '100',
render: (value) => (
<EuiFlexGroup>
<EuiFlexItem>{value}</EuiFlexItem>
</EuiFlexGroup>
),
sortable: true,
},
title_nl: {
field: SERVICE_TICKET_FIELD_TITLE,
name: t('titleNl'),
width: '300',
},
process_state: {
field: SERVICE_TICKET_FIELD_PROCESS_STATE,
name: t('processState'),
width: '120',
render: (value, object) => (
<WfoServiceTicketStatusBadge
serviceTicketState={object.process_state}
/>
),
},
opened_by: {
field: SERVICE_TICKET_FIELD_OPENED_BY,
name: t('openedBy'),
width: '180',
},
start_date: {
field: SERVICE_TICKET_FIELD_START_DATE,
name: t('startDate'),
width: '150',
render: (date) => <WfoDateTime dateOrIsoString={date} />,
renderDetails: parseIsoString(parseDateToLocaleDateTimeString),
clipboardText: parseIsoString(parseDateToLocaleDateTimeString),
},
create_date: {
field: SERVICE_TICKET_FIELD_CREATE_DATE,
name: t('createDate'),
width: '150',
render: (date: string) => (
<span>{new Date(date).toLocaleDateString()}</span>
),
},
last_update_time: {
field: SERVICE_TICKET_FIELD_LAST_UPDATE,
name: t('lastUpdateTime'),
width: '150',
render: (date: string) => (
<span>{new Date(date).toLocaleString()}</span>
),
},
};

const onCriteriaChange = ({
page,
sort,
}: Criteria<ServiceTicketDefinition>) => {
if (page) {
const { index: pageIndex, size: pageSize } = page;
setPageIndex(pageIndex);
setPageSize(pageSize);
}
if (sort) {
const { field: sortField, direction: sortDirection } = sort;
const sortOrder = getSortDirectionFromString(
sortDirection,
) as SortOrder;
setDataSorting({
field: sortField,
sortOrder: sortOrder,
});
}
};

const paginateServiceTickets = (
serviceTickets: ServiceTicketDefinition[],
pageIndex: number,
pageSize: number,
) => {
let pageOfItems;
if (!pageIndex && !pageSize) {
pageOfItems = serviceTickets;
} else {
const startIndex = pageIndex * pageSize;
pageOfItems = serviceTickets.slice(
startIndex,
Math.min(startIndex + pageSize, serviceTickets.length),
);
}
return {
pageOfItems,
totalItemCount: serviceTickets.length,
};
};

const sortedData = data?.sort((a, b) => {
const aValue = a[dataSorting.field];
const bValue = b[dataSorting.field];
if (aValue === bValue) {
return 0;
}
if (aValue === null || aValue === undefined) {
return 1;
}
if (bValue === null || bValue === undefined) {
return -1;
}
return aValue > bValue
? dataSorting.sortOrder === SortOrder.ASC
? 1
: -1
: dataSorting.sortOrder === SortOrder.ASC
? -1
: 1;
});

const { pageOfItems, totalItemCount } = paginateServiceTickets(
sortedData ? sortedData : [],
pageIndex,
pageSize,
);

const pagination = {
pageIndex: pageIndex,
pageSize: pageSize,
totalItemCount: totalItemCount,
pageSizeOptions: DEFAULT_PAGE_SIZES,
};

return (
<WfoBasicTable
data={pageOfItems ? pageOfItems : []}
isLoading={isFetching}
columns={tableColumns}
pagination={pagination}
onCriteriaChange={onCriteriaChange}
dataSorting={dataSorting}
getStatusColorForRow={(row) =>
getColorForState(serviceTicketColorMappings, row.process_state)
}
onUpdateDataSorting={(currentSort) => {
setDataSorting(currentSort);
}}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { WfoServiceTicketListTabType } from '../../types';

export const getServiceTicketListTabTypeFromString = (
tabId?: string,
): WfoServiceTicketListTabType | undefined => {
if (!tabId) {
return undefined;
}

switch (tabId.toUpperCase()) {
case WfoServiceTicketListTabType.ACTIVE.toString():
return WfoServiceTicketListTabType.ACTIVE;
case WfoServiceTicketListTabType.COMPLETED.toString():
return WfoServiceTicketListTabType.COMPLETED;

default:
return undefined;
}
};
1 change: 1 addition & 0 deletions apps/wfo-ui-surf/components/WfoServiceTicketsList/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './WfoServiceTicketsList';
Loading

0 comments on commit 9b95edb

Please sign in to comment.