1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-06-27 01:19:00 +02:00

feat: features overwrite warning (#4535)

This commit is contained in:
Mateusz Kwasniewski 2023-08-21 11:09:09 +02:00 committed by GitHub
parent f114aa401a
commit 2cfb99c768
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 43 additions and 1 deletions

View File

@ -335,6 +335,11 @@ test('validate import data', async () => {
'The following features will not be imported as they are currently archived. To import them, please unarchive them first:', 'The following features will not be imported as they are currently archived. To import them, please unarchive them first:',
affectedItems: [archivedFeature], affectedItems: [archivedFeature],
}, },
{
message:
'The following features already exist in this project and will be overwritten:',
affectedItems: ['existing_feature'],
},
], ],
permissions: [ permissions: [
{ {

View File

@ -151,6 +151,7 @@ export default class ExportImportService {
unsupportedContextFields, unsupportedContextFields,
archivedFeatures, archivedFeatures,
otherProjectFeatures, otherProjectFeatures,
existingProjectFeatures,
missingPermissions, missingPermissions,
] = await Promise.all([ ] = await Promise.all([
this.getUnsupportedStrategies(dto), this.getUnsupportedStrategies(dto),
@ -158,6 +159,7 @@ export default class ExportImportService {
this.getUnsupportedContextFields(dto), this.getUnsupportedContextFields(dto),
this.getArchivedFeatures(dto), this.getArchivedFeatures(dto),
this.getOtherProjectFeatures(dto), this.getOtherProjectFeatures(dto),
this.getExistingProjectFeatures(dto),
this.importPermissionsService.getMissingPermissions( this.importPermissionsService.getMissingPermissions(
dto, dto,
user, user,
@ -176,6 +178,7 @@ export default class ExportImportService {
const warnings = ImportValidationMessages.compileWarnings( const warnings = ImportValidationMessages.compileWarnings(
usedCustomStrategies, usedCustomStrategies,
archivedFeatures, archivedFeatures,
existingProjectFeatures,
); );
const permissions = const permissions =
ImportValidationMessages.compilePermissionErrors( ImportValidationMessages.compilePermissionErrors(
@ -299,7 +302,7 @@ export default class ExportImportService {
this.contextService.createContextField( this.contextService.createContextField(
{ {
name: contextField.name, name: contextField.name,
description: contextField.description, description: contextField.description || '',
legalValues: contextField.legalValues, legalValues: contextField.legalValues,
stickiness: contextField.stickiness, stickiness: contextField.stickiness,
}, },
@ -529,6 +532,15 @@ export default class ExportImportService {
); );
} }
private async getExistingProjectFeatures(dto: ImportTogglesSchema) {
const existingProjectsFeatures =
await this.importTogglesStore.getFeaturesInProject(
dto.data.features.map((feature) => feature.name),
dto.project,
);
return existingProjectsFeatures;
}
private async getNewTagTypes(dto: ImportTogglesSchema) { private async getNewTagTypes(dto: ImportTogglesSchema) {
const existingTagTypes = (await this.tagTypeService.getAll()).map( const existingTagTypes = (await this.tagTypeService.getAll()).map(
(tagType) => tagType.name, (tagType) => tagType.name,

View File

@ -11,6 +11,11 @@ export interface IImportTogglesStore {
project: string, project: string,
): Promise<{ name: string; project: string }[]>; ): Promise<{ name: string; project: string }[]>;
getFeaturesInProject(
featureNames: string[],
project: string,
): Promise<string[]>;
deleteTagsForFeatures(tags: string[]): Promise<void>; deleteTagsForFeatures(tags: string[]): Promise<void>;
strategiesExistForFeatures( strategiesExistForFeatures(

View File

@ -74,6 +74,18 @@ export class ImportTogglesStore implements IImportTogglesStore {
return rows.map((row) => ({ name: row.name, project: row.project })); return rows.map((row) => ({ name: row.name, project: row.project }));
} }
async getFeaturesInProject(
featureNames: string[],
project: string,
): Promise<string[]> {
const rows = await this.db(T.features)
.select(['name', 'project'])
.where('project', project)
.where('archived_at', null)
.whereIn('name', featureNames);
return rows.map((row) => row.name);
}
async deleteTagsForFeatures(features: string[]): Promise<void> { async deleteTagsForFeatures(features: string[]): Promise<void> {
return this.db(T.featureTag).whereIn('feature_name', features).del(); return this.db(T.featureTag).whereIn('feature_name', features).del();
} }

View File

@ -73,6 +73,7 @@ export class ImportValidationMessages {
static compileWarnings( static compileWarnings(
usedCustomStrategies: string[], usedCustomStrategies: string[],
archivedFeatures: string[], archivedFeatures: string[],
existingFeatures: string[],
): ImportTogglesValidateItemSchema[] { ): ImportTogglesValidateItemSchema[] {
const warnings: ImportTogglesValidateItemSchema[] = []; const warnings: ImportTogglesValidateItemSchema[] = [];
if (usedCustomStrategies.length > 0) { if (usedCustomStrategies.length > 0) {
@ -89,6 +90,13 @@ export class ImportValidationMessages {
affectedItems: archivedFeatures, affectedItems: archivedFeatures,
}); });
} }
if (existingFeatures.length > 0) {
warnings.push({
message:
'The following features already exist in this project and will be overwritten:',
affectedItems: existingFeatures,
});
}
return warnings; return warnings;
} }
} }