1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-04-01 01:18:10 +02:00

feat: Default project mode open (#3316)

This commit is contained in:
Mateusz Kwasniewski 2023-03-15 12:28:06 +01:00 committed by GitHub
parent 647f75fa8b
commit 9fd84abaa5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 20 deletions

View File

@ -133,8 +133,11 @@ class ProjectStore implements IProjectStore {
const memberMap = new Map<string, number>(
memberCount.map((c) => [c.project, Number(c.count)]),
);
return projectsWithFeatureCount.map((r) => {
return { ...r, memberCount: memberMap.get(r.id) };
return projectsWithFeatureCount.map((projectWithCount) => {
return {
...projectWithCount,
memberCount: memberMap.get(projectWithCount.id) || 0,
};
});
}
@ -149,6 +152,7 @@ class ProjectStore implements IProjectStore {
featureCount: Number(row.number_of_features) || 0,
memberCount: Number(row.number_of_users) || 0,
updatedAt: row.updated_at,
mode: 'open',
};
}
@ -224,8 +228,8 @@ class ProjectStore implements IProjectStore {
}
async addDefaultEnvironment(projects: any[]): Promise<void> {
const environments = projects.map((p) => ({
project_id: p.id,
const environments = projects.map((project) => ({
project_id: project.id,
environment_name: DEFAULT_ENV,
}));
await this.db('project_environments')
@ -456,6 +460,7 @@ class ProjectStore implements IProjectStore {
createdAt: row.created_at,
health: row.health ?? 100,
updatedAt: row.updated_at || new Date(),
mode: 'open',
};
}
}

View File

@ -55,6 +55,14 @@ export const projectSchema = {
description:
'`true` if the project was favorited, otherwise `false`.',
},
mode: {
type: 'string',
enum: ['open', 'protected'],
example: 'open',
nullable: true,
description:
'A mode of the project affecting what actions are possible in this project. During a rollout of project modes this feature can be optional or `null`',
},
},
components: {},
} as const;

View File

@ -366,7 +366,10 @@ export interface IProject {
createdAt?: Date;
updatedAt?: Date;
changeRequestsEnabled?: boolean;
mode: ProjectMode;
}
export type ProjectMode = 'open' | 'protected';
export interface ICustomRole {
id: number;
name: string;

View File

@ -2836,6 +2836,16 @@ exports[`should serve the OpenAPI spec 1`] = `
"example": 4,
"type": "number",
},
"mode": {
"description": "A mode of the project affecting what actions are possible in this project. During a rollout of project modes this feature can be optional or \`null\`",
"enum": [
"open",
"protected",
],
"example": "open",
"nullable": true,
"type": "string",
},
"name": {
"description": "The name of this project",
"example": "DX-Squad",

View File

@ -206,6 +206,7 @@ test('should update project', async () => {
id: 'test-update',
name: 'New name',
description: 'Blah longer desc',
mode: 'open' as const,
};
await projectService.createProject(project, user);
@ -655,14 +656,14 @@ test('should add a user to the project with a custom role', async () => {
{
id: 2,
name: 'CREATE_FEATURE',
environment: null,
environment: undefined,
displayName: 'Create Feature Toggles',
type: 'project',
},
{
id: 8,
name: 'DELETE_FEATURE',
environment: null,
environment: undefined,
displayName: 'Delete Feature Toggles',
type: 'project',
},
@ -711,14 +712,14 @@ test('should delete role entries when deleting project', async () => {
{
id: 2,
name: 'CREATE_FEATURE',
environment: null,
environment: undefined,
displayName: 'Create Feature Toggles',
type: 'project',
},
{
id: 8,
name: 'DELETE_FEATURE',
environment: null,
environment: undefined,
displayName: 'Delete Feature Toggles',
type: 'project',
},
@ -757,14 +758,14 @@ test('should change a users role in the project', async () => {
{
id: 2,
name: 'CREATE_FEATURE',
environment: null,
environment: undefined,
displayName: 'Create Feature Toggles',
type: 'project',
},
{
id: 8,
name: 'DELETE_FEATURE',
environment: null,
environment: undefined,
displayName: 'Delete Feature Toggles',
type: 'project',
},
@ -940,7 +941,7 @@ test('Should allow bulk update of group permissions', async () => {
{
id: 2,
name: 'CREATE_FEATURE',
environment: null,
environment: undefined,
displayName: 'Create Feature Toggles',
type: 'project',
},
@ -973,7 +974,7 @@ test('Should bulk update of only users', async () => {
{
id: 2,
name: 'CREATE_FEATURE',
environment: null,
environment: undefined,
displayName: 'Create Feature Toggles',
type: 'project',
},
@ -1012,7 +1013,7 @@ test('Should allow bulk update of only groups', async () => {
{
id: 2,
name: 'CREATE_FEATURE',
environment: null,
environment: undefined,
displayName: 'Create Feature Toggles',
type: 'project',
},

View File

@ -42,8 +42,8 @@ export default class FakeProjectStore implements IProjectStore {
}
async getProjectsWithCounts(): Promise<IProjectWithCount[]> {
return this.projects.map((p) => {
return { ...p, memberCount: 0, featureCount: 0 };
return this.projects.map((project) => {
return { ...project, memberCount: 0, featureCount: 0 };
});
}
@ -52,6 +52,7 @@ export default class FakeProjectStore implements IProjectStore {
...project,
health: 100,
createdAt: new Date(),
mode: 'open',
};
this.projects.push(newProj);
return newProj;
@ -63,7 +64,7 @@ export default class FakeProjectStore implements IProjectStore {
async delete(key: string): Promise<void> {
this.projects.splice(
this.projects.findIndex((p) => p.id === key),
this.projects.findIndex((project) => project.id === key),
1,
);
}
@ -90,7 +91,7 @@ export default class FakeProjectStore implements IProjectStore {
}
async exists(key: string): Promise<boolean> {
return this.projects.some((p) => p.id === key);
return this.projects.some((project) => project.id === key);
}
async get(key: string): Promise<IProject> {
@ -120,7 +121,7 @@ export default class FakeProjectStore implements IProjectStore {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
environments?: IEnvironment[],
): Promise<IProject[]> {
return projects.map((p) => this.createInternal(p));
return projects.map((project) => this.createInternal(project));
}
async update(update: IProjectInsert): Promise<void> {
@ -129,8 +130,9 @@ export default class FakeProjectStore implements IProjectStore {
}
async updateHealth(healthUpdate: IProjectHealthUpdate): Promise<void> {
this.projects.find((p) => p.id === healthUpdate.id).health =
healthUpdate.health;
this.projects.find(
(project) => project.id === healthUpdate.id,
)!.health = healthUpdate.health;
}
getMembersCount(): Promise<IProjectMembersCount[]> {