Skip to content

Commit 42c4958

Browse files
Merge pull request #2018 from NicoPennec/fixes
Various fixes
2 parents 08e8acc + 4553d5c commit 42c4958

17 files changed

Lines changed: 860 additions & 1930 deletions

package-lock.json

Lines changed: 646 additions & 1140 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
"@fullcalendar/multimonth": "6.1.20",
2828
"@fullcalendar/vue3": "6.1.20",
2929
"@google/model-viewer": "4.2.0",
30-
"@sentry/vue": "10.53.1",
31-
"@unhead/vue": "3.1.0",
30+
"@sentry/vue": "10.54.0",
31+
"@unhead/vue": "3.1.1",
3232
"@vuepic/vue-datepicker": "11.0.3",
3333
"bowser": "2.14.1",
3434
"bulma": "0.3.1",
@@ -43,14 +43,14 @@
4343
"fabricjs-psbrush": "cgwire/fabricjs-psbrush",
4444
"file-saver": "2.0.5",
4545
"lucide-vue-next": "0.577.0",
46-
"marked": "18.0.3",
46+
"marked": "18.0.4",
4747
"marked-emoji": "2.0.3",
4848
"moment": "2.30.1",
4949
"moment-timezone": "0.6.2",
5050
"panzoom": "9.4.4",
5151
"papaparse": "5.5.3",
5252
"qrcode.vue": "3.9.1",
53-
"sanitize-html": "2.17.3",
53+
"sanitize-html": "2.17.4",
5454
"socket.io-client": "4.8.3",
5555
"superagent": "10.3.0",
5656
"thenby": "1.3.4",
@@ -73,24 +73,24 @@
7373
},
7474
"devDependencies": {
7575
"@eslint/js": "10.0.1",
76-
"@vitejs/plugin-vue": "6.0.6",
76+
"@vitejs/plugin-vue": "6.0.7",
7777
"@vue/compiler-sfc": "3.5.13",
7878
"@vue/test-utils": "2.4.10",
7979
"autoprefixer": "10.5.0",
80-
"eslint": "10.3.0",
80+
"eslint": "10.4.0",
8181
"eslint-config-prettier": "10.1.8",
8282
"eslint-plugin-prettier": "5.5.5",
8383
"eslint-plugin-promise": "7.3.0",
8484
"eslint-plugin-vue": "10.9.1",
8585
"globals": "17.6.0",
8686
"husky": "9.1.7",
8787
"jsdom": "29.1.1",
88-
"lint-staged": "17.0.4",
88+
"lint-staged": "17.0.5",
8989
"localStorage": "1.0.4",
9090
"prettier": "3.8.3",
91-
"sass": "1.99.0",
92-
"vite": "8.0.12",
93-
"vitest": "4.1.6",
91+
"sass": "1.100.0",
92+
"vite": "8.0.14",
93+
"vitest": "4.1.7",
9494
"vitest-localstorage-mock": "0.1.2",
9595
"vue-eslint-parser": "10.4.0"
9696
},

src/components/lists/TimesheetList.vue

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
</div>
3333

