Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Feat : single choice component #3016

Merged
merged 93 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from 91 commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
26b8504
feat(Client): remove on mouseleave event
Jan 30, 2023
a5b48d9
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Jan 31, 2023
bdc3cb9
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Jan 31, 2023
e79eb6e
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Feb 1, 2023
6905376
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Feb 7, 2023
6a102ae
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Feb 14, 2023
e1b844c
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Feb 15, 2023
792fa5e
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Feb 21, 2023
1513d63
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Feb 21, 2023
90e98e0
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Feb 23, 2023
75366b6
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Feb 24, 2023
c117b3d
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 1, 2023
da4026c
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 14, 2023
0c5eef9
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 16, 2023
2a0ff8e
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 21, 2023
b2e20bb
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 21, 2023
b47793e
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 21, 2023
ca314e2
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 22, 2023
5e905f6
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 27, 2023
dc0f4d0
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 28, 2023
b062d10
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 29, 2023
84b383e
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 29, 2023
f7ab48e
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Mar 30, 2023
100ec1a
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Apr 10, 2023
3803181
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
May 19, 2023
a3111fb
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
May 25, 2023
e51119b
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
May 25, 2023
9abd52f
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
May 25, 2023
e75147c
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
May 29, 2023
e84cb8f
:fire: remove props
May 26, 2023
c96e119
:recycle: refacto monoSelection
May 26, 2023
2d665e6
:recycle: refacto Rating
May 26, 2023
a13a4a9
:fire: remove props
May 26, 2023
c6b3150
:heavy_minus_sign: remove props
May 26, 2023
004fa15
:recycle: rating => prepare two bindings
May 26, 2023
92214ef
:lipstick: style monoselection component
May 26, 2023
23fd9d4
:recycle: textArea => prepare for two way bindings
May 26, 2023
4d7ce5e
:label: update props type
May 26, 2023
98bf8d0
:recycle: v-model on form obj
May 26, 2023
ca38700
:rewind: revert change on textArea
May 26, 2023
a65b319
:recycle: renaming
May 26, 2023
304f73c
:recycle: v-model in Rating
May 28, 2023
c6c01bb
:label: add type for monoSelection component to render
May 28, 2023
7d14913
:recycle: split monoSelection component in container and renderer
May 28, 2023
819fc7f
:recycle: update with component type to render
May 28, 2023
b6ae9d8
:recycle: component name match file name
May 29, 2023
732ac8f
:recycle: renaming enum
May 29, 2023
8741957
:recycle: encapsulate logic and style in RatingMonoSelectionComponent
May 29, 2023
efdff65
:fire: remove properties and monoselection components
May 29, 2023
54ee875
:label: update props
May 29, 2023
9c306a6
:coffin: remove obsolete properties
May 29, 2023
1b1f958
:recycle: adapt change to singleLabel and corresponding monoSelection
May 29, 2023
c38f950
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
May 29, 2023
f59e87b
Merge branch 'develop' into front-single-label-component
May 29, 2023
d8e929c
:label: add props
May 29, 2023
b22e6c2
:sparkles: single-label with monoselection
May 29, 2023
53b16aa
:sparkles: mono selection for single label
May 29, 2023
f862313
:sparkles: condition to show the expand button
May 30, 2023
442f5b3
:dizzy: shuffle transition animation
May 30, 2023
0806cb2
:lipstick: button style
May 30, 2023
f05c7ad
:lipstick: css single-label monoselection
May 30, 2023
027d5c0
:recycle: externalized search component
May 30, 2023
6038d3b
:recycle: refacto to call externalized component
May 30, 2023
8c4937d
:sparkles: two-way binding with props
May 31, 2023
e638433
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
May 31, 2023
396ae3c
:iphone: flex-wrap on responses
May 31, 2023
96e720a
:recycle: use two-way binding on text-area
May 31, 2023
691bd5a
:label: backend label change => single_label -> label_selection
May 31, 2023
f30c485
:boom: use `value_in_api` attribute to dissociate value in front and …
May 31, 2023
71df09f
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
May 31, 2023
79dfa70
Merge branch 'develop' into front-update-to-prepare-single-label
May 31, 2023
6bcfe2b
:fire: use `value` and `is_selected` instead of `value_in_api`
May 31, 2023
0d80798
:coffin: remove dead code
May 31, 2023
9b0a907
Merge branch 'front-update-to-prepare-single-label' into front-single…
May 31, 2023
250a28e
:coffin: remove dead code
Jun 1, 2023
a82b456
Merge branch 'front-update-to-prepare-single-label' into front-single…
Jun 1, 2023
d3b77d8
:recycle: two way biding for SingleLabel component
Jun 1, 2023
b5dcd6d
:bug: search case insensitive && switch flag from value to is_selected
Jun 1, 2023
144a1c0
:recycle: compute default attribute for form in parent component
Jun 1, 2023
89334a9
:recycle: renaming && ensure we have unique options
Jun 1, 2023
fb222e1
:recycle: renaming
Jun 1, 2023
7e3702a
:label: add settings attribute to model
Jun 1, 2023
f825e8c
:sparkles: add `dataset_settings` in orm
Jun 1, 2023
44b1570
:recycle: refacto collapse behaviour && renaming
Jun 1, 2023
2ef21a6
:sparkles: default value if no settings `visible_options`
Jun 1, 2023
09c5762
:sparkles: pass props `visible_options` && prepare code for multi_label
Jun 1, 2023
5549c5f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 1, 2023
70b87f0
Merge branch 'develop' of https://github.com/recognai/rubrix into dev…
Jun 1, 2023
36a4f93
Merge branch 'develop' into front-single-label-component
Jun 1, 2023
b93ee95
Merge branch 'front-single-label-component' of https://github.com/rec…
Jun 1, 2023
cd572d5
:bulb: comment for `multi_label` implementation
Jun 1, 2023
4b1b292
:art: format code
Jun 1, 2023
e44b2c9
:bulb: remove comment
Jun 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
@on-error="onError"
/>

