mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-31 00:16:47 +01:00
chore: remove usage of feature naming pattern flag (#5364)
In preparation for this feature going GA
This commit is contained in:
parent
fd099e242e
commit
90d6c7c0ba
@ -23,7 +23,6 @@ import React from 'react';
|
||||
import { useAuthPermissions } from 'hooks/api/getters/useAuth/useAuthPermissions';
|
||||
import { FeatureNamingType } from 'interfaces/project';
|
||||
import { FeatureNamingPatternInfo } from '../FeatureNamingPatternInfo/FeatureNamingPatternInfo';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
|
||||
interface IFeatureToggleForm {
|
||||
type: string;
|
||||
@ -122,15 +121,12 @@ const FeatureForm: React.FC<IFeatureToggleForm> = ({
|
||||
const navigate = useNavigate();
|
||||
const { permissions } = useAuthPermissions();
|
||||
const editable = mode !== 'Edit';
|
||||
const featureNamingPatternEnabled = useUiFlag('featureNamingPattern');
|
||||
|
||||
const renderToggleDescription = () => {
|
||||
return featureTypes.find((toggle) => toggle.id === type)?.description;
|
||||
};
|
||||
|
||||
const displayFeatureNamingInfo = Boolean(
|
||||
featureNamingPatternEnabled && featureNaming?.pattern,
|
||||
);
|
||||
const displayFeatureNamingInfo = Boolean(featureNaming?.pattern);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (featureNaming?.pattern && validateToggleName && name) {
|
||||
|
@ -136,7 +136,6 @@ const ProjectEnterpriseSettingsForm: React.FC<IProjectEnterpriseSettingsForm> =
|
||||
clearErrors,
|
||||
}) => {
|
||||
const privateProjects = useUiFlag('privateProjects');
|
||||
const shouldShowFlagNaming = useUiFlag('featureNamingPattern');
|
||||
|
||||
const { setPreviousPattern, trackPattern } =
|
||||
useFeatureNamePatternTracking();
|
||||
@ -253,115 +252,104 @@ const ProjectEnterpriseSettingsForm: React.FC<IProjectEnterpriseSettingsForm> =
|
||||
options={projectModeOptions}
|
||||
/>
|
||||
</>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(shouldShowFlagNaming)}
|
||||
show={
|
||||
<StyledFieldset>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginBottom: 1,
|
||||
gap: 1,
|
||||
}}
|
||||
>
|
||||
<legend>Feature flag naming pattern?</legend>
|
||||
<FeatureFlagNamingTooltip />
|
||||
</Box>
|
||||
<StyledSubtitle>
|
||||
<StyledPatternNamingExplanation id='pattern-naming-description'>
|
||||
<p>
|
||||
Define a{' '}
|
||||
<a
|
||||
href={`https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Cheatsheet`}
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
JavaScript RegEx
|
||||
</a>{' '}
|
||||
used to enforce feature flag names
|
||||
within this project. The regex will be
|
||||
surrounded by a leading <code>^</code>{' '}
|
||||
and a trailing <code>$</code>.
|
||||
</p>
|
||||
<p>
|
||||
Leave it empty if you don’t want to add
|
||||
a naming pattern.
|
||||
</p>
|
||||
</StyledPatternNamingExplanation>
|
||||
</StyledSubtitle>
|
||||
<StyledFlagNamingContainer>
|
||||
<StyledInput
|
||||
label={'Naming Pattern'}
|
||||
name='feature flag naming pattern'
|
||||
aria-describedby='pattern-naming-description'
|
||||
placeholder='[A-Za-z]+.[A-Za-z]+.[A-Za-z0-9-]+'
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position='start'>
|
||||
^
|
||||
</InputAdornment>
|
||||
),
|
||||
endAdornment: (
|
||||
<InputAdornment position='end'>
|
||||
$
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
type={'text'}
|
||||
value={featureNamingPattern || ''}
|
||||
error={Boolean(errors.featureNamingPattern)}
|
||||
errorText={errors.featureNamingPattern}
|
||||
onChange={(e) =>
|
||||
onSetFeatureNamingPattern(
|
||||
e.target.value,
|
||||
)
|
||||
}
|
||||
/>
|
||||
<StyledSubtitle>
|
||||
<p id='pattern-additional-description'>
|
||||
The example and description will be
|
||||
shown to users when they create a new
|
||||
feature flag in this project.
|
||||
</p>
|
||||
</StyledSubtitle>
|
||||
<StyledFieldset>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginBottom: 1,
|
||||
gap: 1,
|
||||
}}
|
||||
>
|
||||
<legend>Feature flag naming pattern?</legend>
|
||||
<FeatureFlagNamingTooltip />
|
||||
</Box>
|
||||
<StyledSubtitle>
|
||||
<StyledPatternNamingExplanation id='pattern-naming-description'>
|
||||
<p>
|
||||
Define a{' '}
|
||||
<a
|
||||
href={`https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Cheatsheet`}
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
JavaScript RegEx
|
||||
</a>{' '}
|
||||
used to enforce feature flag names within this
|
||||
project. The regex will be surrounded by a
|
||||
leading <code>^</code> and a trailing{' '}
|
||||
<code>$</code>.
|
||||
</p>
|
||||
<p>
|
||||
Leave it empty if you don’t want to add a naming
|
||||
pattern.
|
||||
</p>
|
||||
</StyledPatternNamingExplanation>
|
||||
</StyledSubtitle>
|
||||
<StyledFlagNamingContainer>
|
||||
<StyledInput
|
||||
label={'Naming Pattern'}
|
||||
name='feature flag naming pattern'
|
||||
aria-describedby='pattern-naming-description'
|
||||
placeholder='[A-Za-z]+.[A-Za-z]+.[A-Za-z0-9-]+'
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position='start'>
|
||||
^
|
||||
</InputAdornment>
|
||||
),
|
||||
endAdornment: (
|
||||
<InputAdornment position='end'>
|
||||
$
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
type={'text'}
|
||||
value={featureNamingPattern || ''}
|
||||
error={Boolean(errors.featureNamingPattern)}
|
||||
errorText={errors.featureNamingPattern}
|
||||
onChange={(e) =>
|
||||
onSetFeatureNamingPattern(e.target.value)
|
||||
}
|
||||
/>
|
||||
<StyledSubtitle>
|
||||
<p id='pattern-additional-description'>
|
||||
The example and description will be shown to
|
||||
users when they create a new feature flag in
|
||||
this project.
|
||||
</p>
|
||||
</StyledSubtitle>
|
||||
|
||||
<StyledInput
|
||||
label={'Naming Example'}
|
||||
name='feature flag naming example'
|
||||
type={'text'}
|
||||
aria-describedby='pattern-additional-description'
|
||||
value={featureNamingExample || ''}
|
||||
placeholder='dx.feature1.1-135'
|
||||
error={Boolean(errors.namingExample)}
|
||||
errorText={errors.namingExample}
|
||||
onChange={(e) =>
|
||||
onSetFeatureNamingExample(
|
||||
e.target.value,
|
||||
)
|
||||
}
|
||||
/>
|
||||
<StyledTextField
|
||||
label={'Naming pattern description'}
|
||||
name='feature flag naming description'
|
||||
type={'text'}
|
||||
aria-describedby='pattern-additional-description'
|
||||
placeholder={`<project>.<featureName>.<ticket>
|
||||
<StyledInput
|
||||
label={'Naming Example'}
|
||||
name='feature flag naming example'
|
||||
type={'text'}
|
||||
aria-describedby='pattern-additional-description'
|
||||
value={featureNamingExample || ''}
|
||||
placeholder='dx.feature1.1-135'
|
||||
error={Boolean(errors.namingExample)}
|
||||
errorText={errors.namingExample}
|
||||
onChange={(e) =>
|
||||
onSetFeatureNamingExample(e.target.value)
|
||||
}
|
||||
/>
|
||||
<StyledTextField
|
||||
label={'Naming pattern description'}
|
||||
name='feature flag naming description'
|
||||
type={'text'}
|
||||
aria-describedby='pattern-additional-description'
|
||||
placeholder={`<project>.<featureName>.<ticket>
|
||||
|
||||
The flag name should contain the project name, the feature name, and the ticket number, each separated by a dot.`}
|
||||
multiline
|
||||
minRows={5}
|
||||
value={featureNamingDescription || ''}
|
||||
onChange={(e) =>
|
||||
onSetFeatureNamingDescription(
|
||||
e.target.value,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</StyledFlagNamingContainer>
|
||||
</StyledFieldset>
|
||||
}
|
||||
/>
|
||||
multiline
|
||||
minRows={5}
|
||||
value={featureNamingDescription || ''}
|
||||
onChange={(e) =>
|
||||
onSetFeatureNamingDescription(e.target.value)
|
||||
}
|
||||
/>
|
||||
</StyledFlagNamingContainer>
|
||||
</StyledFieldset>
|
||||
<StyledButtonContainer>{children}</StyledButtonContainer>
|
||||
</StyledForm>
|
||||
);
|
||||
|
@ -61,7 +61,6 @@ export type UiFlags = {
|
||||
customRootRolesKillSwitch?: boolean;
|
||||
strategyVariant?: boolean;
|
||||
lastSeenByEnvironment?: boolean;
|
||||
featureNamingPattern?: boolean;
|
||||
doraMetrics?: boolean;
|
||||
variantTypeNumber?: boolean;
|
||||
privateProjects?: boolean;
|
||||
|
@ -84,7 +84,6 @@ exports[`should create default config 1`] = `
|
||||
"doraMetrics": false,
|
||||
"embedProxy": true,
|
||||
"embedProxyFrontend": true,
|
||||
"featureNamingPattern": false,
|
||||
"featureSearchAPI": false,
|
||||
"featureSearchFrontend": false,
|
||||
"featuresExportImport": true,
|
||||
|
@ -159,7 +159,6 @@ beforeAll(async () => {
|
||||
experimental: {
|
||||
flags: {
|
||||
featuresExportImport: true,
|
||||
featureNamingPattern: true,
|
||||
dependentFeatures: true,
|
||||
},
|
||||
},
|
||||
|
@ -1168,22 +1168,21 @@ class FeatureToggleService {
|
||||
projectId: string,
|
||||
featureNames: string[],
|
||||
): Promise<FeatureNameCheckResultWithFeaturePattern> {
|
||||
if (this.flagResolver.isEnabled('featureNamingPattern')) {
|
||||
const project = await this.projectStore.get(projectId);
|
||||
const patternData = project.featureNaming;
|
||||
const namingPattern = patternData?.pattern;
|
||||
const project = await this.projectStore.get(projectId);
|
||||
const patternData = project.featureNaming;
|
||||
const namingPattern = patternData?.pattern;
|
||||
|
||||
if (namingPattern) {
|
||||
const result = checkFeatureFlagNamesAgainstPattern(
|
||||
featureNames,
|
||||
namingPattern,
|
||||
);
|
||||
if (namingPattern) {
|
||||
const result = checkFeatureFlagNamesAgainstPattern(
|
||||
featureNames,
|
||||
namingPattern,
|
||||
);
|
||||
|
||||
if (result.state === 'invalid') {
|
||||
return { ...result, featureNaming: patternData };
|
||||
}
|
||||
if (result.state === 'invalid') {
|
||||
return { ...result, featureNaming: patternData };
|
||||
}
|
||||
}
|
||||
|
||||
return { state: 'valid' };
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ const irrelevantDate = new Date();
|
||||
beforeAll(async () => {
|
||||
const config = createTestConfig({
|
||||
experimental: {
|
||||
flags: { featureNamingPattern: true, playgroundImprovements: true },
|
||||
flags: { playgroundImprovements: true },
|
||||
},
|
||||
});
|
||||
db = await dbInit(
|
||||
|
@ -23,7 +23,6 @@ export type IFlagKey =
|
||||
| 'filterInvalidClientMetrics'
|
||||
| 'lastSeenByEnvironment'
|
||||
| 'customRootRolesKillSwitch'
|
||||
| 'featureNamingPattern'
|
||||
| 'doraMetrics'
|
||||
| 'variantTypeNumber'
|
||||
| 'privateProjects'
|
||||
@ -116,10 +115,6 @@ const flags: IFlags = {
|
||||
process.env.UNLEASH_EXPERIMENTAL_CUSTOM_ROOT_ROLES_KILL_SWITCH,
|
||||
false,
|
||||
),
|
||||
featureNamingPattern: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_EXPERIMENTAL_FEATURE_NAMING_PATTERN,
|
||||
false,
|
||||
),
|
||||
doraMetrics: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_EXPERIMENTAL_DORA_METRICS,
|
||||
false,
|
||||
|
@ -38,7 +38,6 @@ process.nextTick(async () => {
|
||||
anonymiseEventLog: false,
|
||||
responseTimeWithAppNameKillSwitch: false,
|
||||
lastSeenByEnvironment: true,
|
||||
featureNamingPattern: true,
|
||||
doraMetrics: true,
|
||||
variantTypeNumber: true,
|
||||
privateProjects: true,
|
||||
|
@ -21,7 +21,6 @@ beforeAll(async () => {
|
||||
experimental: {
|
||||
flags: {
|
||||
strictSchemaValidation: true,
|
||||
featureNamingPattern: true,
|
||||
dependentFeatures: true,
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user