Fix app design 1/2 (#19735)
comply with https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=96977-349627&m=dev ## After <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 40 37" src="https://github.com/user-attachments/assets/6d80191a-79a9-4f0f-aa4f-0e447fff4f6d" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 40 22" src="https://github.com/user-attachments/assets/4f763272-027e-4246-b455-7d46babf7d8c" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 39 11" src="https://github.com/user-attachments/assets/b9b35e18-8068-447e-821d-5ec28bb5bd16" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 39 05" src="https://github.com/user-attachments/assets/57d9318a-902f-4fd7-a2a3-5795ebe0b9dc" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 39 02" src="https://github.com/user-attachments/assets/78a33fa8-6bdd-484e-a82d-bd0f7592a623" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 38 58" src="https://github.com/user-attachments/assets/f7987aed-c6e1-4032-a611-86817655137d" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 38 55" src="https://github.com/user-attachments/assets/d1c451ab-1d2d-41e4-a059-cf4303ecabe7" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 38 48" src="https://github.com/user-attachments/assets/593cae36-2320-443f-a955-93b211a6ee3f" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 37 40" src="https://github.com/user-attachments/assets/c9f602b1-8de3-4e82-a3a6-344594a0c153" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 37 34" src="https://github.com/user-attachments/assets/b54ddddf-5dda-46c8-ace3-cffe6015825a" /> ## before <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42 18" src="https://github.com/user-attachments/assets/c0976a0a-0124-48ec-8e7c-78627cea7063" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42 16" src="https://github.com/user-attachments/assets/d2db926c-4040-411d-9091-8b60e7c519e6" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42 13" src="https://github.com/user-attachments/assets/2d69f2ff-f26e-4249-91a3-2cf3d261e840" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42 07" src="https://github.com/user-attachments/assets/1028aabc-77ac-4c51-a8c3-9a194faba87f" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 42 01" src="https://github.com/user-attachments/assets/1caa9f5e-3eaa-433c-9d3b-e0f094f16e8e" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 41 56" src="https://github.com/user-attachments/assets/f42b6976-3a8f-4591-9283-bda79bdb424b" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 41 53" src="https://github.com/user-attachments/assets/93d00df8-0091-4dfa-9ac0-f6f376be5962" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 41 43" src="https://github.com/user-attachments/assets/9deae7e5-39c1-4518-a463-6d79bc5bf132" /> <img width="1512" height="909" alt="Capture d’écran 2026-04-16 à 09 41 37" src="https://github.com/user-attachments/assets/3e21b521-c47d-482c-ad41-66abfe973772" />
This commit is contained in:
+4
@@ -90,6 +90,10 @@ export class ApplicationRegistrationVariableService {
|
||||
updateData.encryptedValue = this.encryptionService.encrypt(update.value);
|
||||
}
|
||||
|
||||
if (isDefined(update.resetValue) && update.resetValue) {
|
||||
updateData.encryptedValue = '';
|
||||
}
|
||||
|
||||
if (isDefined(update.description)) {
|
||||
updateData.description = update.description;
|
||||
}
|
||||
|
||||
+4
@@ -18,6 +18,10 @@ export class UpdateApplicationRegistrationVariablePayload {
|
||||
@IsOptional()
|
||||
value?: string;
|
||||
|
||||
@Field({ nullable: true })
|
||||
@IsOptional()
|
||||
resetValue?: boolean;
|
||||
|
||||
@Field({ nullable: true })
|
||||
@IsString()
|
||||
@MaxLength(2000)
|
||||
|
||||
-1
@@ -60,7 +60,6 @@ export class ApplicationRegistrationResolver {
|
||||
private readonly applicationRegistrationVariableService: ApplicationRegistrationVariableService,
|
||||
private readonly applicationTarballService: ApplicationTarballService,
|
||||
private readonly fileUrlService: FileUrlService,
|
||||
private readonly domainServerConfigService: DomainServerConfigService,
|
||||
) {}
|
||||
|
||||
@UseGuards(PublicEndpointGuard, NoPermissionGuard)
|
||||
|
||||
+36
-16
@@ -24,6 +24,7 @@ import { ApplicationRegistrationSourceType } from 'src/engine/core-modules/appli
|
||||
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import { validateRedirectUri } from 'src/engine/core-modules/auth/utils/validate-redirect-uri.util';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { ApplicationRegistrationVariableService } from 'src/engine/core-modules/application/application-registration-variable/application-registration-variable.service';
|
||||
const BCRYPT_SALT_ROUNDS = 10;
|
||||
|
||||
@Injectable()
|
||||
@@ -35,6 +36,7 @@ export class ApplicationRegistrationService {
|
||||
private readonly applicationRepository: Repository<ApplicationEntity>,
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
private readonly applicationRegistrationVariableService: ApplicationRegistrationVariableService,
|
||||
) {}
|
||||
|
||||
async findMany(
|
||||
@@ -288,26 +290,41 @@ export class ApplicationRegistrationService {
|
||||
isListed: params.isListed,
|
||||
isFeatured: params.isFeatured,
|
||||
});
|
||||
} else {
|
||||
const registration = this.applicationRegistrationRepository.create({
|
||||
universalIdentifier: params.universalIdentifier,
|
||||
name: params.name,
|
||||
sourceType: params.sourceType,
|
||||
sourcePackage: params.sourcePackage,
|
||||
latestAvailableVersion: params.latestAvailableVersion,
|
||||
isListed: params.isListed,
|
||||
isFeatured: params.isFeatured,
|
||||
manifest: params.manifest,
|
||||
oAuthClientId: v4(),
|
||||
oAuthRedirectUris: [],
|
||||
oAuthScopes: [],
|
||||
ownerWorkspaceId: params.ownerWorkspaceId,
|
||||
});
|
||||
|
||||
await this.applicationRegistrationRepository.save(registration);
|
||||
}
|
||||
|
||||
if (!isDefined(params.manifest?.application?.serverVariables)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const registration = this.applicationRegistrationRepository.create({
|
||||
universalIdentifier: params.universalIdentifier,
|
||||
name: params.name,
|
||||
sourceType: params.sourceType,
|
||||
sourcePackage: params.sourcePackage,
|
||||
latestAvailableVersion: params.latestAvailableVersion,
|
||||
isListed: params.isListed,
|
||||
isFeatured: params.isFeatured,
|
||||
manifest: params.manifest,
|
||||
oAuthClientId: v4(),
|
||||
oAuthRedirectUris: [],
|
||||
oAuthScopes: [],
|
||||
ownerWorkspaceId: params.ownerWorkspaceId,
|
||||
});
|
||||
const registration = await this.findOneByUniversalIdentifier(
|
||||
params.universalIdentifier,
|
||||
);
|
||||
|
||||
await this.applicationRegistrationRepository.save(registration);
|
||||
if (!isDefined(registration)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.applicationRegistrationVariableService.syncVariableSchemas(
|
||||
registration.id,
|
||||
params.manifest.application.serverVariables,
|
||||
);
|
||||
}
|
||||
|
||||
async createCliRegistrationIfNotExists(): Promise<ApplicationRegistrationEntity | null> {
|
||||
@@ -337,7 +354,10 @@ export class ApplicationRegistrationService {
|
||||
|
||||
async findManyListed(): Promise<ApplicationRegistrationEntity[]> {
|
||||
return this.applicationRegistrationRepository.find({
|
||||
where: { isListed: true },
|
||||
where: {
|
||||
isListed: true,
|
||||
sourceType: ApplicationRegistrationSourceType.NPM,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+11
-4
@@ -22,6 +22,8 @@ import { readJsonFile } from 'src/engine/core-modules/application/application-pa
|
||||
import { resolvePackageContentDir } from 'src/engine/core-modules/application/application-package/utils/tarball-utils';
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
|
||||
import type { ApplicationManifest } from 'twenty-shared/application';
|
||||
import { ApplicationRegistrationVariableService } from 'src/engine/core-modules/application/application-registration-variable/application-registration-variable.service';
|
||||
|
||||
export const MAX_TARBALL_UPLOAD_SIZE_BYTES = 50 * 1024 * 1024;
|
||||
|
||||
@@ -34,6 +36,7 @@ export class ApplicationTarballService {
|
||||
private readonly appRegistrationRepository: Repository<ApplicationRegistrationEntity>,
|
||||
private readonly fileStorageService: FileStorageService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly applicationRegistrationVariableService: ApplicationRegistrationVariableService,
|
||||
) {}
|
||||
|
||||
async uploadTarball(params: {
|
||||
@@ -58,10 +61,7 @@ export class ApplicationTarballService {
|
||||
const contentDir = await resolvePackageContentDir(extractDir);
|
||||
|
||||
const manifest = await readJsonFile<{
|
||||
application?: {
|
||||
universalIdentifier?: string;
|
||||
displayName?: string;
|
||||
};
|
||||
application?: ApplicationManifest;
|
||||
}>(contentDir, 'manifest.json');
|
||||
|
||||
const packageJson = await readJsonFile<{
|
||||
@@ -181,6 +181,13 @@ export class ApplicationTarballService {
|
||||
ownerWorkspaceId: params.ownerWorkspaceId,
|
||||
});
|
||||
|
||||
if (manifest.application?.serverVariables) {
|
||||
await this.applicationRegistrationVariableService.syncVariableSchemas(
|
||||
appRegistration.id,
|
||||
manifest.application.serverVariables,
|
||||
);
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
`Tarball uploaded for app ${universalIdentifier} (registration ${appRegistration.id})`,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user