mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-23 08:58:26 +00:00
Merge branch 'main' into fix/appbuilder-03
This commit is contained in:
commit
8133199d58
15 changed files with 75 additions and 38 deletions
14
.github/workflows/docker-release.yml
vendored
14
.github/workflows/docker-release.yml
vendored
|
|
@ -21,7 +21,7 @@ jobs:
|
|||
if: "contains(github.event.release.tag_name, '-ce-lts')"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: refs/heads/lts-3.6
|
||||
ref: refs/heads/lts-3.16
|
||||
|
||||
# Create Docker Buildx builder with platform configuration
|
||||
- name: Set up Docker Buildx
|
||||
|
|
@ -108,7 +108,7 @@ jobs:
|
|||
if: "contains(github.event.release.tag_name, '-ee-lts')"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: refs/heads/lts-3.6
|
||||
ref: refs/heads/lts-3.16
|
||||
|
||||
# Create Docker Buildx builder with platform configuration
|
||||
- name: Set up Docker Buildx
|
||||
|
|
@ -155,7 +155,7 @@ jobs:
|
|||
context: .
|
||||
build-args: |
|
||||
CUSTOM_GITHUB_TOKEN=${{ secrets.CUSTOM_GITHUB_TOKEN }}
|
||||
BRANCH_NAME=lts-3.6
|
||||
BRANCH_NAME=lts-3.16
|
||||
file: docker/ee/ee-production.Dockerfile
|
||||
push: true
|
||||
tags: tooljet/tooljet-ee:${{ github.event.release.tag_name }},tooljet/tooljet-ee:ee-lts-latest,tooljet/tooljet:ee-lts-latest,tooljet/tooljet:${{ github.event.release.tag_name }}
|
||||
|
|
@ -185,7 +185,7 @@ jobs:
|
|||
if: "contains(github.event.release.tag_name, '-cloud-lts')"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: refs/heads/lts-3.6
|
||||
ref: refs/heads/lts-3.16
|
||||
|
||||
# Create Docker Buildx builder with platform configuration
|
||||
- name: Set up Docker Buildx
|
||||
|
|
@ -215,7 +215,7 @@ jobs:
|
|||
context: .
|
||||
build-args: |
|
||||
CUSTOM_GITHUB_TOKEN=${{ secrets.CUSTOM_GITHUB_TOKEN }}
|
||||
BRANCH_NAME=lts-3.6
|
||||
BRANCH_NAME=lts-3.16
|
||||
file: docker/cloud/cloud-server.Dockerfile
|
||||
push: true
|
||||
tags: tooljet/saas:${{ github.event.release.tag_name }}
|
||||
|
|
@ -247,11 +247,11 @@ jobs:
|
|||
with:
|
||||
ref: refs/heads/main
|
||||
|
||||
- name: Checkout code to lts-3.0
|
||||
- name: Checkout code to lts-3.16
|
||||
if: contains(github.event.release.tag_name, '-ee-lts')
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: refs/heads/lts-3.0
|
||||
ref: refs/heads/lts-3.16
|
||||
|
||||
# Create Docker Buildx builder with platform configuration
|
||||
- name: Set up Docker Buildx
|
||||
|
|
|
|||
4
.github/workflows/packer-build.yml
vendored
4
.github/workflows/packer-build.yml
vendored
|
|
@ -16,11 +16,11 @@ jobs:
|
|||
name: packer-ee
|
||||
|
||||
steps:
|
||||
- name: Checkout code to lts-3.6 branch
|
||||
- name: Checkout code to lts-3.16 branch
|
||||
if: contains(github.event.release.tag_name, '-ee-lts')
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: refs/heads/lts-3.6
|
||||
ref: refs/heads/lts-3.16
|
||||
|
||||
- name: Setting tag
|
||||
if: "${{ github.event.inputs.version != '' }}"
|
||||
|
|
|
|||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
|
@ -8,8 +8,8 @@
|
|||
"typescript",
|
||||
"typescriptreact"
|
||||
],
|
||||
"eslint.format.enable": true,
|
||||
"editor.formatOnSave": true,
|
||||
"eslint.format.enable": false,
|
||||
"editor.formatOnSave": false,
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": [
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 245477ce5361e7ce2ade3056cb0c17a78a8fc6ec
|
||||
Subproject commit 35fb9f47811a315c9ab8f3daa1a71cd804ba1215
|
||||
|
|
@ -34,6 +34,7 @@ const initialState = {
|
|||
showDeleteConfirmation: false,
|
||||
renamingQueryId: null,
|
||||
deletingQueryId: null,
|
||||
asyncQueryRuns: [],
|
||||
};
|
||||
|
||||
export const createQueryPanelSlice = (set, get) => ({
|
||||
|
|
|
|||
|
|
@ -94,6 +94,11 @@ export const AppMenu = function AppMenu({
|
|||
<Field text={appType === 'module' ? 'Export module' : 'Export app'} onClick={exportApp} />
|
||||
</>
|
||||
)}
|
||||
{canUpdateApp && canCreateApp && appType === 'workflow' && (
|
||||
<>
|
||||
<Field text={'Export workflow'} onClick={exportApp} />
|
||||
</>
|
||||
)}
|
||||
{canDeleteApp && (
|
||||
<Field
|
||||
text={
|
||||
|
|
|
|||
|
|
@ -478,7 +478,7 @@ class HomePageComponent extends React.Component {
|
|||
let installedPluginsInfo = [];
|
||||
try {
|
||||
if (this.state.dependentPlugins.length) {
|
||||
({ installedPluginsInfo =[] } = await pluginsService.installDependentPlugins(
|
||||
({ installedPluginsInfo = [] } = await pluginsService.installDependentPlugins(
|
||||
this.state.dependentPlugins,
|
||||
true
|
||||
));
|
||||
|
|
@ -486,7 +486,8 @@ class HomePageComponent extends React.Component {
|
|||
|
||||
if (importJSON.app[0].definition.appV2.type !== this.props.appType) {
|
||||
toast.error(
|
||||
`${this.props.appType === 'module' ? 'App' : 'Module'} could not be imported in ${this.props.appType === 'module' ? 'modules' : 'apps'
|
||||
`${this.props.appType === 'module' ? 'App' : 'Module'} could not be imported in ${
|
||||
this.props.appType === 'module' ? 'modules' : 'apps'
|
||||
} section. Switch to ${this.props.appType === 'module' ? 'apps' : 'modules'} section and try again.`,
|
||||
{ style: { maxWidth: '425px' } }
|
||||
);
|
||||
|
|
@ -495,7 +496,7 @@ class HomePageComponent extends React.Component {
|
|||
}
|
||||
|
||||
const data = await appsService.importResource(requestBody, this.props.appType);
|
||||
toast.success(`${this.props.appType === 'module' ? 'Module' : 'App'} imported successfully.`);
|
||||
toast.success(`${this.getAppType()} imported successfully.`);
|
||||
this.setState({ isImportingApp: false });
|
||||
|
||||
if (!isEmpty(data.imports.app)) {
|
||||
|
|
@ -1154,13 +1155,14 @@ class HomePageComponent extends React.Component {
|
|||
closeModal: () => 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 {
|
|||
|
||||
<div className="groups-list">
|
||||
<div
|
||||
className={`border rounded text-sm container ${missingGroupsExpanded ? 'max-h-48 overflow-y-auto' : ''
|
||||
}`}
|
||||
className={`border rounded text-sm container ${
|
||||
missingGroupsExpanded ? 'max-h-48 overflow-y-auto' : ''
|
||||
}`}
|
||||
>
|
||||
<div style={{ color: 'var(--text-placeholder)' }} className="tj-text-xsm font-weight-500">
|
||||
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'
|
||||
)}
|
||||
</>
|
||||
</Button>
|
||||
<Dropdown.Toggle
|
||||
|
|
@ -1631,8 +1635,8 @@ class HomePageComponent extends React.Component {
|
|||
classes="mb-3 small"
|
||||
limits={
|
||||
workflowInstanceLevelLimit.current >= 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ const BaseImportAppMenu = ({
|
|||
const { t } = useTranslation();
|
||||
return (
|
||||
<Dropdown.Menu className="import-lg-position new-app-dropdown">
|
||||
{appType !== 'wzorkflow' && appType !== 'module' && (
|
||||
{appType !== 'workflow' && appType !== 'module' && (
|
||||
<Dropdown.Item
|
||||
className="homepage-dropdown-style tj-text tj-text-xsm"
|
||||
onClick={showTemplateLibraryModal}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit f07d4f66de3e25fe5b1dc7c6d3f1226ad00a1f0c
|
||||
Subproject commit 0fbde4b3030aa2117b7b8b024d11c5e175e4302a
|
||||
|
|
@ -32,6 +32,7 @@ export function defineWorkflowAbility(
|
|||
FEATURE_KEY.RELEASE,
|
||||
FEATURE_KEY.VALIDATE_PRIVATE_APP_ACCESS,
|
||||
FEATURE_KEY.VALIDATE_RELEASED_APP_ACCESS,
|
||||
FEATURE_KEY.UPDATE_ICON,
|
||||
],
|
||||
App
|
||||
);
|
||||
|
|
@ -56,6 +57,7 @@ export function defineWorkflowAbility(
|
|||
FEATURE_KEY.RELEASE,
|
||||
FEATURE_KEY.VALIDATE_PRIVATE_APP_ACCESS,
|
||||
FEATURE_KEY.VALIDATE_RELEASED_APP_ACCESS,
|
||||
FEATURE_KEY.UPDATE_ICON,
|
||||
],
|
||||
App
|
||||
);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ export class AppsModule extends SubModule {
|
|||
'services/page.util.service',
|
||||
]);
|
||||
|
||||
const { AppsActionsListener, TemporalService } = await this.getProviders(configs, 'workflows', [
|
||||
'listeners/app-actions.listener',
|
||||
'services/temporal.service',
|
||||
]);
|
||||
|
||||
return {
|
||||
module: AppsModule,
|
||||
imports: [
|
||||
|
|
@ -74,6 +79,8 @@ export class AppsModule extends SubModule {
|
|||
VersionRepository,
|
||||
AppsRepository,
|
||||
AppGitRepository,
|
||||
AppsActionsListener,
|
||||
TemporalService,
|
||||
PageService,
|
||||
EventsService,
|
||||
AppsUtilService,
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import { AUDIT_LOGS_REQUEST_CONTEXT_KEY } from '@modules/app/constants';
|
|||
import { MODULES } from '@modules/app/constants/modules';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { AppGitRepository } from '@modules/app-git/repository';
|
||||
import { WorkflowSchedule } from '@entities/workflow_schedule.entity';
|
||||
|
||||
@Injectable()
|
||||
export class AppsService implements IAppsService {
|
||||
|
|
@ -181,7 +182,24 @@ export class AppsService implements IAppsService {
|
|||
const { organizationId } = user;
|
||||
const { id } = app;
|
||||
|
||||
await this.appRepository.delete({ id, organizationId });
|
||||
await dbTransactionWrap(async (manager: EntityManager) => {
|
||||
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, {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { LicenseUserService } from '@modules/licensing/services/user.service';
|
|||
import { RolesUtilService } from '@modules/roles/util.service';
|
||||
import { OrganizationUser } from '../../entities/organization_user.entity';
|
||||
import { generateNextNameAndSlug } from 'src/helpers/utils.helper';
|
||||
const uuid = require('uuid');
|
||||
import * as uuid from 'uuid';
|
||||
import { Organization } from '../../entities/organization.entity';
|
||||
import { EntityManager } from 'typeorm';
|
||||
import {
|
||||
|
|
@ -121,7 +121,7 @@ export class AuthUtilService implements IAuthUtilService {
|
|||
try {
|
||||
const signedJwt = this.sessionUtilService.verifyToken(token);
|
||||
return signedJwt;
|
||||
} catch (err) {
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ export class UserRepository extends Repository<User> {
|
|||
const existingUser = await manager.findOne(User, { where: { email: user.email } });
|
||||
|
||||
if (existingUser) {
|
||||
Object.assign(existingUser, user);
|
||||
return manager.update(User, { id: existingUser.id }, user);
|
||||
await manager.update(User, { id: existingUser.id }, user);
|
||||
return manager.findOne(User, { where: { id: existingUser.id } });
|
||||
} else {
|
||||
const newUser = manager.create(User, user);
|
||||
return manager.save(User, newUser);
|
||||
|
|
|
|||
|
|
@ -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.`);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue