/*
* 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 { Auth } from "@aws-amplify/auth";
import {
toBase64
} from '../resources/main.js'
import {
Alert,
Select,
SpaceBetween,
StatusIndicator,
Header,
Button,
FormField,
Input,
Container
} from '@awsui/components-react';
import AutomationScriptView from '../components/AutomationScriptView.jsx'
import { useAutomationScripts } from "../actions/AutomationScriptsHook.js";
import AutomationScriptsTable from '../components/AutomationScriptsTable.jsx';
import AutomationScriptImport from "../components/AutomationScriptImport";
import ToolsAPI from "../actions/tools";
const ViewAutomationScript = (props) => {
const [viewerCurrentTab, setViewerCurrentTab] = useState('details');
async function handleViewerTabChange(tabselected)
{
setViewerCurrentTab(tabselected);
}
if (props.selectedItems.length === 1) {
return (
);
} else {
return (null);
}
}
const AutomationScripts = (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 } ] = useAutomationScripts();
const dataAll = {jobs: {data: dataMain, isLoading: isLoadingMain, error: errorMain}};
//Layout state management.
const [editingItem, setEditingItem] = useState(false);
//Main table state management.
const [selectedItems, setSelectedItems] = useState([]);
const [focusItem, setFocusItem] = useState([]);
//Viewer pane state management.
const [action, setAction] = useState('Add');
const [newDefaultVersion, setNewDefaultVersion] = useState('');
//Get base path from the URL, all actions will use this base path.
const basePath = '/automation/scripts'
//Key for main item displayed in table.
const itemIDKey = 'package_uuid';
function handleNotification(notification)
{
return props.updateNotification('add', notification)
}
async function handleRefreshClick(e) {
e.preventDefault();
await updateMain();
refreshSelectedItems();
}
function refreshSelectedItems() {
// Search for previously selected items, and update based on refreshed data.
let updatedItems = []
if (selectedItems.length > 0) {
for (const selectedItem of selectedItems) {
const findResult = dataMain.find(item => item[itemIDKey] === selectedItem[itemIDKey])
if (findResult) {
updatedItems.push(findResult);
}
}
handleItemSelectionChange(updatedItems);
}
setFocusItem(selectedItems.length === 1 ? selectedItems[0] : {});
}
function handleAddItem()
{
navigate({
pathname: basePath + '/add'
})
setAction('Add')
setFocusItem({});
setEditingItem(true);
}
function handleUpdateItem()
{
navigate({
pathname: basePath + '/add'
})
setAction('Update')
setFocusItem(selectedItems.length === 1 ? selectedItems[0] : {});
setEditingItem(true);
}
async function handleAction(e) {
e.preventDefault();
let action = e.detail.id;
if(action === 'new_version'){
handleUpdateItem()
} else if (action === 'change_default'){
setAction('UpdateDefault');
setFocusItem(selectedItems[0]);
setNewDefaultVersion(selectedItems[0].default)
setEditingItem(true);
} else if (action === 'download_default_version'){
setFocusItem(selectedItems[0]);
await handleDownloadVersion()
} else if (action === 'download_latest_version'){
setFocusItem(selectedItems[0]);
await downloadScriptVersion({'package_uuid': selectedItems[0].package_uuid, 'script_name': selectedItems[0].script_name, 'default': selectedItems[0].latest})
}
}
async function handleUpload(selectedFile, details) {
const result = await toBase64(selectedFile).catch(e => Error(e));
if(result instanceof Error) {
console.log('Error: ', result.message);
return;
}
let newItem = {
"script_name": details.script_name,
"script_file": result
};
let notificationId = null;
try {
notificationId = handleNotification({
type: 'success',
loading: true,
dismissible: false,
header: "Uploading script",
content: "Uploading script - " + selectedFile.name,
});
const session = await Auth.currentSession();
const apiTools = await new ToolsAPI(session);
if (action === 'Add') {
await apiTools.postSSMScripts(newItem);
} else if (action === 'Update'){
newItem.action = 'update_package';
newItem.package_uuid = details.package_uuid;
newItem.__make_default = details.__make_default;
const response = await apiTools.putSSMScripts(newItem);
console.log(response)
} else if (action === 'ChangeDefault'){
if (details.__make_default){
newItem.action = 'update_default';
delete newItem.script_file;
newItem.default = details.default
await apiTools.putSSMScripts(newItem);
}
} else {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Uploading script",
content: 'Invalid action supplied.'
});
return;
}
handleNotification({
id: notificationId,
type: 'success',
dismissible: true,
header: "Uploading script",
content: selectedFile.name + " script upload successfully.",
});
updateMain();
} 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: "Uploading script",
content: selectedFile.name + ' script upload failed: ' + JSON.stringify(e.response.data)
});
}
} else {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Uploading script",
content: selectedFile.name + ' script upload failed: ' + e.message
});
}
} else {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Uploading script",
content: selectedFile.name + ' script upload failed: Unknown error occurred',
});
}
}
//
// setSelectedFile(e.target.files[0])
//TODO Deal with file
handleResetScreen();
}
async function handleChangeVersion() {
let newItem = {
"package_uuid": focusItem.package_uuid,
"script_name": focusItem.script_name,
"default": newDefaultVersion
};
let notificationId = null;
try {
notificationId = handleNotification({
type: 'success',
loading: true,
dismissible: false,
header: "Change script default version",
content: "Changing script default version - " + focusItem.script_name,
});
const session = await Auth.currentSession();
const apiTools = await new ToolsAPI(session);
newItem.action = 'update_default';
await apiTools.putSSMScripts(newItem);
handleNotification({
id: notificationId,
type: 'success',
dismissible: true,
header: "Change script default version",
content: focusItem.script_name + " script default version changed to use version " + newDefaultVersion + ".",
});
setSelectedItems([]);
updateMain();
} 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: "Change script default version",
content: focusItem.script_name + ' script version change failed: ' + e.response.data
});
}
} else {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Change script default version",
content: focusItem.script_name + ' script version change failed: ' + e.message
});
}
} else {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Uploading script",
content: focusItem.script_name + ' script version change failed.',
});
}
}
//
// setSelectedFile(e.target.files[0])
//TODO Deal with file
handleResetScreen();
}
function downloadZIP(script) {
const linkSource = `data:application/zip;base64,${script.script_file}`;
const downloadLink = document.createElement("a");
let fileName = script.script_name;
if (fileName.endsWith('.zip')){
fileName = script.script_name.replace('.zip', '_v' + script.script_version + '.zip');
} else {
fileName = script.script_name + '_v' + script.script_version + '.zip';
}
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();
}
async function handleDownloadVersion() {
await downloadScriptVersion(selectedItems[0]);
}
async function downloadScriptVersion(script) {
let notificationId = null;
try {
notificationId = handleNotification({
type: 'success',
loading: true,
dismissible: false,
header: "Download script",
content: "Downloading script default version - " + script.script_name,
});
const session = await Auth.currentSession();
const apiTools = await new ToolsAPI(session);
const response = await apiTools.getSSMScript(script.package_uuid, script.default, true);
downloadZIP(response)
handleNotification({
id: notificationId,
type: 'success',
dismissible: true,
header: "Download script",
content: script.script_name + " script downloaded.",
});
setSelectedItems([]);
} 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: "Download script",
content: script.script_name + ' script download failed: ' + e.response.data
});
}
} else {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Download script",
content: script.script_name + ' script download failed: ' + e.message
});
}
} else {
handleNotification({
id: notificationId,
type: 'error',
dismissible: true,
header: "Download script",
content: script.script_name + ' script download failed.',
});
}
}
}
function handleEditItem(selection = null)
{
if ( selectedItems.length === 1) {
navigate({
pathname: basePath + '/edit/' + selectedItems[0][itemIDKey]
})
setAction('Edit')
setFocusItem(selectedItems[0]);
setEditingItem(true);
} else if ( selection ) {
navigate({
pathname: basePath + '/edit/' + selection[itemIDKey]
})
setAction('Edit');
setFocusItem(selection);
setEditingItem(true);
}
}
function handleResetScreen()
{
navigate({
pathname: basePath
})
setEditingItem(false);
}
function handleItemSelectionChange(selection) {
setSelectedItems(selection);
//Reset URL to base table path.
navigate({
pathname: basePath
})
}
function displayScriptScreen(){
if (editingItem){
return displayEditScreen(action)
} else {
return displayViewScreen()
}
}
function displayViewScreen(){
return
}
function displayEditScreen(action){
switch (action) {
case 'Add': {
return
}
case 'Update': {
return
}
case 'UpdateDefault': {
return displayUpdatedDefault();
}
default:
return undefined;
}
}
function isActionsDisabled(){
if (props.userEntityAccess['script'] && props.userEntityAccess['script'].create && selectedItems.length === 1) {
return false;
}
return true;
}
function displayUpdatedDefault(){
return
Change default script version
}
>
{newDefaultVersion !== focusItem.default ?
{newDefaultVersion !== focusItem.default ? 'Saving will change default script to use version ' + newDefaultVersion + ' instead of version ' + focusItem.default + ' for all automation future jobs.' : '' }
:
undefined}
}
useEffect( () => {
let selected = [];
if (!isLoadingMain) {
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();
}
refreshSelectedItems();
}
}, [dataMain]);
let schemaSSMAttribs = undefined;
if (!props.schemaIsLoading && props.isReady) {
if (props.schema['script']) {
schemaSSMAttribs = props.schema['script'];
} else {
schemaSSMAttribs = [];
}
}
const getVersions = () => {
let versions = [];
for (let versionNum = 1; versionNum <= focusItem.latest; versionNum++){
if (focusItem.default == versionNum){
versions.push({'label': versionNum + ' DEFAULT', 'value': versionNum});
} else {
versions.push({'label': versionNum, 'value': versionNum});
}
}
return versions;
}
return (
{props.schemaIsLoading ?
Loading schema...
:
displayScriptScreen()
}
);
};
export default AutomationScripts;