/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
import React, {useEffect, useState} from 'react';
import {useLocation, useNavigate, useParams} from "react-router-dom";
import {
SpaceBetween,
StatusIndicator
} from '@awsui/components-react';
import AutomationJobView from '../components/AutomationJobView.jsx'
import { useAutomationJobs } from "../actions/AutomationJobsHook.js";
import { useMFWaves } from "../actions/WavesHook.js";
import ItemTable from '../components/ItemTable.jsx';
import AutomationTools from '../components/AutomationTools.jsx'
import {Auth} from "@aws-amplify/auth";
import ToolsAPI from "../actions/tools";
import {userAutomationActionsMenuItems} from "../resources/main";
import {useAutomationScripts} from "../actions/AutomationScriptsHook";
import {useCredentialManager} from "../actions/CredentialManagerHook";
const AutomationJobs = (props) => {
let location = useLocation()
let navigate = useNavigate();
let params = useParams();
//Data items for viewer and table.
//Main table content hook. When duplicating just create a new hook and change the hook function at the end to populate table.
const [{ isLoading: isLoadingMain, data: dataMain, error: errorMain }, {update: updateMain } ] = useAutomationJobs();
const [{ isLoading: isLoadingWaves, data: dataWaves, error: errorWaves }, ] = useMFWaves();
const [{ isLoading: isLoadingScripts, data: dataScripts, error: errorScripts }, ] = useAutomationScripts();
const [{ isLoading: isLoadingSecrets, data: dataSecrets, error: errorSecrets }, ] = useCredentialManager();
const dataAll = {secret: {data: dataSecrets, isLoading: isLoadingSecrets, error: errorSecrets},script: {data: dataScripts, isLoading: isLoadingScripts, error: errorScripts},jobs: {data: dataMain, isLoading: isLoadingMain, error: errorMain},wave: {data: dataWaves, isLoading: isLoadingWaves, error: errorWaves}};
//Main table state management.
const [selectedItems, setSelectedItems] = useState([]);
const [focusItem, setFocusItem] = useState([]);
const [filterJobsShowAll, setFilterJobsShowAll] = useState(false);
//Add Job/Action state management.
const [automationAction, setAutomationAction] = useState(undefined);
const [preformingAction, setPreformingAction] = useState(false);
//Viewer pane state management.
const [viewerCurrentTab, setViewerCurrentTab] = useState('details');
const [action, setAction] = useState(['Add']);
const [actions, setActions] = useState([]);
//Get base path from the URL, all actions will use this base path.
const basePath = '/automation/jobs'
//Key for main item displayed in table.
const itemIDKey = 'uuid';
const schemaName = 'job';
function handleNotification(notification)
{
return props.updateNotification('add', notification)
}
async function handleRefreshClick(e) {
e.preventDefault();
await updateMain(filterJobsShowAll ? undefined : 30);
}
function handleAddItem()
{
navigate({
pathname: basePath + '/add'
})
setAction('Add')
setFocusItem({});
}
function handleEditItem(selection = null)
{
if ( selectedItems.length === 1) {
navigate({
pathname: basePath + '/edit/' + selectedItems[0][itemIDKey]
})
setAction('Edit')
setFocusItem(selectedItems[0]);
} else if ( selection ) {
navigate({
pathname: basePath + '/edit/' + selection[itemIDKey]
})
setAction('Edit');
setFocusItem(selection);
}
}
async function handleViewerTabChange(tabselected)
{
setViewerCurrentTab(tabselected);
}
function handleResetScreen()
{
navigate({
pathname: basePath
});
setAction('View');
}
function handleItemSelectionChange(selection) {
setSelectedItems(selection);
//Reset URL to base table path.
navigate({
pathname: basePath
})
}
const ViewAutomationJob = (props) => {
if (selectedItems.length === 1) {
return (
);
} else {
return (null);
}
}
async function handleActionsClick(e) {
e.preventDefault();
let action = e.detail.id;
setFocusItem(selectedItems);
setAutomationAction(action);
setAction('Action');
}
async function handleAction(actionData, actionId) {
setPreformingAction(true);
let newItem = Object.assign({}, actionData);
let notificationId = null;
let apiAction = props.schema[automationAction].actions.filter(function (entry) {
return entry.id === actionId;
});
if (apiAction.length !== 1) {
handleNotification({
type: 'error',
dismissible: true,
header: "Perform wave action",
content: props.schema[automationAction].friendly_name + ' action [' & actionId & '] not found in schema.',
});
} else {
try {
if (apiAction[0].additionalData){
const keys = Object.keys(apiAction[0].additionalData);
for (const i in keys){
newItem[keys[i]] = apiAction[0].additionalData[keys[i]]
}
}
notificationId = handleNotification({
type: 'success',
loading: true,
dismissible: false,
header: "Perform wave action",
content: "Performing action - " + apiAction[0].name,
});
const session = await Auth.currentSession();
const apiTools = await new ToolsAPI(session);
const response = await apiTools.postTool(apiAction[0].apiPath, newItem);
console.log(response)
//Extra UUID from response.
let uuid = response.split('+');
if (uuid.length > 1){
uuid = uuid[1];
await handleResetScreen();
handleNotification({
id: notificationId,
type: 'success',
dismissible: true,
header: "Perform wave action",
actionButtonTitle: "View Job",
actionButtonLink: "/automation/jobs/" + uuid,
content: apiAction[0].name + " action successfully.",
});
} else {
await handleResetScreen();
handleNotification({
id: notificationId,
type: 'success',
dismissible: true,
header: "Perform wave action",
content: response,
});
}
await updateMain(filterJobsShowAll ? undefined : 30);
} catch (e) {
console.log(e);
if ('response' in e) {
if(e.response != null && typeof e.response === 'object') {
if ('data' in e.response) {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Perform wave action",
content: apiAction[0].name + ' action failed: ' + e.response.data
});
}
} else {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Perform wave action",
content: apiAction[0].name + ' action failed: ' + e.message
});
}
} else {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Perform wave action",
content: apiAction[0].name + ' action failed: Unknown error occured',
});
}
}
}
setPreformingAction(false);
}
async function handleFilterDaysChange(flag){
setFilterJobsShowAll(flag);
await updateMain(flag ? undefined : 30);
}
//Update actions button options on schema change.
useEffect( () => {
if(!props.schemaIsLoading && props.isReady){
setActions(userAutomationActionsMenuItems(props.schema, props.userEntityAccess));
}
},[props.schema, props.userEntityAccess]);
useEffect( () => {
let selected = [];
if (!isLoadingMain) {
if (params.id) {
//URL parameter present.
let item = dataMain.filter(function (entry) {
return entry[itemIDKey] === params.id;
});
if (item.length === 1) {
selected.push(item[0]);
handleItemSelectionChange(selected);
//Check if URL contains edit path and switch to amend component.
if (location.pathname && location.pathname.match('/edit/')) {
handleEditItem(item[0]);
}
} else if (location.pathname && location.pathname.match('/add')) {
//Add url used, redirect to add screen.
handleAddItem();
}
}
}
}, [dataMain]);
//Detect changes to main data table content and if an item was previously selected and in the viewer, refresh the item
//content.
useEffect( () => {
let selected = [];
if (!isLoadingMain) {
if (selectedItems.length == 1) {
//Refresh selected item.
let item = dataMain.filter(function (entry) {
return entry[itemIDKey] === selectedItems[0][itemIDKey];
});
if (item.length === 1) {
//Previous Item found in new data, reload into selected items.
selected.push(item[0]);
handleItemSelectionChange(selected);
} else {
//Item no longer available.
handleItemSelectionChange(selected);
}
}
}
}, [dataMain]);
function provideContent(currentAction){
if(props.schemaIsLoading || !props.isReady){
return (
Loading schema...
)
}
switch (currentAction) {
case 'Action':
return (
)
default:
return
}
}
return provideContent(action);
};
export default AutomationJobs;