diff --git a/frontend/web/components/ActionButton.tsx b/frontend/web/components/ActionButton.tsx index 02bf62e91323..96061510272c 100644 --- a/frontend/web/components/ActionButton.tsx +++ b/frontend/web/components/ActionButton.tsx @@ -11,14 +11,16 @@ type ActionButtonType = { const ActionButton: FC = ({ onClick, ...rest }) => { return ( ) } diff --git a/frontend/web/components/Highlight.js b/frontend/web/components/Highlight.js index fd077257727c..6f5ae59ccaf4 100644 --- a/frontend/web/components/Highlight.js +++ b/frontend/web/components/Highlight.js @@ -145,6 +145,7 @@ class Highlight extends React.Component { return (
         
{this.state.expandable && ( -
+
+ ) + } + + if (!!canEdit && !canRemove) { + return ( + + ) + } + + if (!canEdit && !canRemove) { + return null + } + + return ( +
+
+ { + setIsOpen(true) + }} + /> +
+ + {isOpen && ( +
{ + e.stopPropagation() + }} + onClick={(e) => e.stopPropagation()} + ref={listRef} + className='feature-action__list' + > + {!!canEdit && ( +
{ + e.stopPropagation() + handleActionClick('edit') + }} + > + + View segment +
+ )} + {!!canCopyValue && ( +
{ + e.stopPropagation() + handleActionClick('copy') + }} + > + + Set value from environment +
+ )} + + {!!canRemove && ( +
{ + e.stopPropagation() + handleActionClick('remove') + }} + > + + Remove Override +
+ )} +
+ )} +
+ ) +} + +export default SegmentOverrideAction diff --git a/frontend/web/components/SegmentOverrides.js b/frontend/web/components/SegmentOverrides.js index 898811d140e8..38d9f2a084e1 100644 --- a/frontend/web/components/SegmentOverrides.js +++ b/frontend/web/components/SegmentOverrides.js @@ -16,6 +16,9 @@ import Icon from './Icon' import SegmentOverrideLimit from './SegmentOverrideLimit' import { getStore } from 'common/store' import { getEnvironment } from 'common/services/useEnvironment' +import Tooltip from './Tooltip' +import SegmentsIcon from './svg/SegmentsIcon' +import SegmentOverrideActions from './SegmentOverrideActions' const arrayMoveMutate = (array, from, to) => { array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]) @@ -93,13 +96,13 @@ const SegmentOverrideInner = class Override extends React.Component {
- +
{this.props.id ? ( <> @@ -136,8 +139,16 @@ const SegmentOverrideInner = class Override extends React.Component {
) : ( - - {name || v.segment_name} + + + + {name || v.segment_name} + {v.is_feature_specific && (
Feature-Specific
)} @@ -147,28 +158,6 @@ const SegmentOverrideInner = class Override extends React.Component {
- - - - } - > - Set the Feature state to On or Off for Identities in this - Segment - - { - if (!readOnly) { - this.setState({ changed: true }) - toggle(v) - } - }} - /> - {/* Input to adjust order without drag for E2E */} {E2E && ( - {!v.id || v.is_feature_specific ? ( - - ) : ( - - )} + } else { + window.open( + `${document.location.origin}/project/${this.props.projectId}/segments?id=${v.segment}`, + '_blank', + ) + } + }} + canEdit={permission} + /> , ) } - {!readOnly && ( - - )}
- -
+
+
+
+ + Enabled +
+ } + > + Controls whether the feature is enabled for users belonging to + this segment. + +
+ { + if (!readOnly) { + this.setState({ changed: true }) + toggle(v) + } + }} + /> +
{showValue ? ( <> - - { - this.setState({ changed: true }) - setValue( - Utils.getTypedValue(Utils.safeParseEventValue(e)), - ) - } - } - placeholder="Value e.g. 'big' " - /> +
+ + { + this.setState({ changed: true }) + setValue( + Utils.getTypedValue(Utils.safeParseEventValue(e)), + ) + } + } + placeholder="Value e.g. 'big' " + /> +
) : ( - <> +
- - )} - {!!controlValue && - (!multivariateOptions || !multivariateOptions.length) && ( -
- -
- )} - - {!!multivariateOptions?.length && ( -
- - { - const foundMv = - v.multivariate_options && - v.multivariate_options.find( - (v) => v.multivariate_feature_option === mv.id, - ) - if (foundMv) { - return { - ...mv, - default_percentage_allocation: - foundMv.percentage_allocation, - } - } - return { - ...mv, - default_percentage_allocation: 0, - } - })} - setVariations={(i, e, variationOverrides) => { - setVariations(i, e, variationOverrides) - this.setState({ changed: true }) - }} - setValue={(i, e, variationOverrides) => { - setVariations(i, e, variationOverrides) - this.setState({ changed: true }) - }} - updateVariation={(i, e, variationOverrides) => { - setVariations(i, e, variationOverrides) - this.setState({ changed: true }) - }} - weightTitle='Override Weight %' - /> -
)}
+ {!!multivariateOptions?.length && ( +
+ { + const foundMv = + v.multivariate_options && + v.multivariate_options.find( + (v) => v.multivariate_feature_option === mv.id, + ) + if (foundMv) { + return { + ...mv, + default_percentage_allocation: + foundMv.percentage_allocation, + } + } + return { + ...mv, + default_percentage_allocation: 0, + } + })} + setVariations={(i, e, variationOverrides) => { + setVariations(i, e, variationOverrides) + this.setState({ changed: true }) + }} + setValue={(i, e, variationOverrides) => { + setVariations(i, e, variationOverrides) + this.setState({ changed: true }) + }} + updateVariation={(i, e, variationOverrides) => { + setVariations(i, e, variationOverrides) + this.setState({ changed: true }) + }} + weightTitle='Override Weight %' + /> +
+ )}
) } @@ -581,164 +564,160 @@ class TheComponent extends Component { segmentOverrideLimitAlert.percentage >= 100 return (
- - {({ permission: manageSegments }) => { - return ( -
- {!this.props.id && - !this.props.disableCreate && - !this.props.showCreateSegment && - !this.props.readOnly && ( - - - this.setState({ selectedSegment }, this.addItem) - } - /> - - )} - {!this.props.showCreateSegment && - !this.props.readOnly && - !this.props.disableCreate && ( -
- -
- )} - {this.props.showCreateSegment && !this.state.segmentEditId && ( - )} - {this.props.showCreateSegment && this.state.segmentEditId && ( - { - this.setState({ - segmentEditId: undefined, - }) - this.props.setShowCreateSegment(false) - }} - onCancel={() => { - this.setState({ segmentEditId: undefined }) - this.props.setShowCreateSegment(false) - }} - environmentId={this.props.environmentId} - projectId={this.props.projectId} - /> - )} - {visibleValues && - !!visibleValues.length && - !this.props.showCreateSegment && ( -
- {!this.props.id && ( -
- - Segment overrides override the environment defaults, - prioritise them by dragging it to the top of the - list. Segment overrides will only apply when you - identify via the SDK, any identity overrides will - take priority.{' '} - - Check the Docs for more details - - . - - -
- )} - {value && ( - <> - ({ - ...v, - }))} - setSegmentEditId={this.setSegmentEditId} - onSortEnd={this.onSortEnd} - projectFlag={this.props.projectFlag} - /> -
- -
- - )} + {value && ( + <> + { + const tagName = e.target.tagName.toLowerCase() + + // Check if the clicked element is a button, input, or textarea + if ( + tagName === 'input' || + tagName === 'textarea' || + tagName === 'button' + ) { + return true // Cancel sorting for inputs, buttons, etc. + } + + // Cancel if the clicked element has class 'feature-action__list' + if ( + e.target.closest('.feature-action__item') || // Checks for parent elements with the class + e.target.closest('.hljs') + ) { + return true // Cancel sorting if the target or parent has these classes + } + + // Otherwise, allow sorting + return false + }} // Here we pass the function to prevent sorting in certain cases + disabled={this.props.readOnly} + id={this.props.id} + name={this.props.name} + controlValue={this.props.controlValue} + multivariateOptions={multivariateOptions} + confirmRemove={this.confirmRemove} + setVariations={this.setVariations} + toggle={this.toggle} + setValue={this.setValue} + readOnly={this.props.readOnly} + showEditSegment={this.props.showEditSegment} + environmentId={this.props.environmentId} + projectId={this.props.projectId} + setShowCreateSegment={this.props.setShowCreateSegment} + items={value.map((v) => ({ + ...v, + }))} + setSegmentEditId={this.setSegmentEditId} + onSortEnd={this.onSortEnd} + projectFlag={this.props.projectFlag} + /> +
+
- )} + + )}
- ) - }} - + )} +
) } diff --git a/frontend/web/components/modals/CreateFlag.js b/frontend/web/components/modals/CreateFlag.js index 046d4aead47f..1c1e0ad8b19e 100644 --- a/frontend/web/components/modals/CreateFlag.js +++ b/frontend/web/components/modals/CreateFlag.js @@ -1016,17 +1016,13 @@ const CreateFlag = class extends Component { const onCreateFeature = saveFeatureWithValidation(() => { this.save(createFlag, isSaving) }) + const isLimitReached = false const featureLimitAlert = Utils.calculateRemainingLimitsPercentage( project.total_features, project.max_features_allowed, ) - const showIdentityOverrides = - !identity && - isEdit && - !existingChangeRequest && - !hideIdentityOverridesTab return (
- - - Segment Overrides{' '} - - + +
+ + Segment Overrides{' '} + + + } + place='top' + > + { + Constants.strings + .SEGMENT_OVERRIDES_DESCRIPTION + } + +
+ - { - Constants.strings - .SEGMENT_OVERRIDES_DESCRIPTION + {({ + permission: + manageSegmentOverrides, + }) => + !this.state.showCreateSegment && + !!manageSegmentOverrides && + !this.props.disableCreate && ( +
+ +
+ ) } -
+ {!this.state.showCreateSegment && !noPermissions && (