Skip to content

Commit

Permalink
feat: Allow to reset record (#2338)
Browse files Browse the repository at this point in the history
# Description

This PR includes reset button at record level and as global action to to
allow resetting the record to previous status and annotation

Closes #2278
See #2264

**Type of change**

- [x] New feature (non-breaking change which adds functionality)

**How Has This Been Tested**

- [x] Update recordActionButtons test

**Checklist**

- [x] I have merged the original branch into my forked branch
- [x] follows the style guidelines of this project
- [x] I did a self-review of my code
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works

---------

Co-authored-by: keithCuniah <[email protected]>
  • Loading branch information
leiyre and keithCuniah authored Feb 16, 2023
1 parent 94e8948 commit 00e0efc
Show file tree
Hide file tree
Showing 24 changed files with 597 additions and 124 deletions.
1 change: 1 addition & 0 deletions frontend/assets/icons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require('./no-matching')
require('./pen')
require('./progress')
require('./refresh')
require('./reset')
require('./row-last')
require('./search')
require('./similarity')
Expand Down
27 changes: 27 additions & 0 deletions frontend/assets/icons/reset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* coding=utf-8
* Copyright 2021-present, the Recognai S.L. team.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* eslint-disable */
var icon = require('vue-svgicon')
icon.register({
'reset': {
width: 16,
height: 18,
viewBox: '0 0 16 18',
data: '<path pid="0" d="M.041 0h2.39v3.055a8.364 8.364 0 11-1.24 11.962l1.936-1.415a5.974 5.974 0 10.987-8.823h3.097v2.39H.04V0z" _fill="#000"/>'
}
})
2 changes: 1 addition & 1 deletion frontend/components/base/BaseToast/Toast.vue
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ $toast-colors: map-merge(
// Colors
@each $color, $value in $toast-colors {
.toast-#{$color} {
border: 2px solid $value;
border: 1px solid $value;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
-->

<template>
<div v-if="annotationEnabled" class="container">
<div v-if="showGlobalActions" class="container">
<div class="global-actions">
<validate-discard-action
:datasetId="datasetId"
Expand All @@ -27,6 +27,7 @@
@discard-records="onDiscard"
@validate-records="onValidate"
@clear-records="onClear"
@reset-records="onReset"
@on-select-labels="onSelectLabels($event)"
/>
<create-new-action v-if="isCreationLabel" @new-label="onNewLabel" />
Expand All @@ -35,7 +36,7 @@
</template>

<script>
import { getViewSettingsByDatasetName } from "@/models/viewSettings.queries";
import { getViewSettingsWithPaginationByDatasetName } from "@/models/viewSettings.queries";
export default {
props: {
datasetId: {
Expand Down Expand Up @@ -69,11 +70,17 @@ export default {
},
computed: {
viewSettings() {
return getViewSettingsByDatasetName(this.datasetName);
return getViewSettingsWithPaginationByDatasetName(this.datasetName);
},
annotationEnabled() {
return this.viewSettings.viewMode === "annotate";
},
paginationSizeIsOne() {
return this.viewSettings.pagination.size === 1;
},
showGlobalActions() {
return this.annotationEnabled && !this.paginationSizeIsOne;
},
},
methods: {
onValidate($event) {
Expand All @@ -85,6 +92,9 @@ export default {
onClear($event) {
this.$emit("clear-records", $event);
},
onReset($event) {
this.$emit("reset-records", $event);
},
onSelectLabels($event) {
this.$emit("on-select-labels", $event);
},
Expand All @@ -109,7 +119,7 @@ export default {
align-items: center;
width: 100%;
text-align: left;
padding: 1em $base-space * 2;
padding: 10px $base-space * 2;
background: palette(white);
border-radius: $border-radius-m;
position: relative;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,66 +16,88 @@
-->

<template>
<div
class="validate-discard-actions"
:class="[
selectedRecords.length ? '' : 'validate-discard-actions--disabled',
]"
>
<div class="validate-discard-actions">
<base-checkbox
v-model="allSelected"
:disabled="!visibleRecords.length"
class="list__item__checkbox"
/>
<TextClassificationBulkAnnotationSingle
v-if="datasetTask === 'TextClassification' && !isMultiLabel"
:class="'validate-discard-actions__select'"
:multi-label="isMultiLabel"
:options="availableLabels"
@selected="onSelectLabels($event)"
/>
<TextClassificationBulkAnnotationComponent
v-if="datasetTask === 'TextClassification' && isMultiLabel"
:class="'validate-discard-actions__select'"
:datasetId="datasetId"
:records="selectedRecords"
:recordsIds="selectedRecordsIds"
:labels="availableLabels"
@on-update-annotations="onUpdateAnnotations"
/>
<base-button
class="clear validate-discard-actions__button"
@click="onValidate"
data-title="Validate"
>
<svgicon name="validate" />
</base-button>
<base-button
class="clear validate-discard-actions__button"
@click="onDiscard"
data-title="Discard"
>
<svgicon name="discard" />
</base-button>
<base-button
v-if="datasetTask !== 'Text2Text'"
class="clear validate-discard-actions__button"
@click="onClear"
data-title="Clear"
>
<svgicon name="clear" />
</base-button>
<p v-if="selectedRecords.length" class="validate-discard-actions__text">
Actions will apply to the
<span>{{ selectedRecords.length }} records</span> selected
</p>
<template v-if="selectedRecords.length">
<TextClassificationBulkAnnotationSingle
v-if="datasetTask === 'TextClassification' && !isMultiLabel"
:class="'validate-discard-actions__select'"
:multi-label="isMultiLabel"
:options="availableLabels"
@selected="onSelectLabels($event)"
/>
<TextClassificationBulkAnnotationComponent
v-if="datasetTask === 'TextClassification' && isMultiLabel"
:class="'validate-discard-actions__select'"
:datasetId="datasetId"
:records="selectedRecords"
:recordsIds="selectedRecordsIds"
:labels="availableLabels"
@on-update-annotations="onUpdateAnnotations"
/>
<base-button
class="clear validate-discard-actions__button"
@click="onValidate"
data-title="Validate"
>
<i
id="validateButton"
:key="isAnyPendingStatusRecord"
v-badge="{
showBadge: isAnyPendingStatusRecord,
verticalPosition: 'top',
horizontalPosition: 'right',
}"
>
<svgicon name="validate" />
</i>
</base-button>
<base-button
class="clear validate-discard-actions__button"
@click="onDiscard"
data-title="Discard"
>
<svgicon name="discard" />
</base-button>
<template v-if="allowClearOrReset">
<base-button
class="clear validate-discard-actions__button"
@click="onClear"
data-title="Clear"
>
<svgicon name="clear" />
</base-button>
<base-button
class="clear validate-discard-actions__button"
@click="onReset"
data-title="Reset"
>
<svgicon name="reset" />
</base-button>
</template>
<p
v-if="selectedRecords.length"
class="validate-discard-actions__text"
:class="{
'validate-discard-actions__text_pending_record':
isAnyPendingStatusRecord,
}"
>
{{ message }}
</p>
</template>
</div>
</template>

<script>
import "assets/icons/validate";
import "assets/icons/discard";
import "assets/icons/clear";
import "assets/icons/reset";
import { getDatasetFromORM } from "@/models/dataset.utilities";
import { mapActions } from "vuex";
Expand Down Expand Up @@ -115,11 +137,52 @@ export default {
// TODO: when record will be in own ORM table, replace next line by query ORM
return this.visibleRecords.filter((record) => record.selected);
},
selectedPendingRecords() {
return this.selectedRecords.filter(
(record) => record.status === "Edited"
);
},
selectedNonPendingRecords() {
return this.selectedRecords.filter(
(record) => record.status !== "Edited"
);
},
isAnyPendingStatusRecord() {
return this.selectedPendingRecords.length;
},
allowClearOrReset() {
return (
(this.datasetTask === "TextClassification" && this.isMultiLabel) ||
this.datasetTask === "TokenClassification"
);
},
selectedRecordsIds() {
return new Set(
this.selectedRecords.reduce((acc, curr) => [...acc, curr.id], [])
);
},
message() {
let pendingSentence = "";
let nonPendingSentence = "";
const dynamicText = (number, text) => {
return `${number} record${number === 1 ? ` is` : `s are`} ${text}`;
};
if (this.isAnyPendingStatusRecord) {
pendingSentence = `${dynamicText(
this.selectedPendingRecords.length,
"pending validation"
)}`;
}
if (this.selectedNonPendingRecords.length) {
nonPendingSentence = `${dynamicText(
this.selectedRecords.length,
"selected"
)}`;
}
return `${nonPendingSentence} ${
nonPendingSentence && pendingSentence && "and "
} ${pendingSentence}`;
},
},
watch: {
visibleRecords(newValue) {
Expand Down Expand Up @@ -152,6 +215,9 @@ export default {
onClear() {
this.$emit("clear-records", this.selectedRecords);
},
onReset() {
this.$emit("reset-records", this.selectedRecords);
},
async onValidate() {
this.$emit("validate-records", this.selectedRecords);
},
Expand Down Expand Up @@ -191,7 +257,7 @@ export default {
<style lang="scss" scoped>
.validate-discard-actions {
display: flex;
gap: $base-space;
gap: calc($base-space / 2);
align-items: center;
width: 100%;
.re-checkbox {
Expand Down Expand Up @@ -228,10 +294,12 @@ export default {
@include font-size(13px);
margin: 0 $base-space;
color: $black-54;
span {
font-weight: 700;
color: $black-54;
}
}
&__text_pending_record {
padding-block: 0.5em;
padding-inline: 1em;
background-color: rgb(255, 103, 95, 0.2);
border-radius: 5px;
}
&__button {
.svg-icon {
Expand All @@ -245,12 +313,5 @@ export default {
@extend %has-tooltip--top;
}
}
&--disabled {
.validate-discard-actions__button,
.validate-discard-actions__select {
pointer-events: none;
opacity: 0.3;
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ form {
position: relative;
cursor: pointer;
background: #f0f0fe;
border-radius: 8px;
border-radius: 25px;
color: #4c4ea3;
padding: calc($base-space / 2) $base-space * 3.5 calc($base-space / 2)
$base-space;
Expand Down
Loading

0 comments on commit 00e0efc

Please sign in to comment.