3434
<div class="datatable-wrapper" ref="body" @scroll.passive="onBodyScroll">
35-
<table class="datatable multi-section">
35+
<table class="datatable">
3636
<thead class="datatable-head">
3737
<tr>
3838
<th
@@ -438,15 +438,26 @@ export default {
438438
</script>
439439
440440
<style lang="scss" scoped>
441-
.datatable-row-header {
442-
z-index: 6; // over the .vue-slider (z-index: 5)
441+
.datatable-head .datatable-row-header {
442+
z-index: 8; // sticky <th> must be above all
443+
444+
&.time-spent {
445+
z-index: 6; // <th> must be under the sticky <th> on horizontal scroll
446+
}
447+
}
448+
449+
.datatable-body .datatable-row-header {
450+
z-index: 7; // <th> must be over the .vue-slider (z-index: 5) and .vue-slider-dot (z-index: 6)
443451
444452
&.time-spent {
445-
position: relative;
446453
z-index: 5; // <th> must be under <td> on vertical scroll
447454
}
448455
}
449456
457+
:deep(.vue-slider-dot:hover) {
458+
z-index: 6; // hack to put slider tooltip hover the header
459+
}
460+
450461
.datatable-body tr:first-child th,
451462
.datatable-body tr:first-child td {
452463
border-top: 0;

src/components/mixins/entities.js

Lines changed: 112 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { mapGetters, mapActions } from 'vuex'
22

3-
import stringHelpers from '@/lib/string'
43
import func from '@/lib/func'
54
import preferences from '@/lib/preferences'
5+
import stringHelpers from '@/lib/string'
66

77
/*
8-
* Common functions to shots and assets pages.
8+
* Common functions to entity pages (assets, shots, sequences, edits, episodes).
99
*/
1010
export const entitiesMixin = {
1111
data() {
@@ -25,7 +25,7 @@ export const entitiesMixin = {
2525
`${this.pageName}:department`
2626
)
2727
const selectableDepartments = this.selectableDepartments(
28-
stringHelpers.capitalize(this.type)
28+
this.entityTypeName
2929
).map(department => department.id)
3030

3131
if (
@@ -82,12 +82,28 @@ export const entitiesMixin = {
8282
},
8383

8484
entityTypeName() {
85-
return `${this.type[0].toUpperCase()}${this.type.slice(1)}`
85+
return stringHelpers.capitalize(this.type)
8686
},
8787

8888
selectedEntities() {
89-
if (['Episode', 'Sequence'].includes(this.entityTypeName)) return []
89+
if (['Episode', 'Sequence'].includes(this.entityTypeName)) {
90+
return new Map()
91+
}
9092
return this[`selected${this.entityTypeName}s`]
93+
},
94+
95+
deleteAllTasksText() {
96+
const taskType = this.taskTypeForTaskDeletion
97+
return taskType
98+
? this.$t('tasks.delete_all_text', { name: taskType.name })
99+
: ''
100+
},
101+
102+
restoreText() {
103+
const entity = this[`${this.type}ToRestore`]
104+
return entity
105+
? this.$t(`${this.type}s.restore_text`, { name: entity.name })
106+
: ''
91107
}
92108
},
93109

@@ -135,49 +151,57 @@ export const entitiesMixin = {
135151
} else {
136152
this.departmentFilter = [departmentId]
137153
}
138-
this.$store.commit('CLEAR_SELECTED_TASKS')
154+
this.clearSelectedTasks()
139155
preferences.setPreference(`${this.pageName}:department`, departmentId)
140156
},
141157

142158
selectableDepartments(forEntity) {
143159
if (!this.currentProduction) {
144160
return []
145161
}
146-
return this.currentProduction.task_types
147-
.map(taskTypeId => {
148-
const taskType = this.taskTypeMap.get(taskTypeId)
149-
return taskType && taskType.for_entity === forEntity
150-
? this.departmentMap.get(taskType.department_id)
151-
: false
152-
})
153-
.filter(
154-
(department, index, self) =>
155-
department && self.indexOf(department) === index
162+
return [
163+
...new Set(
164+
this.currentProduction.task_types
165+
.map(id => this.taskTypeMap.get(id))
166+
.filter(taskType => taskType?.for_entity === forEntity)
167+
.map(taskType => this.departmentMap.get(taskType.department_id))
168+
.filter(Boolean)
156169
)
157-
},
158-
159-
onEntityThumbnailClicked(entityId) {
160-
if (!entityId) return
161-
this.previvewFileIdToShow = entityId
162-
this.modals.isPreviewDisplayed = true
170+
]
163171
},
164172

165173
closeMetadataModal() {
166174
this.modals.isAddMetadataDisplayed = false
167175
},
168176

177+
confirmAddMetadata(form) {
178+
this.loading.addMetadata = true
179+
form.entity_type = this.entityTypeName
180+
this.addMetadataDescriptor(form)
181+
.then(() => {
182+
this.modals.isAddMetadataDisplayed = false
183+
})
184+
.catch(err => {
185+
console.error(err)
186+
this.errors.addMetadata = true
187+
})
188+
.finally(() => {
189+
this.loading.addMetadata = false
190+
})
191+
},
192+
169193
confirmDeleteMetadata() {
170194
this.errors.deleteMetadata = false
171195
this.loading.deleteMetadata = true
172196
this.deleteMetadataDescriptor(this.descriptorIdToDelete)
173197
.then(() => {
174-
this.errors.deleteMetadata = false
175-
this.loading.deleteMetadata = false
176198
this.modals.isDeleteMetadataDisplayed = false
177199
})
178200
.catch(err => {
179201
console.error(err)
180202
this.errors.deleteMetadata = true
203+
})
204+
.finally(() => {
181205
this.loading.deleteMetadata = false
182206
})
183207
},
@@ -204,16 +228,22 @@ export const entitiesMixin = {
204228
const projectId = this.currentProduction.id
205229
this.errors.deleteAllTasks = false
206230
this.loading.deleteAllTasks = true
207-
this.deleteAllTasks({ projectId, taskTypeId, selectionOnly })
231+
this[`deleteAll${this.entityTypeName}Tasks`]({
232+
projectId,
233+
taskTypeId,
234+
selectionOnly
235+
})
208236
.then(() => {
209-
this.loading.deleteAllTasks = false
237+
if (!selectionOnly) this.reset()
210238
this.modals.isDeleteAllTasksDisplayed = false
211239
})
212240
.catch(err => {
213241
console.error(err)
214-
this.loading.deleteAllTasks = false
215242
this.errors.deleteAllTasks = true
216243
})
244+
.finally(() => {
245+
this.loading.deleteAllTasks = false
246+
})
217247
},
218248

219249
confirmAddThumbnails(forms) {
@@ -225,7 +255,7 @@ export const entitiesMixin = {
225255
taskStatusId: form.task.task_status_id,
226256
form
227257
})
228-
.then(({ newComment, preview }) => {
258+
.then(({ preview }) => {
229259
return this.setPreview({
230260
taskId: form.task.id,
231261
entityId: form.task.entity_id,
@@ -270,13 +300,14 @@ export const entitiesMixin = {
270300
})
271301
},
272302

273-
deleteAllTasksText() {
274-
const taskType = this.taskTypeForTaskDeletion
275-
if (taskType) {
276-
return this.$t('tasks.delete_all_text', { name: taskType.name })
277-
} else {
278-
return ''
279-
}
303+
runTasksCreation(form, selectionOnly) {
304+
this.errors.creatingTasks = false
305+
return this.createTasks({
306+
type: `${this.type}s`,
307+
task_type_id: form.task_type_id,
308+
project_id: this.currentProduction.id,
309+
selectionOnly
310+
})
280311
},
281312

282313
onDeleteAllTasksClicked(taskTypeId) {
@@ -286,16 +317,52 @@ export const entitiesMixin = {
286317
this.modals.isDeleteAllTasksDisplayed = true
287318
},
288319

320+
onRestoreClicked(entity) {
321+
this[`${this.type}ToRestore`] = entity
322+
this.modals.isRestoreDisplayed = true
323+
},
324+
289325
saveScrollPosition(scrollPosition) {
290-
this.$store.commit('SET_EDIT_LIST_SCROLL_POSITION', scrollPosition)
326+
this.$store.commit(
327+
`SET_${this.type.toUpperCase()}_LIST_SCROLL_POSITION`,
328+
scrollPosition
329+
)
291330
},
292331

293-
onChangeSortClicked(sortInfo) {
294-
this[`change${this.type[0].toUpperCase()}${this.type.slice(1)}Sort`](
295-
sortInfo
332+
saveSearchQuery(searchQuery) {
333+
if (this.loading.savingSearch) return
334+
this.loading.savingSearch = true
335+
this[`save${this.entityTypeName}Search`](searchQuery)
336+
.catch(console.error)
337+
.finally(() => {
338+
this.loading.savingSearch = false
339+
})
340+
},
341+
342+
removeSearchQuery(searchQuery) {
343+
this[`remove${this.entityTypeName}Search`](searchQuery).catch(
344+
console.error
296345
)
297346
},
298347

348+
getPath(section) {
349+
const route = {
350+
name: section,
351+
params: {
352+
production_id: this.currentProduction.id
353+
}
354+
}
355+
if (this.isTVShow && this.currentEpisode) {
356+
route.name = `episode-${section}`
357+
route.params.episode_id = this.currentEpisode.id
358+
}
359+
return route
360+
},
361+
362+
onChangeSortClicked(sortInfo) {
363+
this[`change${this.entityTypeName}Sort`](sortInfo)
364+
},
365+
299366
onKeepTaskPanelOpenChanged(keepOpen) {
300367
this.keepTaskPanelOpen = keepOpen
301368
},
@@ -311,6 +378,12 @@ export const entitiesMixin = {
311378
this.onSelectedDepartmentChanged()
312379
},
313380

381+
currentProduction(newProd, oldProd) {
382+
if (!oldProd || !newProd || oldProd.id === newProd.id) return
383+
this.keepTaskPanelOpen = false
384+
this.clearSelection()
385+
},
386+
314387
displaySettings: {
315388
deep: true,
316389
handler(newSettings) {

0 commit comments

Comments
 (0)