Skip to content
This repository was archived by the owner on Apr 18, 2024. It is now read-only.

Commit fd0c332

Browse files
authored
chore: LEAP-221: Remove Taxonomy flags (#1489)
* fix: LSDV-1476: Fix selected=true for Taxonomy First try, not fully working. Now `<Choice selected="true">` will work inside Taxonomy as well. * Fix example; typo in FFs; list of taxonomy FFs - fix example for classifications - fix typo in FF link - add list of all Taxonomy and Choices related FFs * Add test for preselected Taxonomy; with 3617 FF off * fix work with shared store (FF_DEV_3617) * Add tests for static/dynamic + on/off cases * Linting + remove unused alert * Remove FF_DEV_2007 flag * Remove FF_DEV_2007_DEV_2008 FF * Actually use ffState in test * Remove FF_DEV_2100_A * Remove FF_DEV_2244 * Linting from prev commits * Add missing required flags * Fix TS recognition of cypress globals * Remove unused FF groupping Not the best way to do it anyway * It does work with FF_DEV_3617 after the fix! * Add comment about fixed updateValue() * Update ls-frontend-test to have hasNoSelected() * Fix tests * Add FF to fix init order Children should be init before other processes like setDefaultValues() * Make it safe to `updateValue()` without task This case can happen during store init in Label Stream, task will be loaded later. * Update ls-frontend-test * Remove flags from tests * Small fixes for test data * Connect updated test helpers * Get rid of unused FF list * Update ls-frontend-test --------- Co-authored-by: hlomzik <hlomzik@users.noreply.github.com>
1 parent 5d5d569 commit fd0c332

File tree

15 files changed

+62
-238
lines changed

15 files changed

+62
-238
lines changed

e2e/tests/nested-choices.test.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ Scenario('Switching states at nested choices', async ({ I, LabelStudio })=>{
3030

3131
I.amOnPage('/');
3232

33-
LabelStudio.setFeatureFlags({
34-
ff_dev_2007_rework_choices_280322_short: true,
35-
ff_dev_2100_preselected_choices_250422_short: true,
36-
ff_front_dev_2244_nested_choices_des_107_160522_short: true,
37-
});
38-
3933
LabelStudio.init(params);
4034

4135
{
@@ -100,12 +94,6 @@ Scenario('Nested choices states from the annotation', async ({ I, LabelStudio })
10094

10195
I.amOnPage('/');
10296

103-
LabelStudio.setFeatureFlags({
104-
ff_dev_2007_rework_choices_280322_short: true,
105-
ff_dev_2100_preselected_choices_250422_short: true,
106-
ff_front_dev_2244_nested_choices_des_107_160522_short: true,
107-
});
108-
10997
// Load annotation with each type of selection for branches (fully checked, fully unchecked, partly checked)
11098
LabelStudio.init({
11199
...params,

e2e/tests/regression-tests/dynamic-choices.test.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@ const assert = require('assert');
33
Feature('Dynamic choices').tag('@regress');
44

55
Scenario('Hotkeys for dynamic choices', async ({ I, LabelStudio })=>{
6-
LabelStudio.setFeatureFlags({
7-
ff_dev_2007_rework_choices_280322_short: true,
8-
ff_dev_2007_dev_2008_dynamic_tag_children_250322_short: true,
9-
ff_dev_2100_preselected_choices_250422_short: true,
10-
ff_front_dev_2244_nested_choices_des_107_160522_short: true,
11-
});
12-
136
const params = {
147
config: `
158
<View>

e2e/tests/regression-tests/preselected-choices.test.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ Scenario('Make a duplicate of annotation with preselected choices', async ({ I,
3333
};
3434

3535
I.amOnPage('/');
36-
LabelStudio.setFeatureFlags({
37-
ff_dev_2100_preselected_choices_250422_short: true,
38-
});
3936
LabelStudio.init(params);
4037
// Try to create copy of current annotation
4138
AtTopbar.click('[aria-label="Copy Annotation"]');
@@ -75,9 +72,6 @@ Scenario('Make a duplicate of empty annotation with preselected choices', async
7572
};
7673

7774
I.amOnPage('/');
78-
LabelStudio.setFeatureFlags({
79-
ff_dev_2100_preselected_choices_250422_short: true,
80-
});
8175
LabelStudio.init(params);
8276
// Try to create copy of current annotation
8377
AtTopbar.click('[aria-label="Copy Annotation"]');

e2e/tests/taxonomy.test.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ Feature('Taxonomy');
66
Before(({ LabelStudio }) => {
77
LabelStudio.setFeatureFlags({
88
fflag_feat_front_lsdv_5451_async_taxonomy_110823_short: false,
9-
ff_dev_2007_dev_2008_dynamic_tag_children_250322_short: true,
109
fflag_fix_front_dev_3617_taxonomy_memory_leaks_fix: true,
1110
ff_front_dev_1536_taxonomy_user_labels_150222_long: true,
1211
ff_front_1170_outliner_030222_short: true,

src/stores/Annotation/Annotation.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
FF_DEV_1284,
1616
FF_DEV_1598,
1717
FF_DEV_2100,
18-
FF_DEV_2100_A,
1918
FF_DEV_2432,
2019
FF_DEV_3391, FF_LLM_EPIC,
2120
FF_LSDV_3009,
@@ -596,7 +595,6 @@ export const Annotation = types
596595
},
597596

598597
setDefaultValues() {
599-
if (!isFF(FF_DEV_2100_A)) return;
600598
self.names.forEach(tag => {
601599
if (['choices', 'taxonomy'].includes(tag?.type) && tag.preselectedValues?.length) {
602600
// <Choice selected="true"/>
@@ -752,13 +750,6 @@ export const Annotation = types
752750
// may come handy when you have a tag that acts or depends
753751
// on other elements in the tree.
754752
if (node.annotationAttached) node.annotationAttached();
755-
756-
757-
// @todo special place to init such predefined values; `afterAttach` of the tag?
758-
// preselected choices
759-
if (!isFF(FF_DEV_2100_A) && !self.pk && node?.type === 'choices' && node.preselectedValues?.length) {
760-
self.createResult({}, { choices: node.preselectedValues }, node, node.toname);
761-
}
762753
});
763754

764755
self.history.onUpdate(self.updateObjects);

src/tags/control/Choice.js

Lines changed: 9 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import React, { Component, useCallback, useState } from 'react';
1+
import React, { useCallback, useState } from 'react';
22
import Button from 'antd/lib/button/index';
3-
import Form from 'antd/lib/form/index';
43
import Radio from 'antd/lib/radio/index';
54
import Checkbox from 'antd/lib/checkbox/index';
65
import { inject, observer } from 'mobx-react';
@@ -13,7 +12,7 @@ import Tree from '../../core/Tree';
1312
import Types from '../../core/Types';
1413
import { AnnotationMixin } from '../../mixins/AnnotationMixin';
1514
import { TagParentMixin } from '../../mixins/TagParentMixin';
16-
import { FF_DEV_2007, FF_DEV_2244, FF_DEV_3391, FF_PROD_309, isFF } from '../../utils/feature-flags';
15+
import { FF_DEV_3391, FF_PROD_309, isFF } from '../../utils/feature-flags';
1716
import { Block, Elem } from '../../utils/bem';
1817
import './Choice/Choice.styl';
1918
import { LsChevron } from '../../assets/icons';
@@ -22,7 +21,6 @@ import { HintTooltip } from '../../components/Taxonomy/Taxonomy';
2221
/**
2322
* The `Choice` tag represents a single choice for annotations. Use with the `Choices` tag or `Taxonomy` tag to provide specific choice options.
2423
*
25-
* [^FF_DEV_2007]: `ff_dev_2007_rework_choices_280322_short` should be enabled to use `html` attribute
2624
* [^FF_PROD_309]: The `hint` attribute works only when `fflag_feat_front_prod_309_choice_hint_080523_short` is enabled
2725
*
2826
* @example
@@ -44,7 +42,7 @@ import { HintTooltip } from '../../components/Taxonomy/Taxonomy';
4442
* @param {string} [alias] - Alias for the choice. If used, the alias replaces the choice value in the annotation results. Alias does not display in the interface.
4543
* @param {style} [style] - CSS style of the checkbox element
4644
* @param {string} [hotkey] - Hotkey for the selection
47-
* @param {string} [html] - Can be used to show enriched content[^FF_DEV_2007], it has higher priority than `value`, however `value` will be used in the exported result (should be properly escaped)
45+
* @param {string} [html] - Can be used to show enriched content, it has higher priority than `value`, however `value` will be used in the exported result (should be properly escaped)
4846
* @param {string} [hint] - Hint for choice on hover[^FF_PROD_309]
4947
* @param {string} [color] - Color for Taxonomy item
5048
*/
@@ -55,8 +53,8 @@ const TagAttrs = types.model({
5553
value: types.maybeNull(types.string),
5654
hotkey: types.maybeNull(types.string),
5755
style: types.maybeNull(types.string),
56+
html: types.maybeNull(types.string),
5857
color: types.maybeNull(types.string),
59-
...(isFF(FF_DEV_2007) ? { html: types.maybeNull(types.string) } : {}),
6058
...(isFF(FF_PROD_309) ? { hint: types.maybeNull(types.string) } : {}),
6159
});
6260

@@ -92,11 +90,11 @@ const Model = types
9290
},
9391

9492
get sel() {
95-
return !isFF(FF_DEV_2244) || self.isLeaf ? self._sel : self.children.every(child => child.sel === true);
93+
return self.isLeaf ? self._sel : self.children.every(child => child.sel === true);
9694
},
9795

9896
get indeterminate() {
99-
return isFF(FF_DEV_2244) && (self.isLeaf ? false : !self.sel && self.children.some(child => child.sel === true));
97+
return self.isLeaf ? false : !self.sel && self.children.some(child => child.sel === true);
10098
},
10199

102100
get parentChoice() {
@@ -106,13 +104,13 @@ const Model = types
106104
return !self.nestedResults && !!self.parentChoice;
107105
},
108106
get nestedResults() {
109-
return isFF(FF_DEV_2007) && self.parent?.allownested !== false;
107+
return self.parent?.allownested !== false;
110108
},
111109
get _resultValue() {
112110
return self.alias ?? self._value;
113111
},
114112
get resultValue() {
115-
if (isFF(FF_DEV_2007) && self.nestedResults) {
113+
if (self.nestedResults) {
116114
const value = [];
117115
let choice = self;
118116

@@ -171,65 +169,6 @@ const Model = types
171169

172170
const ChoiceModel = types.compose('ChoiceModel', TagParentMixin, TagAttrs, ProcessAttrsMixin, Model, AnnotationMixin);
173171

174-
function triggerElementGetter(el) {
175-
return el?.input?.parentNode?.parentNode;
176-
}
177-
178-
class HtxChoiceView extends Component {
179-
render() {
180-
const { item, store } = this.props;
181-
182-
let style = {};
183-
184-
if (item.style) style = Tree.cssConverter(item.style);
185-
186-
if (!item.visible) {
187-
style['display'] = 'none';
188-
}
189-
190-
const showHotkey =
191-
(store.settings.enableTooltips || store.settings.enableLabelTooltips) &&
192-
store.settings.enableHotkeys &&
193-
item.hotkey;
194-
195-
const props = {
196-
checked: item.sel,
197-
disabled: item.parent?.isReadOnly(),
198-
onChange: ev => {
199-
if (item.isReadOnly()) return;
200-
item.toggleSelected();
201-
ev.nativeEvent.target.blur();
202-
},
203-
};
204-
205-
if (item.isCheckbox) {
206-
const cStyle = Object.assign({ display: 'flex', alignItems: 'center', marginBottom: 0 }, style);
207-
208-
return (
209-
<Form.Item style={cStyle}>
210-
<HintTooltip title={item.hint} triggerElementGetter={triggerElementGetter}>
211-
<Checkbox name={item._value} {...props} disabled={item.isReadOnly()}>
212-
{item._value}
213-
{showHotkey && <Hint>[{item.hotkey}]</Hint>}
214-
</Checkbox>
215-
</HintTooltip>
216-
</Form.Item>
217-
);
218-
} else {
219-
return (
220-
<div style={style}>
221-
<HintTooltip title={item.hint} triggerElementGetter={triggerElementGetter}>
222-
<Radio value={item._value} style={{ display: 'inline-block', marginBottom: '0.5em' }} {...props}>
223-
{item._value}
224-
{showHotkey && <Hint>[{item.hotkey}]</Hint>}
225-
</Radio>
226-
</HintTooltip>
227-
</div>
228-
);
229-
}
230-
}
231-
}
232-
233172
// `name` can't be passed into bem components
234173
const nameWrapper = (Component, name) => {
235174
return props => <Component {...props} name={name} />;
@@ -287,14 +226,7 @@ const HtxNewChoiceView = ({ item, store }) => {
287226
);
288227
};
289228

290-
const HtxOldChoice = inject('store')(observer(HtxChoiceView));
291-
const HtxNewChoice = inject('store')(observer(HtxNewChoiceView));
292-
293-
const HtxChoice = (props) => {
294-
const HtxChoiceComponent = !isFF(FF_DEV_2007) ? HtxOldChoice : HtxNewChoice;
295-
296-
return <HtxChoiceComponent {...props} />;
297-
};
229+
const HtxChoice = inject('store')(observer(HtxNewChoiceView));
298230

299231
Registry.addTag('choice', ChoiceModel, HtxChoice);
300232

src/tags/control/Choices.js

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Form, Select } from 'antd';
2+
import { Select } from 'antd';
33
import { observer } from 'mobx-react';
44
import { types } from 'mobx-state-tree';
55

@@ -19,7 +19,7 @@ import './Choices/Choises.styl';
1919

2020
import './Choice';
2121
import DynamicChildrenMixin from '../../mixins/DynamicChildrenMixin';
22-
import { FF_DEV_2007, FF_DEV_2007_DEV_2008, FF_LSDV_4583, isFF } from '../../utils/feature-flags';
22+
import { FF_LSDV_4583, isFF } from '../../utils/feature-flags';
2323
import { ReadOnlyControlMixin } from '../../mixins/ReadOnlyMixin';
2424
import SelectedChoiceMixin from '../../mixins/SelectedChoiceMixin';
2525
import { HintTooltip } from '../../components/Taxonomy/Taxonomy';
@@ -37,8 +37,6 @@ const { Option } = Select;
3737
* The `Choices` tag can be used with any data types.
3838
*
3939
* [^FF_LSDV_4583]: `fflag_feat_front_lsdv_4583_multi_image_segmentation_short` should be enabled for `perItem` functionality.
40-
* [^FF_DEV_2007_DEV_2008]: `ff_dev_2007_dev_2008_dynamic_tag_children_250322_short` should be enabled to use dynamic options.
41-
* [^FF_DEV_2007]: `ff_dev_2007_rework_choices_280322_short` should be enabled to use `html` attribute
4240
*
4341
* @example
4442
* <!--Basic text classification labeling configuration-->
@@ -54,8 +52,8 @@ const { Option } = Select;
5452
*
5553
* @example <caption>This config with dynamic labels</caption>
5654
* <!--
57-
* `Choice`s can be loaded dynamically from task data[^FF_DEV_2007_DEV_2008]. It should be an array of objects with attributes.
58-
* `html` can be used to show enriched content[^FF_DEV_2007], it has higher priority than `value`, however `value` will be used in the exported result.
55+
* `Choice`s can be loaded dynamically from task data. It should be an array of objects with attributes.
56+
* `html` can be used to show enriched content, it has higher priority than `value`, however `value` will be used in the exported result.
5957
* -->
6058
* <View>
6159
* <Audio name="audio" value="$audio" />
@@ -97,20 +95,15 @@ const { Option } = Select;
9795
* @param {string} [whenChoiceValue] - Use with visibleWhen ("choice-selected" or "choice-unselected") and whenTagName, both are required. Narrow down visibility by choice value
9896
* @param {boolean} [perRegion] - Use this tag to select a choice for a specific region instead of the entire task
9997
* @param {boolean} [perItem] - Use this tag to select a choice for a specific item inside the object instead of the whole object[^FF_LSDV_4583]
100-
* @param {string} [value] - Task data field containing a list of dynamically loaded choices (see example below)[^FF_DEV_2007_DEV_2008]
98+
* @param {string} [value] - Task data field containing a list of dynamically loaded choices (see example below)
10199
* @param {boolean} [allowNested] - Allow to use `children` field in dynamic choices to nest them. Submitted result will contain array of arrays, every item is a list of values from topmost parent choice down to selected one.
102100
*/
103101
const TagAttrs = types.model({
104102
toname: types.maybeNull(types.string),
105-
106103
showinline: types.maybeNull(types.boolean),
107-
108104
choice: types.optional(types.enumeration(['single', 'single-radio', 'multiple']), 'single'),
109-
110105
layout: types.optional(types.enumeration(['select', 'inline', 'vertical']), 'vertical'),
111-
112-
...(isFF(FF_DEV_2007_DEV_2008) ? { value: types.optional(types.string, '') } : {}),
113-
106+
value: types.optional(types.string, ''),
114107
allownested: types.optional(types.boolean, false),
115108
});
116109

@@ -252,7 +245,7 @@ const ChoicesModel = types.compose(
252245
ReadOnlyControlMixin,
253246
SelectedChoiceMixin,
254247
VisibilityMixin,
255-
...(isFF(FF_DEV_2007_DEV_2008) ? [DynamicChildrenMixin] : []),
248+
DynamicChildrenMixin,
256249
AnnotationMixin,
257250
TagAttrs,
258251
Model,
@@ -296,9 +289,7 @@ const HtxChoices = observer(({ item }) => {
296289
{item.layout === 'select' ? (
297290
<ChoicesSelectLayout item={item} />
298291
) : (
299-
!isFF(FF_DEV_2007)
300-
? <Form layout={item.layout}>{Tree.renderChildren(item, item.annotation)}</Form>
301-
: Tree.renderChildren(item, item.annotation)
292+
Tree.renderChildren(item, item.annotation)
302293
)}
303294
</Block>
304295
);

src/tags/control/Labels/Labels.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import DynamicChildrenMixin from '../../../mixins/DynamicChildrenMixin';
1313
import LabelMixin from '../../../mixins/LabelMixin';
1414
import SelectedModelMixin from '../../../mixins/SelectedModel';
1515
import { Block } from '../../../utils/bem';
16-
import { FF_DEV_2007_DEV_2008, isFF } from '../../../utils/feature-flags';
1716
import ControlBase from '../Base';
1817
import '../Label';
1918
import './Labels.styl';
@@ -85,7 +84,7 @@ const TagAttrs = types.model({
8584
fillopacity: types.maybeNull(customTypes.range()),
8685
allowempty: types.optional(types.boolean, false),
8786

88-
...(isFF(FF_DEV_2007_DEV_2008) ? { value: types.optional(types.string, '') } : {}),
87+
value: types.optional(types.string, ''),
8988
});
9089

9190
/**
@@ -141,7 +140,7 @@ const LabelsModel = types.compose(
141140
ModelAttrs,
142141
TagAttrs,
143142
AnnotationMixin,
144-
...(isFF(FF_DEV_2007_DEV_2008) ? [DynamicChildrenMixin] : []),
143+
DynamicChildrenMixin,
145144
Model,
146145
SelectedModelMixin.props({ _child: 'LabelModel' }),
147146
);

src/tags/control/Taxonomy/Taxonomy.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import { SharedStoreMixin } from '../../../mixins/SharedChoiceStore/mixin';
2121
import VisibilityMixin from '../../../mixins/Visibility';
2222
import { parseValue } from '../../../utils/data';
2323
import {
24-
FF_DEV_2007_DEV_2008,
2524
FF_DEV_3617,
2625
FF_LSDV_4583,
2726
FF_TAXONOMY_ASYNC,
@@ -102,7 +101,7 @@ const TagAttrs = types.model({
102101
maxwidth: types.maybeNull(types.string),
103102
dropdownwidth: types.maybeNull(types.string),
104103
maxusages: types.maybeNull(types.string),
105-
...(isFF(FF_DEV_2007_DEV_2008) ? { value: types.optional(types.string, '') } : {}),
104+
value: types.optional(types.string, ''),
106105
});
107106

108107
function traverse(root) {
@@ -135,7 +134,7 @@ function traverse(root) {
135134
};
136135

137136
if (!root) return [];
138-
if (isFF(FF_DEV_2007_DEV_2008) && !Array.isArray(root)) return visitUnique([root]);
137+
if (!Array.isArray(root)) return visitUnique([root]);
139138
return visitUnique(root);
140139
}
141140

@@ -573,7 +572,7 @@ const TaxonomyModel = types.compose('TaxonomyModel',
573572
ControlBase,
574573
ClassificationBase,
575574
TagAttrs,
576-
...(isFF(FF_DEV_2007_DEV_2008) ? [DynamicChildrenMixin] : []),
575+
DynamicChildrenMixin,
577576
AnnotationMixin,
578577
RequiredMixin,
579578
Model,

0 commit comments

Comments
 (0)