Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
GuiΩ
ActivitesMentales_Django
Commits
c29db654
Commit
c29db654
authored
Jun 21, 2022
by
GuiΩ
Browse files
feat(seances): context menu: delete selected seances
parent
982e7ee8
Changes
7
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/FeuilleList.vue
View file @
c29db654
...
...
@@ -108,16 +108,16 @@ Events:
<
style
lang=
"sass"
>
.FeuilleList
vertical-align
:
top
overflow-y
:
scroll
display
:
flex
flex-direction
:
column
height
:
calc
(
100%
-
4px
)
border
:
solid
2px
lightGray
overflow
:
scroll
scroll-behavior
:
smooth
text-align
:
center
/* width: 1200px; */
//align-content: flex-start
min-height
:
100px
/* height: 600px; */
margin
:
0
padding
:
0
list-style
:
none
background-color
:
#ffdffb
.FeuilleList_newFeuilleBtn
...
...
frontend/src/components/FeuilleListFeuille.vue
View file @
c29db654
...
...
@@ -99,7 +99,7 @@ Events:
@seance-changed="$emit('seance-changed', $event)"
@show-question-tooltip="$emit('show-question-tooltip', $event)"
@show-context-menu="$emit('show-context-menu', $event)")/
button.Feuille_
newFeuill
eBtn(
button.Feuille_
addSeanc
eBtn(
type="button"
@click="addSeance({feuille: props.feuilleId})"
) Ajouter une séance
...
...
@@ -107,14 +107,17 @@ Events:
<
style
>
.Feuille
{
min-width
:
1062px
;
border-bottom
:
solid
2px
dimgray
;
display
:
flex
;
flex-direction
:
column
;
border-bottom
:
solid
3px
black
;
padding
:
0
;
margin
:
0
;
}
.FeuilleHeader
{
display
:
block
;
/*display: block;*/
align-self
:
center
;
flex
:
0
0
auto
;
font-size
:
24px
;
margin
:
10px
;
}
...
...
@@ -130,8 +133,10 @@ Events:
}
.Feuille_newFeuilleBtn
{
.Feuille_addSeanceBtn
{
align-self
:
center
;
margin
:
20px
;
max-width
:
fit-content
;
}
</
style
>
\ No newline at end of file
frontend/src/components/FeuilleListFeuilleSeance.vue
View file @
c29db654
...
...
@@ -77,6 +77,16 @@ Events:
return
true
})
const
selectionIsDeletable
=
computed
(()
=>
{
for
(
const
seanceId
of
props
.
selection
.
seances
)
{
const
seance
=
feuilles
.
getSeance
(
seanceId
)
for
(
const
questionPosee
of
seance
?.
questionsPosees
!
)
if
(
questionPosee
.
score
!==
null
)
return
false
}
return
true
})
const
isSelected
=
computed
(()
=>
props
.
selection
.
seances
.
indexOf
(
props
.
seanceId
)
>-
1
)
const
seance
=
computed
(()
=>
feuilles
.
getSeance
(
props
.
seanceId
))
...
...
@@ -198,6 +208,9 @@ Events:
emit
(
'
show-context-menu
'
,
{
event
:
event
,
options
:[
{
name
:
'
Copier
'
+
(
multipleSel
?
'
les seances
'
:
'
la seance
'
)
,
callback
:
()
=>
emit
(
'
copy
'
,
event
)
},
{
name
:
'
Supprimer
'
+
(
multipleSel
?
'
les seances
'
:
'
la seance
'
),
disabled
:
!
selectionIsDeletable
,
callback
:
()
=>
undoables
.
deleteSeances
(
props
.
selection
.
seances
)},
{
name
:
'
Insérer
'
+
(
multipleClip
?
'
les seances
'
:
'
la seance
'
)
+
'
avant
'
,
disabled
:
props
.
clipboard
.
seances
.
length
<
1
,
callback
:
()
=>
pasteSeance
(
seance
.
value
?.
position
!
)},
...
...
@@ -207,6 +220,7 @@ Events:
{
name
:
'
Annuler
'
}]})
}
function
pasteSeance
(
position
:
number
)
{
const
seances
:
Partial
<
ISeanceR
>
[]
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
clipboard
.
seances
))
for
(
const
s
of
seances
)
{
...
...
@@ -234,9 +248,12 @@ Events:
:data-testid="'seance_' + props.seanceId"
v-if="seance"
@click="onClick")
.Seance_body(
:class="{selected: isSelected}")
| Seance
{{
seance
.
position
}}
.Seance_header Seance
{{
seance
.
position
}}
|
span.Seance_deleteBtn(
:disabled="! isDeletable"
@click="undoables.deleteSeance(seance)") 🗙
.Seance_body(:class="{selected: isSelected}")
FeuilleListFeuilleSeanceSlot(
v-for="position in 5"
:key="'slot' + props.seanceId + '_' + position"
...
...
@@ -254,7 +271,7 @@ Events:
@question-drop="$emit('question-drop', $event)"
@show-question-tooltip="$emit('show-question-tooltip', $event)"
@show-context-menu="$emit('show-context-menu', $event)")/
.
tools
.
Seance_footer
button(v-if="! state.scoresEditing" @click="showEvaluate") Saisir les notes
button.valider(v-if="state.scoresEditing" :ref="(el) => btnScoreSave=el" @click="save") Valider
br
...
...
@@ -296,44 +313,69 @@ Events:
a(v-if="isDeletable" @click="undoables.deleteSeance(seance)") Supprimer la séance
</
template
>
<
style
>
.Seance
{
display
:
table-row
;
margin
:
0
;
padding
:
0
;
text-align
:
left
;
vertical-align
:
middle
;
}
.Seance_body.selected
{
background
:
rgba
(
1
,
0
,
0
,
.05
);
border
:
solid
red
1px
;
}
.Seance_date
{
position
:
relative
;
top
:
50%
;
cursor
:
pointer
;
}
.seance
>
div
{
display
:
inline-block
;
vertical-align
:
top
;
margin
:
0
;
<
style
lang=
"sass"
>
.Seance
display
:
flex
justify-content
:
flex-start
text-align
:
left
margin-left
:
10px
padding
:
0
}
padding-bottom
:
5px
.Seance_header
height
:
min-content
margin-left
:
-60px
font-size
:
90%
//border: solid 1px
transform-origin
:
top
right
transform
:
translate
(
-27px
,
10px
)
rotate
(
-90deg
)
.Seance_deleteBtn
font-size
:
140%
color
:
red
cursor
:
pointer
&
.disabled
color
:
gray
cursor
:
default
.Seance_body
flex
:
0
0
auto
display
:
flex
&
.selected
background
:
rgba
(
1
,
0
,
0
,.
05
)
border
:
solid
red
1px
&
.questionSlot
flex
:
0
0
auto
.Seance_date
position
:
relative
top
:
50%
cursor
:
pointer
//
//.seance > div
// display: inline-block
// vertical-align: top
// margin: 0
// padding: 0
.Seance_footer
display
:
flex
flex-direction
:
column
min-width
:
150px
.tools
.button
//display: inline-block
//margin: auto
.tools
{
display
:
inline-block
;
}
.tools
.button
{
display
:
inline-block
;
margin
:
auto
;
}
a
cursor
:
pointer
a
{
cursor
:
pointer
;
}
</
style
>
\ No newline at end of file
frontend/src/components/FeuilleListFeuilleSeanceSlot.vue
View file @
c29db654
...
...
@@ -211,7 +211,7 @@ Events:
</
script
>
<
template
lang=
"pug"
>
.
q
uestionSlot(
.
Q
uestionSlot(
ref="root"
:data-testid="'slot_' + props.seanceId + '_' + position"
@drop.prevent.stop="onDrop"
...
...
@@ -220,14 +220,14 @@ Events:
@dragenter.prevent
@contextmenu.prevent
)
.questionPosee(
.
QuestionSlot_
questionPosee(
v-if="questionPosee"
@contextmenu.prevent="onContextMenu")
Score(:score="questionPosee.score")
.saise(v-if="scoreEditing")
input(ref="input" v-model.number.trim="newScore" size="2" @change="onInput($event)" @input="onInput($event)")
| /
{{
bareme
}}
.question(
.
QuestionSlot_
question(
v-if="question"
@click="onClick"
@dblclick="onDblClick"
...
...
@@ -237,64 +237,58 @@ Events:
:alt="'question ' + questionPosee.question"
:src="'/static/thumbs/' + question.thumb_name"
@load="$emit('loaded', props.questionId)")
div.
question
_v
ide(v-else) Question
{{
questionPosee
.
question
}}
.QuestionSlot_
question
V
ide(v-else) Question
{{
questionPosee
.
question
}}
</
template
>
<
style
scoped
>
.questionSlot
{
display
:
table-cell
;
vertical-align
:
top
;
width
:
211px
;
height
:
50px
;
border
:
solid
1px
gray
;
}
<
style
lang=
"sass"
>
.QuestionSlot
width
:
211px
min-height
:
50px
border
:
solid
1px
gray
.QuestionSlot_questionPosee
text-align
:
center
.questionPosee
{
text-align
:
center
;
}
/* Affichage du score : */
/* si non évalué : gris */
.score
{
display
:
block
;
max-height
:
5px
;
width
:
60%
;
height
:
3px
;
background
:
lightgray
;
border
:
1px
solid
gray
;
margin
:
auto
;
margin-top
:
4px
;
}
/* si évalué : fond rouge */
.score.evaluee
{
background
:
red
;
}
.score
display
:
block
max-height
:
5px
width
:
60%
height
:
3px
background
:
lightgray
border
:
1px
solid
gray
margin
:
auto
margin-top
:
4px
.evaluee
background
:
red
/* et score en vert */
.scorevalue
{
height
:
100%
;
background
:
greenyellow
;
}
.
q
uestion
_v
ide
{
display
:
block
;
text-align
:
center
;
width
:
209px
;
height
:
60px
;
.scorevalue
height
:
100%
background
:
greenyellow
.
Q
uestion
Slot_questionV
ide
display
:
block
text-align
:
center
width
:
209px
height
:
60px
/*padding-top: 20px;*/
border
:
1px
solid
black
;
border
:
1px
solid
black
/*noinspection CssUnknownTarget*/
background
:
white
center
no-repeat
url("/static/src/assets/loading.gif")
;
}
background
:
white
center
no-repeat
url("/static/src/assets/loading.gif")
.saisie
input
{
max-width
:
20px
;
margin
:
auto
;
}
.saisie
input
max-width
:
20px
margin
:
auto
img
background
:
rgba
(
255
,
255
,
255
,
.7
)
img
{
background
:
rgba
(
255
,
255
,
255
,
.7
);
}
</
style
>
\ No newline at end of file
frontend/src/components/MainPage.vue
View file @
c29db654
...
...
@@ -289,12 +289,6 @@ body {
.FeuilleList
{
flex
:
10
10
auto
;
display
:
flex
;
flex-direction
:
column
;
overflow
:
auto
;
height
:
calc
(
100%
-
4px
);
padding
:
10px
;
border
:
solid
2px
lightGray
;
}
</
style
>
\ No newline at end of file
frontend/src/store/undoableActions.ts
View file @
c29db654
...
...
@@ -254,6 +254,19 @@ export class SeanceDelActionR extends _SeanceAddDelActionR {
}
}
export
class
SeancesDelActionR
extends
MultipleAction
{
constructor
(
seances
:
ISeanceR
[],
redoMsg
?:
string
,
undoMsg
?:
string
)
{
const
actions
=
[]
for
(
const
seance
of
seances
)
actions
.
push
(
new
SeanceDelActionR
(
seance
))
if
(
redoMsg
===
undefined
)
redoMsg
=
'
Supprimer les séances
'
if
(
undoMsg
===
undefined
)
undoMsg
=
'
Restaurer les séances
'
super
(
redoMsg
,
undoMsg
,
actions
);
}
}
/* **********************
* Feuilles *
************************/
...
...
frontend/src/store/undoables.ts
View file @
c29db654
import
{
defineStore
}
from
'
pinia
'
import
type
{
ClasseID
,
FeuilleID
,
IFeuille
,
IQuestionPosee
,
ISeanceR
,
IUndoable
,
QuestionID
}
from
"
@/types
"
;
import
type
{
ClasseID
,
FeuilleID
,
IFeuille
,
IQuestionPosee
,
ISeanceR
,
IUndoable
,
QuestionID
,
SeanceID
}
from
"
@/types
"
;
import
{
useClassesStore
}
from
"
@/store/classes
"
;
import
{
FeuilleAddDelActionR
,
...
...
@@ -7,8 +7,9 @@ import {
QuestionPoseeAddDelAction
,
QuestionPoseePatchAction
,
SeanceAddActionR
,
SeanceDelActionR
,
SeancesAddActionR
SeanceDelActionR
,
SeancesAddActionR
,
SeancesDelActionR
}
from
"
@/store/undoableActions
"
;
import
{
useFeuillesStore
}
from
"
@/store/feuilles
"
;
export
const
QUESTION_SAVE_INIT
=
'
INIT_QUESTION_SAVE
'
...
...
@@ -167,6 +168,17 @@ export const useUndoablesStore = defineStore( 'undoablesStore',{
return
this
.
redo
()
},
deleteSeances
(
seancesId
:
SeanceID
[])
{
const
feuilles
=
useFeuillesStore
()
console
.
debug
(
'
undoables.deleteSeances
'
,
seancesId
)
const
seances
=
[]
for
(
const
seanceId
of
seancesId
)
seances
.
push
(
feuilles
.
getSeance
(
seanceId
)
!
)
this
.
queuePush
(
new
SeancesDelActionR
(
seances
))
return
this
.
redo
()
},
/* ********************
* QuestionPosees
**********************/
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment