From 4d146e53e29a158e30ee5defdcec166c4faeff33 Mon Sep 17 00:00:00 2001 From: frikky Date: Sat, 11 Jun 2022 23:23:08 +0200 Subject: [PATCH] Added a way to handle extra apps with default actions --- backend/go-app/go.mod | 2 +- backend/go-app/main.go | 4 + frontend/src/App.jsx | 13 +++ frontend/src/components/ExtraApps.jsx | 27 +++++ frontend/src/components/ParsedAction.jsx | 110 ++++++++++++++++++ frontend/src/components/ShuffleCodeEditor.jsx | 6 +- frontend/src/views/AngularWorkflow.jsx | 44 ++++++- 7 files changed, 197 insertions(+), 9 deletions(-) create mode 100644 frontend/src/components/ExtraApps.jsx diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index a5425e4d..ebc1cfba 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -2,7 +2,7 @@ module main go 1.16 -//replace github.com/shuffle/shuffle-shared => ../../../shuffle-shared +replace github.com/shuffle/shuffle-shared => ../../../shuffle-shared //replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi //replace github.com/frikky/go-elasticsearch => ../../../../git/go-elasticsearch diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 3e3d3630..d15e31f5 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -6100,6 +6100,10 @@ func initHandlers() { r.HandleFunc("/api/v1/users/notifications/clear", shuffle.HandleClearNotifications).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/users/notifications/{notificationId}/markasread", shuffle.HandleMarkAsRead).Methods("GET", "OPTIONS") + //r.HandleFunc("/api/v1/users/notifications/{notificationId}/markasread", shuffle.HandleMarkAsRead).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/dashboards/{key}/widgets", shuffle.HandleNewWidget).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/dashboards/{key}/widgets/{widget_id}", shuffle.HandleGetWidget).Methods("GET", "OPTIONS") + http.Handle("/", r) } diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index a16a3302..440bd00a 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -16,6 +16,7 @@ import Apps from "./views/Apps"; import AppCreator from "./views/AppCreator"; import Dashboard from "./views/Dashboard.jsx"; +import DashboardView from "./views/DashboardViews.jsx"; import AdminSetup from "./views/AdminSetup"; import Admin from "./views/Admin"; import Docs from "./views/Docs"; @@ -644,6 +645,18 @@ const App = (message, props) => { /> } /> + + } + /> '), + "template": true, + "actions": [{ + "name": "Create Alert", + "description": "Create a ticket", + "parameters": [{ + "name": "id", + }, + { + "name": "name", + }, + { + "name": "description", + "multiline": true, + }, + ], + }], +}] + +export default extraApps diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx index e1a8eae8..85e6f560 100644 --- a/frontend/src/components/ParsedAction.jsx +++ b/frontend/src/components/ParsedAction.jsx @@ -1064,6 +1064,8 @@ const ParsedAction = (props) => { */ } + console.log("APP: ", selectedApp) + // FIXME: Issue #40 - selectedActionParameters not reset if ( Object.getOwnPropertyNames(selectedAction).length > 0 && @@ -1090,6 +1092,114 @@ const ParsedAction = (props) => { Parameters + {selectedAction.template === true && selectedAction.matching_actions !== undefined && selectedAction.matching_actions !== null && selectedAction.matching_actions.length > 0 ? +
+ + Select an app you want to use + + { + console.log("LABEL: ", option) + if ( + option === undefined || + option === null || + option.app_name === undefined || + option.app_name === null + ) { + return null; + } + + const newname = ( + option.app_name.charAt(0).toUpperCase() + option.app_name.substring(1) + ).replaceAll("_", " "); + return newname; + }} + options={selectedAction.matching_actions} + fullWidth + style={{ + backgroundColor: theme.palette.inputColor, + height: 50, + borderRadius: theme.palette.borderRadius, + }} + onChange={(event, newValue) => { + console.log("SELECT: ", event, newValue) + // Workaround with event lol + //if (newValue !== undefined && newValue !== null) { + // setNewSelectedAction({ target: { value: newValue.name } }); + //} + }} + renderOption={(data) => { + var newActionname = data.app_name; + if ( + data.label !== undefined && + data.label !== null && + data.label.length > 0 + ) { + newActionname = data.label; + } + + const iconInfo = GetIconInfo({ name: data.app_name }); + const useIcon = iconInfo.originalIcon; + + newActionname = ( + newActionname.charAt(0).toUpperCase() + + newActionname.substring(1) + ).replaceAll("_", " "); + + return ( +
+ + {useIcon} + + {newActionname} +
+ ); + }} + renderInput={(params) => { + if (params.inputProps !== undefined && params.inputProps !== null && params.inputProps.value !== undefined && params.inputProps.value !== null) { + const prefixes = ["Post", "Put", "Patch"] + for (var key in prefixes) { + if (params.inputProps.value.startsWith(prefixes[key])) { + params.inputProps.value = params.inputProps.value.replace(prefixes[key]+" ", "", -1) + if (params.inputProps.value.length > 1) { + params.inputProps.value = params.inputProps.value.charAt(0).toUpperCase()+params.inputProps.value.substring(1) + } + break + } + } + } + + return ( + + ); + }} + /> +
+ : null} {selectedAction.description !== undefined && selectedAction.description !== null && selectedAction.description.length > 0 && hiddenDescription === false ? (
{ > {liquidFilters.map((item, index) => { return ( - { + { handleClick(item) }}>{item.name} ) @@ -486,7 +486,7 @@ const CodeEditor = (props) => { > {mathFilters.map((item, index) => { return ( - { + { handleClick(item) }}>{item.name} ) @@ -521,7 +521,7 @@ const CodeEditor = (props) => { > {pythonFilters.map((item, index) => { return ( - { + { handleClick(item) }}>{item.name} ) diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index 7b1efd02..5cba127e 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -111,6 +111,7 @@ import ConfigureWorkflow from "../components/ConfigureWorkflow.jsx"; import AuthenticationOauth2 from "../components/Oauth2Auth.jsx"; import ParsedAction from "../components/ParsedAction.jsx"; import PaperComponent from "../components/PaperComponent.jsx" +import ExtraApps from "../components/ExtraApps.jsx" const surfaceColor = "#27292D"; const inputColor = "#383B40"; @@ -2509,6 +2510,32 @@ const AngularWorkflow = (defaultprops) => { (a.loop_versions !== null && a.loop_versions.includes(curaction.app_version))) ); + + if (curaction.template === true) { + //newapps. + const parsedname = curaction.name.replaceAll(" ", "_").toLowerCase() + console.log("FIND AN ACTION AMONG THE APPS THAT MATCHES NAME: ", parsedname) + + curaction.matching_actions = [] + for (var key in newapps) { + for (var subkey in newapps[key].actions) { + const tmpaction = newapps[key].actions[subkey] + if (tmpaction.name.replaceAll(" ", "_").toLowerCase() === parsedname) { + console.log("MATCH!: ", newapps[key]) + curaction.matching_actions.push({ + "app_name": newapps[key].name, + "app_version": newapps[key].app_version, + "app_id": newapps[key].id, + "action": tmpaction, + "large_image": newapps[key].large_image, + "app_index": key, + "action_index": subkey, + }) + } + } + } + } + if (!curapp || curapp === undefined) { console.log("APPS: ", newapps) //alert.error(`App ${curaction.app_name}:${curaction.app_version} not found. Is it activated?`); @@ -4983,6 +5010,7 @@ const AngularWorkflow = (defaultprops) => { var thisview = ( @@ -5337,7 +5365,7 @@ const AngularWorkflow = (defaultprops) => { } // AUTHENTICATION - if (app.authentication.required) { + if (app.authentication !== undefined && app.authentication !== null && app.authentication.required === true) { console.log("App auth is required!") // Setup auth here :) @@ -5462,6 +5490,7 @@ const AngularWorkflow = (defaultprops) => { var description = "" if ( + app.actions[0].parameters !== undefined && app.actions[0].parameters !== null && app.actions[0].parameters.length > 0 ) { @@ -5469,6 +5498,8 @@ const AngularWorkflow = (defaultprops) => { } if ( + app.actions[0].returns !== undefined && + app.actions[0].returns !== null && app.actions[0].returns.example !== undefined && app.actions[0].returns.example !== null && app.actions[0].returns.example.length > 0 @@ -5524,6 +5555,7 @@ const AngularWorkflow = (defaultprops) => { : "", authentication_id: "", finished: false, + template: app.template === true ? true : false, }; // FIXME: overwrite category if the ACTION chosen has a different category @@ -5548,10 +5580,12 @@ const AngularWorkflow = (defaultprops) => { }; const AppView = (props) => { - const { allApps, prioritizedApps, filteredApps } = props; + const { allApps, prioritizedApps, filteredApps, extraApps } = props; + //extraApps, const [visibleApps, setVisibleApps] = React.useState( - prioritizedApps.concat( - filteredApps.filter((innerapp) => !internalIds.includes(innerapp.id)) + Array.prototype.concat.apply( + prioritizedApps, + filteredApps.filter((innerapp) => !internalIds.includes(innerapp.id)), ) ); @@ -5841,7 +5875,7 @@ const AngularWorkflow = (defaultprops) => { runSearch(event.target.value); }} /> - {visibleApps.length > 0 ? ( + {visibleApps.length > extraApps.length ? (
{visibleApps.map((app, index) => { if (app.invalid) {