<!--TODO - pass visibleOption as props from settings-->
keithCuniah marked this conversation as resolved.
Show resolved Hide resolved
<SingleLabelComponent
v-if="input.component_type === COMPONENT_TYPE.SINGLE_LABEL"
:questionId="input.id"
:title="input.question"
:options="input.options"
v-model="input.options"
:isRequired="input.is_required"
:tooltipMessage="input.description"
@on-change-single-label="
onChangeMonoSelection({ newOptions: $event, idComponent: input.id })
"
:visibleOptions="input.settings.visible_options"
@on-error="onError"
/>

Expand Down Expand Up @@ -240,11 +240,7 @@ export default {
default:
}
},
onChangeMonoSelection({ newOptions, idComponent }) {
// TODO - to remove when single label will use v-model
const component = this.inputs.find(({ id }) => id === idComponent);
component.options = newOptions;
},

async sendBackendRequest(responseValues) {
try {
let responseData = null;
Expand Down Expand Up @@ -534,6 +530,18 @@ export default {
this.inputs.forEach((input) => {
let selectedOption = null;
switch (input.component_type) {
// case COMPONENT_TYPE.MULTI_LABEL:
//TODO - place the code after the switch inside RATING and FREE_TEXT cases
// const selectedOptions = input.options?.filter(
// (option) => option.is_selected
// );

// if (selectedOptions?.length) {
// responseByQuestionName[input.name] = {
// value: selectedOptions.map((option) => option.value),
// };
// }
// break;
case COMPONENT_TYPE.SINGLE_LABEL:
case COMPONENT_TYPE.RATING:
selectedOption = input.options?.find(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,24 @@
/>
</div>

<SingleLabelMonoSelectionComponent v-model="options" />
<SingleLabelMonoSelectionComponent
:options="uniqueOptions"
:componentId="questionId"
:showSearch="showSearch"
:maxOptionsToShowBeforeCollapse="maxOptionsToShowBeforeCollapse"
@change="$emit('update:options', options)"
/>
</div>
</template>

<script>
import SingleLabelMonoSelectionComponent from "./SingleLabelMonoSelection.component.vue";
export default {
components: { SingleLabelMonoSelectionComponent },
name: "SingleLabelComponent",
props: {
questionId: {
type: String,
required: true,
},
title: {
type: String,
required: true,
Expand All @@ -43,19 +51,33 @@ export default {
type: String,
default: () => "",
},
visibleOptions: {
type: Number | null,
required: false,
},
},
methods: {
onChangeSingleLabel(newOptions) {
this.$emit("on-change-single-label", newOptions);
const isAnySingleLabelSelected =
this.isAnySingleLabelSelected(newOptions);

if (this.isRequired) {
this.$emit("on-error", !isAnySingleLabelSelected);
model: {
prop: "options",
},
data() {
return {
uniqueOptions: [],
};
},
beforeMount() {
this.uniqueOptions = this.options.reduce((accumulator, current) => {
if (!accumulator.find((item) => item.id === current.id)) {
accumulator.push(current);
}
return accumulator;
}, []);
},
computed: {
showSearch() {
return this.uniqueOptions.length >= 12;
},
isAnySingleLabelSelected(options) {
return options.some((option) => option.value);
maxOptionsToShowBeforeCollapse() {
return this.visibleOptions ?? -1;
},
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,68 +1,182 @@
<template>
<div class="container">
<div class="inputs-area">
<div class="input-button" v-for="option in options" :key="option.id">
<div class="component-header" v-if="showSearch || showCollapseButton">
<div class="left-header">
<SearchSingleLabelComponent
v-if="showSearch"
v-model="searchInput"
:searchRef="searchRef"
:placeholder="placeholder"
/>
</div>

<div class="right-header">
<button
type="button"
class="show-less-button cursor-pointer"
v-if="showCollapseButton"
v-text="textToShowInTheCollapseButton"
@click="toggleShowLess"
/>
</div>
</div>
<transition-group
name="shuffle"
class="inputs-area"
v-if="filteredOptions.length"
>
<div
class="input-button"
v-for="option in visibleOptions"
:key="option.id"
>
<input
type="checkbox"
:name="option.text"
:id="option.id"
v-model="option.value"
v-model="option.is_selected"
@change="onSelect(option)"
/>
<label
class="label-text cursor-pointer"
:class="{ 'label-active': option.value }"
:class="{ 'label-active': option.is_selected }"
:for="option.id"
v-text="option.text"
/>
</div>
</div>
</transition-group>
<i
class="no-result"
v-if="!filteredOptions.length"
v-text="noResultMessage"
/>
</div>
</template>

<script>
export default {
name: "SingleLabelMonoSelectionComponent",
props: {
maxOptionsToShowBeforeCollapse: {
type: Number,
default: () => -1,
},
options: {
type: Array,
required: true,
},
placeholder: {
type: String,
default: () => "Search labels",
},
componentId: {
type: String,
required: true,
},
showSearch: {
type: Boolean,
default: () => false,
},
},
model: {
prop: "options",
event: "on-change",
},
data() {
return {
searchInput: "",
showLess: false,
};
},
created() {
this.searchRef = `${this.componentId}SearchFilterRef`;
},
computed: {
filteredOptions() {
return this.options.filter((option) =>
String(option.text)
.toLowerCase()
.includes(this.searchInput.toLowerCase())
);
},
visibleOptions() {
if (!this.showCollapseButton || this.showLess)
return this.filteredOptions;

return this.filteredOptions.slice(
0,
this.maxOptionsToShowBeforeCollapse + 1
);
},
noResultMessage() {
return `There is no result matching: ${this.searchInput}`;
},
numberToShowInTheCollapseButton() {
return this.filteredOptions.length - this.maxOptionsToShowBeforeCollapse;
},
showCollapseButton() {
if (this.maxOptionsToShowBeforeCollapse === -1) return false;
if (this.numberToShowInTheCollapseButton < 0) return false;
return this.options.length > this.maxOptionsToShowBeforeCollapse;
},
textToShowInTheCollapseButton() {
if (this.showLess) {
return "Show less";
}
return `+${this.numberToShowInTheCollapseButton}`;
},
},
methods: {
onSelect({ id, value }) {
onSelect({ id, is_selected }) {
this.options.map((option) => {
if (option.id === id) {
option.value = value;
option.is_selected = is_selected;
} else {
option.value = false;
option.is_selected = false;
}
return option;
});

this.$emit("on-change", this.options);
},
toggleShowLess() {
this.showLess = !this.showLess;
},
},
};
</script>

<style lang="scss" scoped>
.container {
display: flex;
flex-direction: column;
gap: $base-space * 2;
.component-header {
display: grid;
grid-template-columns: 1fr auto;
}
.inputs-area {
display: inline-flex;
gap: $base-space;
flex-wrap: wrap;
border-radius: 5em;
background: transparent;
&:hover {
border-color: darken(palette(purple, 800), 12%);
}
}
}

.show-less-button {
background: none;
border: none;
color: rgba(0, 0, 0, 0.6);
text-decoration: none;
&:hover {
color: rgba(0, 0, 0, 0.87);
}
}

.label-text {
display: flex;
width: 100%;
Expand All @@ -82,7 +196,7 @@ export default {
background: darken(palette(purple, 800), 8%);
}
}
input {
input[type="checkbox"] {
display: none;
}
.label-active {
Expand All @@ -92,4 +206,17 @@ input {
.cursor-pointer {
cursor: pointer;
}

.shuffle-move {
transition: transform 0.5s;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}

.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>
Loading