44-->
55<template >
66 <div class =" cell-stars" :style =" { opacity: !canEditCell() ? 0.6 : 1 }" >
7- <div v-if =" !isEditing" @click =" startEditing" >
8- <div class =" stars-display" >
9- {{ getValue }}
10- </div >
11- </div >
12- <div v-else
13- ref =" editingContainer"
14- class =" inline-editing-container"
15- tabindex =" 0"
16- @keydown.enter =" saveChanges"
17- @keydown.escape =" cancelEdit" >
18- <div class =" align-center" :class =" { 'is-loading': localLoading }" >
19- <div class =" clickable-stars" >
20- <span v-for =" star in 5"
21- :key =" star"
22- class =" star"
23- :class =" { 'filled': star <= editValue, 'clickable': !localLoading && canEditCell() }"
24- :aria-label =" t('tables', 'Set {star} stars', { star })"
25- @click =" setStar(star)" >
26- {{ star <= editValue ? '★' : '☆' }}
27- </span >
28- </div >
29- <div v-if =" localLoading" class =" icon-loading-small icon-loading-inline" />
7+ <div class =" inline-editing-container" >
8+ <div class =" interactive-stars"
9+ @mouseleave =" hoverValue = null" >
10+ <span v-for =" star in 5"
11+ :key =" star"
12+ class =" star"
13+ :class =" {
14+ 'filled': star <= (hoverValue !== null ? hoverValue : editValue),
15+ 'clickable': !localLoading && canEditCell(),
16+ 'hovering': hoverValue !== null
17+ }"
18+ :aria-label =" t('tables', 'Set {star} stars', { star })"
19+ @mouseenter =" hoverValue = star"
20+ @click =" setStar(star)" >
21+ {{ star <= (hoverValue !== null ? hoverValue : editValue) ? '★' : '☆' }}
22+ </span >
3023 </div >
24+ <div v-if =" localLoading" class =" icon-loading-small icon-loading-inline" />
3125 </div >
3226 </div >
3327</template >
3428
3529<script >
36- import cellEditMixin from ' ../mixins/cellEditMixin.js'
3730import { translate as t } from ' @nextcloud/l10n'
31+ import cellEditMixin from ' ../mixins/cellEditMixin.js'
3832
3933export default {
4034 name: ' TableCellStars' ,
4135
4236 mixins: [cellEditMixin],
4337
4438 props: {
45- column: {
46- type: Object ,
47- default : () => {},
48- },
49- rowId: {
50- type: Number ,
51- default: null ,
52- },
5339 value: {
5440 type: Number ,
5541 default: 0 ,
5642 },
5743 },
5844
59- computed: {
60- getValue () {
61- const starEmpty = ' ☆'
62- const starFull = ' ★'
63- const v = this .value
64- return starFull .repeat (v) + starEmpty .repeat (5 - v)
65- },
45+ data () {
46+ return {
47+ hoverValue: null ,
48+ editValue: this .value ,
49+ }
6650 },
6751
6852 watch: {
69- isEditing (newValue ) {
70- if (newValue) {
71- this .$nextTick (() => {
72- document .addEventListener (' click' , this .handleClickOutside )
73- })
74- } else {
75- document .removeEventListener (' click' , this .handleClickOutside )
76- }
53+ value (newValue ) {
54+ this .editValue = newValue
7755 },
7856 },
7957
@@ -83,11 +61,14 @@ export default {
8361 setStar (starNumber ) {
8462 if (! this .localLoading && this .canEditCell ()) {
8563 // If clicking on a star that represents the current rating, clear to 0
86- if (starNumber === this .editValue ) {
64+ if (starNumber === this .value ) {
8765 this .editValue = 0
8866 } else {
8967 this .editValue = starNumber
9068 }
69+
70+ this .hoverValue = null
71+ this .saveChanges ()
9172 }
9273 },
9374
@@ -97,25 +78,16 @@ export default {
9778 }
9879
9980 if (this .editValue === this .value ) {
100- this .isEditing = false
10181 return
10282 }
10383
10484 const success = await this .updateCellValue (this .editValue )
10585
10686 if (! success) {
107- this .cancelEdit ()
87+ this .editValue = this . value
10888 }
10989
11090 this .localLoading = false
111- this .isEditing = false
112- },
113-
114- handleClickOutside (event ) {
115- // Check if the click is outside the editing container
116- if (this .$refs .editingContainer && ! this .$refs .editingContainer .contains (event .target )) {
117- this .saveChanges ()
118- }
11991 },
12092 },
12193}
@@ -126,45 +98,35 @@ export default {
12698 width : 100% ;
12799}
128100
129- .cell-stars > div :first-child {
130- cursor : pointer ;
131- }
132-
133- .stars-display {
134- font-size : 20px ;
135- cursor : pointer ;
136- }
137-
138- .align-center {
139- align-items : center ;
101+ .inline-editing-container {
140102 display : flex ;
141-
142- & .is-loading {
143- opacity : 0.7 ;
144- }
103+ align-items : center ;
145104}
146105
147- .clickable -stars {
106+ .interactive -stars {
148107 display : flex ;
149108 align-items : center ;
150- gap : 2 px ;
109+ gap : 0 ;
151110}
152111
153112.star {
154- font-size : 1.4em ;
155- padding : 4px ;
156- transition : transform 0.1s ease ;
113+ font-size : 20px ;
114+ color : var (--color-main-text );
115+ padding : 0 ;
116+ transition : color 0.1s ease ;
157117
158118 & .clickable {
159119 cursor : pointer ;
160-
161- & :hover {
162- transform : scale (1.1 );
163- }
164120 }
165121
166122 & .filled {
167- color : var (--color-warning );
123+ color : var (--color-main-text );
124+ }
125+
126+ & .hovering {
127+ & .filled {
128+ color : var (--color-text-maxcontrast );
129+ }
168130 }
169131}
170132
0 commit comments