|
| 1 | +# LSF init |
| 2 | + |
| 3 | +Different thoughts and investingations related to LSF init. |
| 4 | + |
| 5 | +## App render |
| 6 | + |
| 7 | +We have 3 UI versions: old (awful), medium (outliner v1), modern (draggable panels) |
| 8 | + |
| 9 | +Flags: |
| 10 | + |
| 11 | +- `ff_front_1170_outliner_030222_short` — initial **FF_1170** |
| 12 | +- `fflag_feat_front_dev_3873_labeling_ui_improvements_short` — modern **FF_3873** |
| 13 | + |
| 14 | +Components: |
| 15 | + |
| 16 | +- modern (FF_1170 + FF_3873): `SideTabsPanels` + `SidePanels/TabPanels` + `OutlinerTree` + `BottomBar` |
| 17 | +- medium (FF_1170): `SidePanels` + `OutlinerTree` |
| 18 | +- old: `SidebarTabs` + `AnnotationTab` + `Entities/RegionTree` and surprisingly `BottomBar` if FF_3873 enabled without FF_1170 |
| 19 | + |
| 20 | +They all have `TopBar` with 2 different layouts: |
| 21 | +- modern (FF_3873): annotations tab by `AnnotationsCarousel` + custom actions |
| 22 | +- medium and old: annotations dropdown by `TopBar/Annotations` + `TopBar/Actions` |
| 23 | + |
| 24 | +## configureStore, environments and init |
| 25 | + |
| 26 | +configureStore() has the idea of environment, which comes from development/production run |
| 27 | +and contains some very important but not irreplaceable things: |
| 28 | +- rootElement() (yes, that's a function!) is redundant |
| 29 | +- getData() should be embedded |
| 30 | +- getExample() is definitely too much — example should be set from outside |
| 31 | +- configureApplication() just passes through a lot of methods with default values which are just a placeholders |
| 32 | + |
| 33 | +## selected annotations |
| 34 | + |
| 35 | +All annotations should've been always selected on init, most probably because of some weird issues in the past. |
| 36 | +Don't think we need it now. That could be pretty heavy operation. And it's something we should always think about. |
| 37 | + |
| 38 | +## `AppStore#initializeStore` |
| 39 | + |
| 40 | +Main flow: LabelStudio -> constructor -> createApp -> configureStore -> initializeStore (+src/Component does the similar) |
| 41 | + |
| 42 | +Also it's called at these places right after `assignTask()`: |
| 43 | +- AnnotationPreview (?) |
| 44 | +- Config/Preview |
| 45 | +- ReviewPage -> setTask |
| 46 | +- lsf-sdk -> setLSFTask |
| 47 | + |
| 48 | +## `hydrated` |
| 49 | + |
| 50 | +Should prevent some types of objects from requesting resources too early because the whole LSF will be recreated. |
| 51 | + |
| 52 | +It's default to `false` in AppStore; |
| 53 | +but set to `true` by default in configureStore if value is not reassigned. |
| 54 | +Can only be changed on init if Audio3 FF is on. |
| 55 | + |
| 56 | +For some reason it's set to `false` in lsf-sdk constructor, but `true` in ReviewPage's setTask. |
| 57 | +But is set to `true` in lsf-sdk setLSFTask. |
| 58 | + |
| 59 | +Apparently it was not used anymore after https://github.com/HumanSignal/label-studio-frontend/pull/1166 |
| 60 | + |
| 61 | +## `userGenerate` and `sentUserGenerate` |
| 62 | + |
| 63 | +wtf?? lot of logic without comments |
| 64 | + |
| 65 | +There is `Annotation#exists` getter to check that annotation was saved and can be updated. |
| 66 | + |
| 67 | +`userGenerate` is used to mark annotations that were added by user in current session or is still a draft. Is set to true when: |
| 68 | + |
| 69 | +- annotation created by user in `createAnnotation()` |
| 70 | +- annotation created from prediction in `addAnnotationFromPrediction()` |
| 71 | +- draft is loaded without annotation in `setAnnotation()` in lsf-sdk |
| 72 | +- is set by default to true, so it’s worth to check other places; but it defaults to false in `createItem()` |
| 73 | + |
| 74 | +Can be submitted in current session, but this flag will remain the same. |
| 75 | + |
| 76 | +## `setAnnotation()` |
| 77 | + |
| 78 | +called from 3 places: |
| 79 | + |
| 80 | +- `setLSFTask()` |
| 81 | +- `onStorageInitialized()` — called from `AppStore#initializeStore()`, one of the core LSF methods; if there is a task and that’s not a Label Stream it selects annotation based on `initialAnnotation` and `lastAnnotation` |
| 82 | +- `onDeleteAnnotation()` |
| 83 | + |
| 84 | +## Huge mess with "side panels" |
| 85 | + |
| 86 | +We have three versions of interface: |
| 87 | +1. with DEV-1170 FF off we have old interface with `components/SidebarTabs` |
| 88 | +2. with DEV-1170 FF on and DEV-3873 off we have intermediate interface with `components/SidePanels/SidePanels.tsx` |
| 89 | +3. with both FFs on we have new desired interface with `components/SidePanels/TabPanels/SideTabsPanels.tsx` |
| 90 | + |
| 91 | +They both are only disabled in couple places. |
| 92 | + |
| 93 | +Also the whole `App.panels` prop is only used in the first, the oldest version. |
| 94 | + |
| 95 | +Apparently, `panels` were used only to add Comments tab and even this tab was moved into AnnotationTab after |
| 96 | +https://github.com/HumanSignal/label-studio-frontend/pull/774. So they are removed along with anything related. |
| 97 | + |
| 98 | +## `assignTask` |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | +## `initializeStore` |
| 103 | + |
| 104 | +`afterReset()` — refill StaredStorage Stores in `extender.js`, but looks like it's not used |
| 105 | + |
| 106 | +initRoot — config |
| 107 | + |
| 108 | +for every prediction: addPrediction, selectPrediction, deserializeResults |
| 109 | + |
| 110 | +for every annotation: addAnnotation, selectAnnotation, deserializeResults, reinitHistory (!!) |
| 111 | + |
| 112 | +setInitialValues for last annotation |
| 113 | + |
| 114 | +setHistory to set annotation history — some messed up thing in general |
| 115 | + |
| 116 | +set initialized = true and invoke storageInitialized |
| 117 | + |
| 118 | + |
| 119 | +### problematic places during store init |
| 120 | + |
| 121 | +They might require annotation to be selected. |
| 122 | + |
| 123 | +ToolManagerMixin.afterAttach() — does lot of things with tools, selecting, unselecting, assigning |
| 124 | + |
| 125 | +RelationStore.afterAttach() — was referring to selected annotation; fixed |
| 126 | + |
| 127 | +Annotation.afterAttach() calls super helpful method annotationAttached(), but it's only implemented in Pairwise |
| 128 | + |
| 129 | + |
| 130 | +## What could happen on `deserializeResults()`? |
| 131 | + |
| 132 | +prepareAnnotation -> fixBrokenAnnotation -> some changes on result json |
| 133 | + |
| 134 | +deserializeSingleResult for every result in JSON — some area/result/state manipulations, |
| 135 | +should be no side effects. |
| 136 | +it calls `updateAppearenceFromState` for merged labels and results (only Video tag regions), |
| 137 | +but this should only be called on selected annotation. |
| 138 | + |
| 139 | +cleanClassificationAreas — WUT??? |
| 140 | + |
| 141 | +updateFromResult for every global classification — a bit redundant unless we select annotation; |
| 142 | +but there is `hidden` param already, used only on Annotation History deserialization. |
| 143 | + |
| 144 | +deserializeRelation for every relation |
| 145 | + |
| 146 | + |
| 147 | +# Streams |
| 148 | + |
| 149 | +- one-way data flow |
| 150 | +- describe all possible external things that can affect current view |
| 151 | + |
| 152 | +# Still left to fix after https://github.com/HumanSignal/label-studio-frontend/pull/1640 |
| 153 | + |
| 154 | +- Annotation History should be updated with correct annotation when we select it from View All; why not to do the same on usual annotation select? and if we do why do we need special case here? |
| 155 | + |
| 156 | +- **Experiment**: use dev addons from outside via additional entry point for webpack. And how to distinguish this from e2e runs? Additional param? |
| 157 | + |
| 158 | +- `description` option should be renamed to `instructions` |
| 159 | + |
| 160 | + |
| 161 | +# Other improvements |
| 162 | + |
| 163 | + |
| 164 | +https://github.com/HumanSignal/label-studio-frontend/blob/d0dd212bf7b12cb7f4469c9c2aa32dfe166f5abe/src/stores/RegionStore.js#L181-L183 |
| 165 | +could be shifted towards self.selection.selectRegions(regions) and then |
| 166 | +https://github.com/HumanSignal/label-studio-frontend/blob/d0dd212bf7b12cb7f4469c9c2aa32dfe166f5abe/src/stores/RegionStore.js#L45-L47 |
| 167 | +can be changed to usual method called only once. |
| 168 | + |
| 169 | + |
| 170 | + |
| 171 | + |
| 172 | +# Current changes |
| 173 | + |
| 174 | +### Main change |
| 175 | + |
| 176 | +**Only one annotation is selected during task opening.** |
| 177 | + |
| 178 | +We have the concept of selecting annotation, when we not just assign it as current one, but also update data in tags, trigger external event, load annotation history, setup hotkeys, set initial values. |
| 179 | + |
| 180 | +Previosly it was required to select every annotation to do some extra work in regions/tags inside it because of some quirky legacy code. I fixed what I found so far and ran all possible tests — they all are green, so consider this change mostly safe. |
| 181 | + |
| 182 | +Benefits: |
| 183 | +- improved performance as only one annotation is selected, reducing number of calculations and renders |
| 184 | +- no excess network requests to retrieve annotation history for every of these annotations |
| 185 | +- more clean code |
| 186 | +- one more step to remove one of the oldest legacy concept of `states`: it's not used in init anymore |
| 187 | + |
| 188 | +Things changed: |
| 189 | +- `STORE_INIT_OK` global var added to catch tags that can't properly work with new system (edge cases we missed) |
| 190 | +- apparently we have only one unit test for tags — Ranker; it's securely mocked |
| 191 | + |
| 192 | +Concerns: |
| 193 | +- `states` in Video tag select only *Labels controls, but changed code is in `fixBrokenAnnotation` which will do nothing to Video anyway |
| 194 | +- in potential missed edge case app will just crash |
| 195 | +- we could potentially check that we are inside init process by some flag, right? |
| 196 | + |
| 197 | +### Other changes |
| 198 | +- removed Predictions panel and related code like showAllPredictions |
| 199 | +- removed panels from App and down the stream — we don't use them anywhere (3rd party LSF can be affected, but not sure anyone using panels there) |
| 200 | +- converted `LabelStudio.js` to TypeScript |
| 201 | +- fixed bunch of annoying react warnings (non-html props, wrong values, missed refs) |
| 202 | +- started to reorganize our "envs" to get rid of them at some point; for now it's `getRoot()` removed from there |
| 203 | +- removed `SidebarPage` as it was useless, plus removed multi-tabs support from `SidebarTabs` as `panels` were not used; plus that's all only for the old interface which is about to be removed |
| 204 | +- removed `hydrated` as it's not used anymore after https://github.com/HumanSignal/label-studio-frontend/pull/1166 |
0 commit comments