1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01:00

chore: remove private projects flag (#5743)

This commit is contained in:
Jaanus Sellin 2024-01-02 15:53:26 +02:00 committed by GitHub
parent 049c5b9afa
commit dc0df235dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 89 additions and 143 deletions

View File

@ -14,7 +14,6 @@ const StyledDescription = styled(Typography)(({ theme }) => ({
})); }));
export const CollaborationModeTooltip: FC = () => { export const CollaborationModeTooltip: FC = () => {
const privateProjects = useUiFlag('privateProjects');
return ( return (
<HelpIcon <HelpIcon
htmlTooltip htmlTooltip
@ -33,19 +32,13 @@ export const CollaborationModeTooltip: FC = () => {
requests requests
</StyledDescription> </StyledDescription>
</Box> </Box>
<ConditionallyRender <Box sx={{ mt: 2 }}>
condition={Boolean(privateProjects)} <StyledTitle>private: </StyledTitle>
show={ <StyledDescription>
<Box sx={{ mt: 2 }}> Only admins, editors and project members can see and
<StyledTitle>private: </StyledTitle> access the project and associated feature toggles
<StyledDescription> </StyledDescription>
Only admins, editors and project members can </Box>
see and access the project and associated
feature toggles
</StyledDescription>
</Box>
}
/>
</> </>
} }
/> />

View File

@ -133,23 +133,15 @@ const ProjectEnterpriseSettingsForm: React.FC<IProjectEnterpriseSettingsForm> =
setFeatureNamingDescription, setFeatureNamingDescription,
setProjectMode, setProjectMode,
errors, errors,
clearErrors,
}) => { }) => {
const privateProjects = useUiFlag('privateProjects');
const { setPreviousPattern, trackPattern } = const { setPreviousPattern, trackPattern } =
useFeatureNamePatternTracking(); useFeatureNamePatternTracking();
const projectModeOptions = privateProjects const projectModeOptions = [
? [ { key: 'open', label: 'open' },
{ key: 'open', label: 'open' }, { key: 'protected', label: 'protected' },
{ key: 'protected', label: 'protected' }, { key: 'private', label: 'private' },
{ key: 'private', label: 'private' }, ];
]
: [
{ key: 'open', label: 'open' },
{ key: 'protected', label: 'protected' },
];
useEffect(() => { useEffect(() => {
setPreviousPattern(featureNamingPattern || ''); setPreviousPattern(featureNamingPattern || '');

View File

@ -103,18 +103,12 @@ const ProjectForm: React.FC<IProjectForm> = ({
clearErrors, clearErrors,
}) => { }) => {
const { isEnterprise } = useUiConfig(); const { isEnterprise } = useUiConfig();
const privateProjects = useUiFlag('privateProjects');
const projectModeOptions = privateProjects const projectModeOptions = [
? [ { key: 'open', label: 'open' },
{ key: 'open', label: 'open' }, { key: 'protected', label: 'protected' },
{ key: 'protected', label: 'protected' }, { key: 'private', label: 'private' },
{ key: 'private', label: 'private' }, ];
]
: [
{ key: 'open', label: 'open' },
{ key: 'protected', label: 'protected' },
];
return ( return (
<StyledForm <StyledForm

View File

@ -62,7 +62,6 @@ export type UiFlags = {
customRootRolesKillSwitch?: boolean; customRootRolesKillSwitch?: boolean;
strategyVariant?: boolean; strategyVariant?: boolean;
doraMetrics?: boolean; doraMetrics?: boolean;
privateProjects?: boolean;
dependentFeatures?: boolean; dependentFeatures?: boolean;
scheduledConfigurationChanges?: boolean; scheduledConfigurationChanges?: boolean;
featureSearchAPI?: boolean; featureSearchAPI?: boolean;

View File

@ -104,7 +104,6 @@ exports[`should create default config 1`] = `
"migrationLock": true, "migrationLock": true,
"newStrategyConfiguration": false, "newStrategyConfiguration": false,
"personalAccessTokensKillSwitch": false, "personalAccessTokensKillSwitch": false,
"privateProjects": false,
"proPlanAutoCharge": false, "proPlanAutoCharge": false,
"responseTimeWithAppNameKillSwitch": false, "responseTimeWithAppNameKillSwitch": false,
"scheduledConfigurationChanges": false, "scheduledConfigurationChanges": false,

View File

@ -1095,7 +1095,7 @@ class FeatureToggleService {
archived, archived,
); );
if (this.flagResolver.isEnabled('privateProjects') && userId) { if (userId) {
const projectAccess = const projectAccess =
await this.privateProjectChecker.getUserAccessibleProjects( await this.privateProjectChecker.getUserAccessibleProjects(
userId, userId,
@ -2053,20 +2053,15 @@ class FeatureToggleService {
): Promise<FeatureToggle[]> { ): Promise<FeatureToggle[]> {
const features = await this.featureToggleStore.getArchivedFeatures(); const features = await this.featureToggleStore.getArchivedFeatures();
if (this.flagResolver.isEnabled('privateProjects')) { const projectAccess =
const projectAccess = await this.privateProjectChecker.getUserAccessibleProjects(userId);
await this.privateProjectChecker.getUserAccessibleProjects( if (projectAccess.mode === 'all') {
userId, return features;
); } else {
if (projectAccess.mode === 'all') { return features.filter((f) =>
return features; projectAccess.projects.includes(f.project),
} else { );
return features.filter((f) =>
projectAccess.projects.includes(f.project),
);
}
} }
return features;
} }
async getArchivedFeaturesByProjectId( async getArchivedFeaturesByProjectId(

View File

@ -19,7 +19,6 @@ beforeAll(async () => {
advancedPlayground: true, advancedPlayground: true,
strictSchemaValidation: true, strictSchemaValidation: true,
strategyVariant: true, strategyVariant: true,
privateProjects: true,
}, },
}, },
}, },

View File

@ -102,20 +102,17 @@ export class PlaygroundService {
const segments = await this.segmentService.getActive(); const segments = await this.segmentService.getActive();
let filteredProjects: typeof projects = projects; let filteredProjects: typeof projects = projects;
if (this.flagResolver.isEnabled('privateProjects')) {
const projectAccess = const projectAccess =
await this.privateProjectChecker.getUserAccessibleProjects( await this.privateProjectChecker.getUserAccessibleProjects(userId);
userId, if (projectAccess.mode === 'all') {
); filteredProjects = projects;
if (projectAccess.mode === 'all') { } else if (projects === ALL) {
filteredProjects = projects; filteredProjects = projectAccess.projects;
} else if (projects === ALL) { } else {
filteredProjects = projectAccess.projects; filteredProjects = projects.filter((project) =>
} else { projectAccess.projects.includes(project),
filteredProjects = projects.filter((project) => );
projectAccess.projects.includes(project),
);
}
} }
const environmentFeatures = await Promise.all( const environmentFeatures = await Promise.all(

View File

@ -1,10 +1,10 @@
import { IPrivateProjectChecker } from './privateProjectCheckerType'; import { IPrivateProjectChecker } from './privateProjectCheckerType';
import { ProjectAccess } from './privateProjectStore'; import { ALL_PROJECT_ACCESS, ProjectAccess } from './privateProjectStore';
export class FakePrivateProjectChecker implements IPrivateProjectChecker { export class FakePrivateProjectChecker implements IPrivateProjectChecker {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
async getUserAccessibleProjects(userId: number): Promise<ProjectAccess> { async getUserAccessibleProjects(userId: number): Promise<ProjectAccess> {
throw new Error('Method not implemented.'); return ALL_PROJECT_ACCESS;
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars

View File

@ -160,29 +160,24 @@ export default class ClientInstanceService {
): Promise<IClientApplication[]> { ): Promise<IClientApplication[]> {
const applications = const applications =
await this.clientApplicationsStore.getAppsForStrategy(query); await this.clientApplicationsStore.getAppsForStrategy(query);
if (this.flagResolver.isEnabled('privateProjects')) { const accessibleProjects =
const accessibleProjects = await this.privateProjectChecker.getUserAccessibleProjects(userId);
await this.privateProjectChecker.getUserAccessibleProjects( if (accessibleProjects.mode === 'all') {
userId, return applications;
); } else {
if (accessibleProjects.mode === 'all') { return applications.map((application) => {
return applications; return {
} else { ...application,
return applications.map((application) => { usage: application.usage?.filter(
return { (usageItem) =>
...application, usageItem.project === ALL_PROJECTS ||
usage: application.usage?.filter( accessibleProjects.projects.includes(
(usageItem) => usageItem.project,
usageItem.project === ALL_PROJECTS || ),
accessibleProjects.projects.includes( ),
usageItem.project, };
), });
),
};
});
}
} }
return applications;
} }
async getApplication(appName: string): Promise<IApplication> { async getApplication(appName: string): Promise<IApplication> {

View File

@ -75,24 +75,17 @@ class ContextService {
): Promise<ContextFieldStrategiesSchema> { ): Promise<ContextFieldStrategiesSchema> {
const strategies = const strategies =
await this.featureStrategiesStore.getStrategiesByContextField(name); await this.featureStrategiesStore.getStrategiesByContextField(name);
if (this.flagResolver.isEnabled('privateProjects')) { const accessibleProjects =
const accessibleProjects = await this.privateProjectChecker.getUserAccessibleProjects(userId);
await this.privateProjectChecker.getUserAccessibleProjects( if (accessibleProjects.mode === 'all') {
userId, return this.mapStrategies(strategies);
); } else {
if (accessibleProjects.mode === 'all') { return this.mapStrategies(
return this.mapStrategies(strategies); strategies.filter((strategy) =>
} else { accessibleProjects.projects.includes(strategy.projectId),
return this.mapStrategies( ),
strategies.filter((strategy) => );
accessibleProjects.projects.includes(
strategy.projectId,
),
),
);
}
} }
return this.mapStrategies(strategies);
} }
private mapStrategies(strategies: IFeatureStrategy[]) { private mapStrategies(strategies: IFeatureStrategy[]) {

View File

@ -180,7 +180,7 @@ export default class ProjectService {
userId, userId,
); );
if (this.flagResolver.isEnabled('privateProjects') && userId) { if (userId) {
const projectAccess = const projectAccess =
await this.privateProjectChecker.getUserAccessibleProjects( await this.privateProjectChecker.getUserAccessibleProjects(
userId, userId,

View File

@ -96,24 +96,19 @@ export class SegmentService implements ISegmentService {
userId: number, userId: number,
): Promise<StrategiesUsingSegment> { ): Promise<StrategiesUsingSegment> {
const allStrategies = await this.getAllStrategies(id); const allStrategies = await this.getAllStrategies(id);
if (this.flagResolver.isEnabled('privateProjects')) { const accessibleProjects =
const accessibleProjects = await this.privateProjectChecker.getUserAccessibleProjects(userId);
await this.privateProjectChecker.getUserAccessibleProjects( if (accessibleProjects.mode === 'all') {
userId, return allStrategies;
); } else {
if (accessibleProjects.mode === 'all') { const filter = (strategy) =>
return allStrategies; accessibleProjects.projects.includes(strategy.projectId);
} else { return {
const filter = (strategy) => strategies: allStrategies.strategies.filter(filter),
accessibleProjects.projects.includes(strategy.projectId); changeRequestStrategies:
return { allStrategies.changeRequestStrategies.filter(filter),
strategies: allStrategies.strategies.filter(filter), };
changeRequestStrategies:
allStrategies.changeRequestStrategies.filter(filter),
};
}
} }
return allStrategies;
} }
async getAllStrategies(id: number): Promise<StrategiesUsingSegment> { async getAllStrategies(id: number): Promise<StrategiesUsingSegment> {

View File

@ -23,7 +23,6 @@ export type IFlagKey =
| 'advancedPlayground' | 'advancedPlayground'
| 'filterInvalidClientMetrics' | 'filterInvalidClientMetrics'
| 'customRootRolesKillSwitch' | 'customRootRolesKillSwitch'
| 'privateProjects'
| 'disableMetrics' | 'disableMetrics'
| 'featureSearchAPI' | 'featureSearchAPI'
| 'featureSearchFrontend' | 'featureSearchFrontend'
@ -112,10 +111,6 @@ const flags: IFlags = {
process.env.UNLEASH_EXPERIMENTAL_CUSTOM_ROOT_ROLES_KILL_SWITCH, process.env.UNLEASH_EXPERIMENTAL_CUSTOM_ROOT_ROLES_KILL_SWITCH,
false, false,
), ),
privateProjects: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_PRIVATE_PROJECTS,
false,
),
disableMetrics: parseEnvVarBoolean( disableMetrics: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_DISABLE_METRICS, process.env.UNLEASH_EXPERIMENTAL_DISABLE_METRICS,
false, false,

View File

@ -40,7 +40,6 @@ process.nextTick(async () => {
embedProxyFrontend: true, embedProxyFrontend: true,
anonymiseEventLog: false, anonymiseEventLog: false,
responseTimeWithAppNameKillSwitch: false, responseTimeWithAppNameKillSwitch: false,
privateProjects: true,
featureSearchAPI: true, featureSearchAPI: true,
featureSearchFrontend: true, featureSearchFrontend: true,
stripClientHeadersOn304: true, stripClientHeadersOn304: true,

View File

@ -10,13 +10,17 @@ let app: IUnleashTest;
beforeAll(async () => { beforeAll(async () => {
db = await dbInit('context_api_serial', getLogger); db = await dbInit('context_api_serial', getLogger);
app = await setupAppWithCustomConfig(db.stores, { app = await setupAppWithCustomConfig(
experimental: { db.stores,
flags: { {
strictSchemaValidation: true, experimental: {
flags: {
strictSchemaValidation: true,
},
}, },
}, },
}); db.rawDatabase,
);
}); });
afterAll(async () => { afterAll(async () => {

View File

@ -10,7 +10,7 @@ let db: ITestDb;
beforeAll(async () => { beforeAll(async () => {
db = await dbInit('metrics_serial', getLogger, {}); db = await dbInit('metrics_serial', getLogger, {});
app = await setupAppWithCustomConfig(db.stores, {}); app = await setupAppWithCustomConfig(db.stores, {}, db.rawDatabase);
}); });
beforeEach(async () => { beforeEach(async () => {

View File

@ -61,9 +61,6 @@ beforeAll(async () => {
}); });
const config = createTestConfig({ const config = createTestConfig({
getLogger, getLogger,
experimental: {
flags: { privateProjects: true },
},
}); });
eventService = new EventService(stores, config); eventService = new EventService(stores, config);
accessService = createAccessService(db.rawDatabase, config); accessService = createAccessService(db.rawDatabase, config);