1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-08 01:15:49 +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:',
affectedItems: [archivedFeature],
},
{
message:
'The following features already exist in this project and will be overwritten:',
affectedItems: ['existing_feature'],
},
],
permissions: [
{

View File

@ -151,6 +151,7 @@ export default class ExportImportService {
unsupportedContextFields,
archivedFeatures,
otherProjectFeatures,
existingProjectFeatures,
missingPermissions,
] = await Promise.all([
this.getUnsupportedStrategies(dto),
@ -158,6 +159,7 @@ export default class ExportImportService {
this.getUnsupportedContextFields(dto),
this.getArchivedFeatures(dto),
this.getOtherProjectFeatures(dto),
this.getExistingProjectFeatures(dto),
this.importPermissionsService.getMissingPermissions(
dto,
user,
@ -176,6 +178,7 @@ export default class ExportImportService {
const warnings = ImportValidationMessages.compileWarnings(
usedCustomStrategies,
archivedFeatures,
existingProjectFeatures,
);
const permissions =
ImportValidationMessages.compilePermissionErrors(
@ -299,7 +302,7 @@ export default class ExportImportService {
this.contextService.createContextField(
{
name: contextField.name,
description: contextField.description,
description: contextField.description || '',
legalValues: contextField.legalValues,
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) {
const existingTagTypes = (await this.tagTypeService.getAll()).map(
(tagType) => tagType.name,

View File

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

View File

@ -74,6 +74,18 @@ export class ImportTogglesStore implements IImportTogglesStore {
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> {
return this.db(T.featureTag).whereIn('feature_name', features).del();
}

View File

@ -73,6 +73,7 @@ export class ImportValidationMessages {
static compileWarnings(
usedCustomStrategies: string[],
archivedFeatures: string[],
existingFeatures: string[],
): ImportTogglesValidateItemSchema[] {
const warnings: ImportTogglesValidateItemSchema[] = [];
if (usedCustomStrategies.length > 0) {
@ -89,6 +90,13 @@ export class ImportValidationMessages {
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;
}
}