mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-06 01:15:28 +02:00
feat: Default project mode open (#3316)
This commit is contained in:
parent
647f75fa8b
commit
9fd84abaa5
@ -133,8 +133,11 @@ class ProjectStore implements IProjectStore {
|
|||||||
const memberMap = new Map<string, number>(
|
const memberMap = new Map<string, number>(
|
||||||
memberCount.map((c) => [c.project, Number(c.count)]),
|
memberCount.map((c) => [c.project, Number(c.count)]),
|
||||||
);
|
);
|
||||||
return projectsWithFeatureCount.map((r) => {
|
return projectsWithFeatureCount.map((projectWithCount) => {
|
||||||
return { ...r, memberCount: memberMap.get(r.id) };
|
return {
|
||||||
|
...projectWithCount,
|
||||||
|
memberCount: memberMap.get(projectWithCount.id) || 0,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +152,7 @@ class ProjectStore implements IProjectStore {
|
|||||||
featureCount: Number(row.number_of_features) || 0,
|
featureCount: Number(row.number_of_features) || 0,
|
||||||
memberCount: Number(row.number_of_users) || 0,
|
memberCount: Number(row.number_of_users) || 0,
|
||||||
updatedAt: row.updated_at,
|
updatedAt: row.updated_at,
|
||||||
|
mode: 'open',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,8 +228,8 @@ class ProjectStore implements IProjectStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async addDefaultEnvironment(projects: any[]): Promise<void> {
|
async addDefaultEnvironment(projects: any[]): Promise<void> {
|
||||||
const environments = projects.map((p) => ({
|
const environments = projects.map((project) => ({
|
||||||
project_id: p.id,
|
project_id: project.id,
|
||||||
environment_name: DEFAULT_ENV,
|
environment_name: DEFAULT_ENV,
|
||||||
}));
|
}));
|
||||||
await this.db('project_environments')
|
await this.db('project_environments')
|
||||||
@ -456,6 +460,7 @@ class ProjectStore implements IProjectStore {
|
|||||||
createdAt: row.created_at,
|
createdAt: row.created_at,
|
||||||
health: row.health ?? 100,
|
health: row.health ?? 100,
|
||||||
updatedAt: row.updated_at || new Date(),
|
updatedAt: row.updated_at || new Date(),
|
||||||
|
mode: 'open',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,14 @@ export const projectSchema = {
|
|||||||
description:
|
description:
|
||||||
'`true` if the project was favorited, otherwise `false`.',
|
'`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: {},
|
components: {},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -366,7 +366,10 @@ export interface IProject {
|
|||||||
createdAt?: Date;
|
createdAt?: Date;
|
||||||
updatedAt?: Date;
|
updatedAt?: Date;
|
||||||
changeRequestsEnabled?: boolean;
|
changeRequestsEnabled?: boolean;
|
||||||
|
mode: ProjectMode;
|
||||||
}
|
}
|
||||||
|
export type ProjectMode = 'open' | 'protected';
|
||||||
|
|
||||||
export interface ICustomRole {
|
export interface ICustomRole {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -2836,6 +2836,16 @@ exports[`should serve the OpenAPI spec 1`] = `
|
|||||||
"example": 4,
|
"example": 4,
|
||||||
"type": "number",
|
"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": {
|
"name": {
|
||||||
"description": "The name of this project",
|
"description": "The name of this project",
|
||||||
"example": "DX-Squad",
|
"example": "DX-Squad",
|
||||||
|
@ -206,6 +206,7 @@ test('should update project', async () => {
|
|||||||
id: 'test-update',
|
id: 'test-update',
|
||||||
name: 'New name',
|
name: 'New name',
|
||||||
description: 'Blah longer desc',
|
description: 'Blah longer desc',
|
||||||
|
mode: 'open' as const,
|
||||||
};
|
};
|
||||||
|
|
||||||
await projectService.createProject(project, user);
|
await projectService.createProject(project, user);
|
||||||
@ -655,14 +656,14 @@ test('should add a user to the project with a custom role', async () => {
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
name: 'CREATE_FEATURE',
|
name: 'CREATE_FEATURE',
|
||||||
environment: null,
|
environment: undefined,
|
||||||
displayName: 'Create Feature Toggles',
|
displayName: 'Create Feature Toggles',
|
||||||
type: 'project',
|
type: 'project',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 8,
|
id: 8,
|
||||||
name: 'DELETE_FEATURE',
|
name: 'DELETE_FEATURE',
|
||||||
environment: null,
|
environment: undefined,
|
||||||
displayName: 'Delete Feature Toggles',
|
displayName: 'Delete Feature Toggles',
|
||||||
type: 'project',
|
type: 'project',
|
||||||
},
|
},
|
||||||
@ -711,14 +712,14 @@ test('should delete role entries when deleting project', async () => {
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
name: 'CREATE_FEATURE',
|
name: 'CREATE_FEATURE',
|
||||||
environment: null,
|
environment: undefined,
|
||||||
displayName: 'Create Feature Toggles',
|
displayName: 'Create Feature Toggles',
|
||||||
type: 'project',
|
type: 'project',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 8,
|
id: 8,
|
||||||
name: 'DELETE_FEATURE',
|
name: 'DELETE_FEATURE',
|
||||||
environment: null,
|
environment: undefined,
|
||||||
displayName: 'Delete Feature Toggles',
|
displayName: 'Delete Feature Toggles',
|
||||||
type: 'project',
|
type: 'project',
|
||||||
},
|
},
|
||||||
@ -757,14 +758,14 @@ test('should change a users role in the project', async () => {
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
name: 'CREATE_FEATURE',
|
name: 'CREATE_FEATURE',
|
||||||
environment: null,
|
environment: undefined,
|
||||||
displayName: 'Create Feature Toggles',
|
displayName: 'Create Feature Toggles',
|
||||||
type: 'project',
|
type: 'project',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 8,
|
id: 8,
|
||||||
name: 'DELETE_FEATURE',
|
name: 'DELETE_FEATURE',
|
||||||
environment: null,
|
environment: undefined,
|
||||||
displayName: 'Delete Feature Toggles',
|
displayName: 'Delete Feature Toggles',
|
||||||
type: 'project',
|
type: 'project',
|
||||||
},
|
},
|
||||||
@ -940,7 +941,7 @@ test('Should allow bulk update of group permissions', async () => {
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
name: 'CREATE_FEATURE',
|
name: 'CREATE_FEATURE',
|
||||||
environment: null,
|
environment: undefined,
|
||||||
displayName: 'Create Feature Toggles',
|
displayName: 'Create Feature Toggles',
|
||||||
type: 'project',
|
type: 'project',
|
||||||
},
|
},
|
||||||
@ -973,7 +974,7 @@ test('Should bulk update of only users', async () => {
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
name: 'CREATE_FEATURE',
|
name: 'CREATE_FEATURE',
|
||||||
environment: null,
|
environment: undefined,
|
||||||
displayName: 'Create Feature Toggles',
|
displayName: 'Create Feature Toggles',
|
||||||
type: 'project',
|
type: 'project',
|
||||||
},
|
},
|
||||||
@ -1012,7 +1013,7 @@ test('Should allow bulk update of only groups', async () => {
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
name: 'CREATE_FEATURE',
|
name: 'CREATE_FEATURE',
|
||||||
environment: null,
|
environment: undefined,
|
||||||
displayName: 'Create Feature Toggles',
|
displayName: 'Create Feature Toggles',
|
||||||
type: 'project',
|
type: 'project',
|
||||||
},
|
},
|
||||||
|
16
src/test/fixtures/fake-project-store.ts
vendored
16
src/test/fixtures/fake-project-store.ts
vendored
@ -42,8 +42,8 @@ export default class FakeProjectStore implements IProjectStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getProjectsWithCounts(): Promise<IProjectWithCount[]> {
|
async getProjectsWithCounts(): Promise<IProjectWithCount[]> {
|
||||||
return this.projects.map((p) => {
|
return this.projects.map((project) => {
|
||||||
return { ...p, memberCount: 0, featureCount: 0 };
|
return { ...project, memberCount: 0, featureCount: 0 };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +52,7 @@ export default class FakeProjectStore implements IProjectStore {
|
|||||||
...project,
|
...project,
|
||||||
health: 100,
|
health: 100,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
|
mode: 'open',
|
||||||
};
|
};
|
||||||
this.projects.push(newProj);
|
this.projects.push(newProj);
|
||||||
return newProj;
|
return newProj;
|
||||||
@ -63,7 +64,7 @@ export default class FakeProjectStore implements IProjectStore {
|
|||||||
|
|
||||||
async delete(key: string): Promise<void> {
|
async delete(key: string): Promise<void> {
|
||||||
this.projects.splice(
|
this.projects.splice(
|
||||||
this.projects.findIndex((p) => p.id === key),
|
this.projects.findIndex((project) => project.id === key),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -90,7 +91,7 @@ export default class FakeProjectStore implements IProjectStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async exists(key: string): Promise<boolean> {
|
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> {
|
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
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
environments?: IEnvironment[],
|
environments?: IEnvironment[],
|
||||||
): Promise<IProject[]> {
|
): Promise<IProject[]> {
|
||||||
return projects.map((p) => this.createInternal(p));
|
return projects.map((project) => this.createInternal(project));
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(update: IProjectInsert): Promise<void> {
|
async update(update: IProjectInsert): Promise<void> {
|
||||||
@ -129,8 +130,9 @@ export default class FakeProjectStore implements IProjectStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateHealth(healthUpdate: IProjectHealthUpdate): Promise<void> {
|
async updateHealth(healthUpdate: IProjectHealthUpdate): Promise<void> {
|
||||||
this.projects.find((p) => p.id === healthUpdate.id).health =
|
this.projects.find(
|
||||||
healthUpdate.health;
|
(project) => project.id === healthUpdate.id,
|
||||||
|
)!.health = healthUpdate.health;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMembersCount(): Promise<IProjectMembersCount[]> {
|
getMembersCount(): Promise<IProjectMembersCount[]> {
|
||||||
|
Loading…
Reference in New Issue
Block a user