Skip to content

Commit

Permalink
feat: OPTIC-107: Draft saving on view all (#5141)
Browse files Browse the repository at this point in the history
* [submodules] Build static HumanSignal/dm2

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7097074264

* [submodules] Build static HumanSignal/dm2

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7116534992

* [submodules] Build static HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7144515885

* [submodules] Build static HumanSignal/dm2

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7146147747

* [submodules] Build static HumanSignal/dm2

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7146602686

* [submodules] Build static HumanSignal/dm2

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7147053583

* [submodules] Build static HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7343943231

* [submodules] Build static HumanSignal/dm2

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7343979856

* [submodules] Build static HumanSignal/dm2

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7403418709

* [submodules] Build static HumanSignal/dm2

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7411598048

* [submodules] Build static HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7411646587

* [submodules] Build static HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7411763053

* [submodules] Build static HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7411947490

* [submodules] Build static HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7413202243

* [submodules] Copy src HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7450770716

* [submodules] Build static HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7450770716

* ci: Build frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7450816474

* [submodules] Copy src HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7452161161

* [submodules] Build static HumanSignal/label-studio-frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7452161161

* ci: Build frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/7452196513

---------

Co-authored-by: Travis1282 <travisjosephclark@gmail.com>
Co-authored-by: Travis Clark <travisclark@Traviss-MBP-2.lan>
Co-authored-by: Travis1282 <Travis1282@users.noreply.github.com>
Co-authored-by: robot-ci-heartex <robot-ci-heartex@users.noreply.github.com>
  • Loading branch information
5 people committed Jan 9, 2024
1 parent a9c13b1 commit 632d3f9
Show file tree
Hide file tree
Showing 23 changed files with 131 additions and 116 deletions.
2 changes: 1 addition & 1 deletion label_studio/frontend/dist/dm/js/main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion label_studio/frontend/dist/dm/js/main.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions label_studio/frontend/dist/dm/version.json
@@ -1,6 +1,6 @@
{
"message": "feat: DIA-474: [FE] add new column for DE",
"commit": "a8e6e5e6cd6601d765a7f0abd4efa87cec1a3fe5",
"message": "feat: OPTIC-107: Draft saving on view all",
"commit": "b2006083fb40a3d5a1ee7979ff24497864dfcdac",
"branch": "master",
"date": "2024-01-03T07:13:20Z"
"date": "2024-01-04T09:37:55Z"
}
2 changes: 1 addition & 1 deletion label_studio/frontend/dist/lsf/css/main.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion label_studio/frontend/dist/lsf/css/main.css.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion label_studio/frontend/dist/lsf/js/main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion label_studio/frontend/dist/lsf/js/main.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions label_studio/frontend/dist/lsf/version.json
@@ -1,6 +1,6 @@
{
"message": "fix: LEAP-344: View all annotation tab is not loading",
"commit": "eb1194c1e8ad5f9c0e725b2955dbc202f169649b",
"message": "feat: OPTIC-107: Draft saving on view all",
"commit": "08aa5b599a64e4b90956b861739df273946ee738",
"branch": "master",
"date": "2024-01-08T09:48:32Z"
"date": "2024-01-08T13:19:30Z"
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion web/dist/libs/editor/main.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion web/dist/libs/editor/main.css.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion web/dist/libs/editor/main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion web/dist/libs/editor/main.js.map

Large diffs are not rendered by default.

Expand Up @@ -171,6 +171,7 @@ const RelationItemObserver = observer(({ relation, startNode, endNode, visible,
endNode={endNode}
direction={relation.direction}
visible={visibility}
labels={relation.selectedValues}
{...rest}
/>
) : null;
Expand Down Expand Up @@ -229,7 +230,6 @@ class RelationsOverlay extends PureComponent {
rootRef={this.rootNode}
startNode={relation.node1}
endNode={relation.node2}
labels={relation.relations?.selectedValues()}
dimm={hasHighlight && !highlighted}
highlight={highlighted}
visible={highlighted || visible}
Expand Down
Expand Up @@ -31,6 +31,7 @@

&__icon
width 24px
min-height 24px
display flex
flex none
position relative
Expand Down
Expand Up @@ -56,9 +56,9 @@ const RelationItem: FC<{relation: any}> = observer(({ relation }) => {
const { direction } = relation;

switch (direction) {
case 'left': return <IconRelationLeft/>;
case 'right': return <IconRelationRight/>;
case 'bi': return <IconRelationBi/>;
case 'left': return <IconRelationLeft data-direction={relation.direction}/>;
case 'right': return <IconRelationRight data-direction={relation.direction}/>;
case 'bi': return <IconRelationBi data-direction={relation.direction}/>;
default: return null;
}
}, [relation.direction]);
Expand Down Expand Up @@ -92,6 +92,7 @@ const RelationItem: FC<{relation: any}> = observer(({ relation }) => {
{(hovered || relation.showMeta) && relation.hasRelations && (
<Button
primary={relation.showMeta}
aria-label={`${relation.showMeta ? 'Hide' : 'Show'} Relation Labels`}
type={relation.showMeta ? undefined : 'text'}
onClick={relation.toggleMeta}
style={{ padding: 0 }}
Expand All @@ -102,14 +103,14 @@ const RelationItem: FC<{relation: any}> = observer(({ relation }) => {
</Elem>
<Elem name="action">
{(hovered || !relation.visible) && (
<Button type="text" onClick={relation.toggleVisibility}>
<Button type="text" onClick={relation.toggleVisibility} aria-label={`${relation.visible ? 'Hide' : 'Show'} Relation`}>
{relation.visible ? <IconEyeOpened/> : <IconEyeClosed />}
</Button>
)}
</Elem>
<Elem name="action">
{hovered && (
<Button type="text" danger onClick={() => {
<Button type="text" danger aria-label="Delete Relation" onClick={() => {
relation.node1.setHighlight(false);
relation.node2.setHighlight(false);
relation.parent.deleteRelation(relation);
Expand All @@ -127,10 +128,9 @@ const RelationItem: FC<{relation: any}> = observer(({ relation }) => {
);
});

const RelationMeta: FC<any> = ({ relation }) => {
const { relations } = relation;
const { children, choice } = relations;
const selected = relations.getSelected().map((v: any) => v.value);
const RelationMeta: FC<any> = observer(({ relation }) => {
const { selectedValues, control } = relation;
const { children, choice } = control;

const selectionMode = useMemo(() => {
return choice === 'multiple' ? 'multiple' : undefined;
Expand All @@ -139,17 +139,16 @@ const RelationMeta: FC<any> = ({ relation }) => {
const onChange = useCallback((val: any) => {
const values: any[] = wrapArray(val);

relations.unselectAll();
values.forEach(v => relations.findRelation(v).setSelected(true));
}, []);
relation.setRelations(values);
}, [relation]);

return (
<Block name="relation-meta">
<Select
mode={selectionMode}
style={{ width: '100%' }}
placeholder="Select labels"
defaultValue={selected}
value={selectedValues}
onChange={onChange}
>
{children.map((c: any) => (
Expand All @@ -160,6 +159,6 @@ const RelationMeta: FC<any> = ({ relation }) => {
</Select>
</Block>
);
};
});

export const Relations = observer(RealtionsComponent);
1 change: 1 addition & 0 deletions web/libs/editor/src/components/TopBar/Actions.js
Expand Up @@ -15,6 +15,7 @@ export const Actions = ({ store }) => {
const isViewAll = annotationStore.viewingAll;

const onToggleVisibility = useCallback(() => {
!isViewAll && entity.saveDraftImmediatelyWithResults({ useToast: true });
annotationStore.toggleViewingAllAnnotations();
}, [annotationStore]);

Expand Down
7 changes: 6 additions & 1 deletion web/libs/editor/src/components/TopBar/TopBar.js
Expand Up @@ -19,6 +19,11 @@ export const TopBar = observer(({ store }) => {

const isViewAll = annotationStore?.viewingAll === true;

const toggleViewAll = () => {
!isViewAll && entity.saveDraftImmediatelyWithResults({ useToast: true });
annotationStore.toggleViewingAllAnnotations();
};

return store ? (
<Block name="topbar" mod={{ newLabelingUI: isFF(FF_DEV_3873) }}>
{isFF(FF_DEV_3873) ? (
Expand All @@ -31,7 +36,7 @@ export const TopBar = observer(({ store }) => {
icon={<IconViewAll />}
type="text"
aria-label="View All"
onClick={() => annotationStore.toggleViewingAllAnnotations()}
onClick={toggleViewAll}
primary={ isViewAll }
style={{
height: 36,
Expand Down
3 changes: 2 additions & 1 deletion web/libs/editor/src/core/TimeTraveller.js
Expand Up @@ -9,7 +9,7 @@ const TimeTraveller = types
undoIdx: 0,
targetPath: '',
skipNextUndoState: types.optional(types.boolean, false),

lastAdditionTime: types.optional(types.Date, new Date()),
createdIdx: 0,
})
.volatile(() => ({
Expand Down Expand Up @@ -102,6 +102,7 @@ const TimeTraveller = types
self.undoIdx = self.history.length - 1;
replaceNextUndoState = false;
changesDuringFreeze = false;
self.lastAdditionTime = new Date();
},

reinit(force = true) {
Expand Down
34 changes: 24 additions & 10 deletions web/libs/editor/src/stores/Annotation/Annotation.js
Expand Up @@ -31,6 +31,12 @@ import { UserExtended } from '../UserStore';

const hotkeys = Hotkey('Annotations', 'Annotations');

const TrackedState = types
.model('TrackedState', {
areas: types.map(Area),
relationStore: types.optional(RelationStore, {}),
});

export const Annotation = types
.model('Annotation', {
id: types.identifier,
Expand Down Expand Up @@ -70,19 +76,19 @@ export const Annotation = types
ground_truth: types.optional(types.boolean, false),
skipped: false,

history: types.optional(TimeTraveller, { targetPath: '../areas' }),
// This field stores all data that affects undo/redo history
// It should contain real objects to be able to work with them through snapshots
// Annotation will use getters to get them at the top level
// This data is never redefined directly, it's empty at the start
trackedState: types.optional(TrackedState, {}),
history: types.optional(TimeTraveller, { targetPath: '../trackedState' }),

dragMode: types.optional(types.boolean, false),

editable: types.optional(types.boolean, true),
readonly: types.optional(types.boolean, false),

relationMode: types.optional(types.boolean, false),
relationStore: types.optional(RelationStore, {
relations: [],
}),

areas: types.map(Area),

suggestions: types.map(Area),

Expand All @@ -98,6 +104,14 @@ export const Annotation = types

...(isFF(FF_DEV_3391) ? { root: Types.allModelsTypes() } : {}),
})
.views(self => ({
get areas() {
return self.trackedState.areas;
},
get relationStore() {
return self.trackedState.relationStore;
},
}))
.preProcessSnapshot(sn => {
// sn.draft = Boolean(sn.draft);
let user = sn.user ?? sn.completed_by ?? undefined;
Expand Down Expand Up @@ -188,7 +202,7 @@ export const Annotation = types
return self.results
.map(r => r.serialize())
.filter(Boolean)
.concat(self.relationStore.serializeAnnotation());
.concat(self.relationStore.serialize());
},

get serializedSelection() {
Expand Down Expand Up @@ -696,11 +710,11 @@ export const Annotation = types
if (self.autosave) self.autosave.flush();
},

async saveDraftImmediatelyWithResults() {
async saveDraftImmediatelyWithResults(params) {
// There is no draft to save as it was already saved as an annotation
if (self.submissionStarted || self.isDraftSaving) return {};
self.setDraftSaving(true);
const res = await self.saveDraft(null);
const res = await self.saveDraft(params);

return res;
},
Expand Down Expand Up @@ -928,7 +942,7 @@ export const Annotation = types
const result = self.results
.map(r => r.serialize(options))
.filter(Boolean)
.concat(self.relationStore.serializeAnnotation(options));
.concat(self.relationStore.serialize(options));

document.body.style.cursor = 'default';

Expand Down

0 comments on commit 632d3f9

Please sign in to comment.