diff --git a/frontend/ee b/frontend/ee index 113d2ec552..5ebcf5ccda 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit 113d2ec5525571afd0a08187552a5b0d0979ecc3 +Subproject commit 5ebcf5ccda1d11cb73e77b9a9bf71c16e1404c7b diff --git a/frontend/src/AppBuilder/_stores/slices/queryPanelSlice.js b/frontend/src/AppBuilder/_stores/slices/queryPanelSlice.js index 47d425a0c0..27052d3603 100644 --- a/frontend/src/AppBuilder/_stores/slices/queryPanelSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/queryPanelSlice.js @@ -34,6 +34,7 @@ const initialState = { showDeleteConfirmation: false, renamingQueryId: null, deletingQueryId: null, + asyncQueryRuns: [], }; export const createQueryPanelSlice = (set, get) => ({ diff --git a/frontend/src/HomePage/AppMenu.jsx b/frontend/src/HomePage/AppMenu.jsx index 6c2a521c57..0bfa96583e 100644 --- a/frontend/src/HomePage/AppMenu.jsx +++ b/frontend/src/HomePage/AppMenu.jsx @@ -94,6 +94,11 @@ export const AppMenu = function AppMenu({ )} + {canUpdateApp && canCreateApp && appType === 'workflow' && ( + <> + + + )} {canDeleteApp && ( this.setState({ showImportAppModal: false }), processApp: this.importFile, show: this.openImportAppModal, - title: 'Import app', - actionButton: 'Import app', + title: `Import ${this.getAppType().toLocaleLowerCase()}`, + actionButton: `Import ${this.getAppType().toLocaleLowerCase()}`, actionLoadingButton: 'Importing', fileContent: fileContent, selectedAppName: fileName, dependentPluginsDetail: dependentPluginsDetail, dependentPlugins: dependentPlugins, + appType: this.props.appType, }, template: { modalType: 'template', @@ -1224,8 +1226,9 @@ class HomePageComponent extends React.Component {
User groups @@ -1301,8 +1304,8 @@ class HomePageComponent extends React.Component { this.props.appType === 'workflow' ? 'homePage.deleteWorkflowAndData' : this.props.appType === 'front-end' - ? 'homePage.deleteAppAndData' - : deleteModuleText, + ? 'homePage.deleteAppAndData' + : deleteModuleText, { appName: appToBeDeleted?.name, } @@ -1567,10 +1570,11 @@ class HomePageComponent extends React.Component { {this.props.appType === 'module' ? 'Create new module' : this.props.t( - `${this.props.appType === 'workflow' ? 'workflowsDashboard' : 'homePage' - }.header.createNewApplication`, - 'Create new app' - )} + `${ + this.props.appType === 'workflow' ? 'workflowsDashboard' : 'homePage' + }.header.createNewApplication`, + 'Create new app' + )} = workflowInstanceLevelLimit.total || - 100 > workflowInstanceLevelLimit.percentage >= 90 || - workflowInstanceLevelLimit.current === workflowInstanceLevelLimit.total - 1 + 100 > workflowInstanceLevelLimit.percentage >= 90 || + workflowInstanceLevelLimit.current === workflowInstanceLevelLimit.total - 1 ? workflowInstanceLevelLimit : workflowWorkspaceLevelLimit } @@ -1726,8 +1730,8 @@ class HomePageComponent extends React.Component { appType={this.props.appType} workflowsLimit={ workflowInstanceLevelLimit.current >= workflowInstanceLevelLimit.total || - 100 > workflowInstanceLevelLimit.percentage >= 90 || - workflowInstanceLevelLimit.current === workflowInstanceLevelLimit.total - 1 + 100 > workflowInstanceLevelLimit.percentage >= 90 || + workflowInstanceLevelLimit.current === workflowInstanceLevelLimit.total - 1 ? workflowInstanceLevelLimit : workflowWorkspaceLevelLimit } diff --git a/frontend/src/modules/common/components/BaseImportAppMenu/BaseImportAppMenu.jsx b/frontend/src/modules/common/components/BaseImportAppMenu/BaseImportAppMenu.jsx index 85a6c25b8d..4808ca46b5 100644 --- a/frontend/src/modules/common/components/BaseImportAppMenu/BaseImportAppMenu.jsx +++ b/frontend/src/modules/common/components/BaseImportAppMenu/BaseImportAppMenu.jsx @@ -17,7 +17,7 @@ const BaseImportAppMenu = ({ const { t } = useTranslation(); return ( - {appType !== 'wzorkflow' && appType !== 'module' && ( + {appType !== 'workflow' && appType !== 'module' && ( { + const schedules = await manager + .createQueryBuilder(WorkflowSchedule, 'workflowSchedule') + .innerJoinAndSelect('workflowSchedule.workflow', 'appVersion') + .where('appVersion.appId = :appId', { appId: id }) + .getMany(); + + // Emit event with schedule IDs for temporal schedule cleanup + if (schedules.length > 0) { + const scheduleIds = schedules.map((schedule) => schedule.id); + this.eventEmitter.emit('app.deleted', { + appId: id, + scheduleIds: scheduleIds, + }); + } + + await manager.delete(App, { id, organizationId }); + }); //APP_DELETE audit RequestContext.setLocals(AUDIT_LOGS_REQUEST_CONTEXT_KEY, { diff --git a/server/src/modules/workflows/listeners/app-deletion.listener.ts b/server/src/modules/workflows/listeners/app-actions.listener.ts similarity index 71% rename from server/src/modules/workflows/listeners/app-deletion.listener.ts rename to server/src/modules/workflows/listeners/app-actions.listener.ts index 302bd36b86..72d28d991e 100644 --- a/server/src/modules/workflows/listeners/app-deletion.listener.ts +++ b/server/src/modules/workflows/listeners/app-actions.listener.ts @@ -4,8 +4,8 @@ import { OnEvent } from '@nestjs/event-emitter'; @Injectable() export class AppsActionsListener { constructor() {} - @OnEvent('beforeAppDelete') + @OnEvent('app.deleted') async handleAppDeletion(args: { appId: string }) { - throw new Error('Method not implemented'); + console.log(`App with ID ${args.appId} has been deleted.`); } }