diff --git a/src/App.vue b/src/App.vue index 1b2f36d060..8903ccf6f8 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2529,6 +2529,14 @@ th.validation-cell { height: 43px; } +// vue-date-picker's default dark border (`#2d2d2d`) is too low-contrast +// against the picker background. Bump it just enough to read as a +// border without dominating, and keep the library defaults for +// everything else (background, hover/focus stay untouched). +.dp__theme_dark { + --dp-border-color: #3a3a3a !important; +} + #app .v3-emoji-picker.v3-color-theme-dark .v3-sticky { text-transform: uppercase; font-size: 0.8em; diff --git a/src/components/cells/TaskStatusCell.vue b/src/components/cells/TaskStatusCell.vue index d0956ff04d..62e9afdf0f 100644 --- a/src/components/cells/TaskStatusCell.vue +++ b/src/components/cells/TaskStatusCell.vue @@ -1,5 +1,5 @@ - @@ -119,4 +120,79 @@ export default { width: 300px; padding: 1em; } + +@media screen and (max-width: 768px) { + // Turn each row into a card: the table head disappears, every cell is + // labelled via its data-label attribute, and the actions cell collapses + // to a footer row. Keep the wrapper's overflow-y: auto from the global + // .datatable-wrapper rule so the list still scrolls inside .fixed-page. + :deep(.datatable-wrapper) { + background: transparent; + border: 0; + overflow-x: visible; + } + + .datatable, + .datatable-body { + display: block; + width: 100%; + } + + .datatable-head { + display: none; + } + + .datatable-row { + background: var(--background); + border: 1px solid var(--border); + border-radius: 12px; + display: block; + margin-bottom: 0.75em; + padding: 0.85em 1em; + } + + .dark .datatable-row { + background: var(--background-alt); + } + + .datatable-row td { + border: 0; + display: block; + padding: 0.4em 0; + width: auto; + } + + // Cells without a data-label are placeholders to keep the desktop + // table columns aligned — collapse them on mobile so empty fields + // don't leave gaps. + .datatable-row td:not([data-label]):not(.actions):not(.name) { + display: none; + } + + .datatable-row td[data-label]::before { + color: var(--text-alt); + content: attr(data-label); + display: block; + font-size: 0.75em; + letter-spacing: 0.06em; + margin-bottom: 0.2em; + text-transform: uppercase; + } + + // The name doubles as the card title — drop its label and bump the + // font weight. + .datatable-row .name { + font-size: 1.05em; + font-weight: 600; + padding-top: 0; + + &::before { + display: none; + } + } + + .datatable-row .actions { + display: none; + } +} diff --git a/src/components/lists/BackgroundList.vue b/src/components/lists/BackgroundList.vue index 782ae23101..bb91ef69ec 100644 --- a/src/components/lists/BackgroundList.vue +++ b/src/components/lists/BackgroundList.vue @@ -43,7 +43,7 @@ - +

{{ entries.length }} diff --git a/src/components/lists/CustomActionList.vue b/src/components/lists/CustomActionList.vue index 2f3bdbc859..049eb66411 100644 --- a/src/components/lists/CustomActionList.vue +++ b/src/components/lists/CustomActionList.vue @@ -57,7 +57,12 @@ - +

{{ entries.length }} {{ $t('custom_actions.number', entries.length) }} diff --git a/src/components/lists/DayOffList.vue b/src/components/lists/DayOffList.vue index 9c19ca73cb..70f83924e8 100644 --- a/src/components/lists/DayOffList.vue +++ b/src/components/lists/DayOffList.vue @@ -61,7 +61,12 @@

{{ $t('days_off.no_days_off') }}

- +
- + {{ linkedHardwareItems[entry.id]?.map(item => item.name).join(', ') }} - + {{ linkedSoftwareLicenses[entry.id] ?.map(item => item.name) @@ -49,7 +55,12 @@ - +

{{ entries.length }} {{ $t('departments.number', entries.length) }}

@@ -116,4 +127,71 @@ defineEmits(['delete-clicked', 'edit-clicked']) padding: 0.5em; } } + +@media screen and (max-width: 768px) { + // Stack each row as a card, mirroring the AssetTypeList mobile layout. + :deep(.datatable-wrapper) { + background: transparent; + border: 0; + overflow-x: visible; + } + + .datatable, + .datatable-body { + display: block; + width: 100%; + } + + .datatable-head { + display: none; + } + + .datatable-row { + background: var(--background); + border: 1px solid var(--border); + border-radius: 12px; + display: block; + margin-bottom: 0.75em; + padding: 0.85em 1em; + } + + .dark .datatable-row { + background: var(--background-alt); + } + + .datatable-row td { + border: 0; + display: block; + height: auto; + max-width: none; + min-width: 0; + padding: 0.4em 0; + text-align: left; + width: auto; + } + + .datatable-row td[data-label]::before { + color: var(--text-alt); + content: attr(data-label); + display: block; + font-size: 0.75em; + letter-spacing: 0.06em; + margin-bottom: 0.2em; + text-transform: uppercase; + } + + .datatable-row .name { + font-size: 1.05em; + font-weight: 600; + padding-top: 0; + + &::before { + display: none; + } + } + + .datatable-row .actions { + display: none; + } +} diff --git a/src/components/lists/EditList.vue b/src/components/lists/EditList.vue index b1588ee0d9..2d238137e2 100644 --- a/src/components/lists/EditList.vue +++ b/src/components/lists/EditList.vue @@ -450,7 +450,7 @@ - +
- +
- +
- +
- + {{ entry.name }} - + {{ entry.short_name }} - + {{ entry.monthly_cost }} - + {{ entry.inventory_amount }} {{ remainingHardwareItems[entry.id] }} @@ -51,7 +61,12 @@
- +

{{ entries.length }} {{ $t('hardware_items.number', entries.length) }} @@ -90,14 +105,74 @@ defineEmits(['delete-clicked', 'edit-clicked']) } @media screen and (max-width: 768px) { - .name { - min-width: auto; - padding: 0.5em; + // Stack each row as a card, mirroring the AssetTypeList mobile layout. + :deep(.datatable-wrapper) { + background: transparent; + border: 0; + overflow-x: visible; + } + + .datatable, + .datatable-body { + display: block; + width: 100%; + } + + .datatable-head { + display: none; + } + + // Override App.vue's global `:last-child { background: transparent !important }` + // rule, which would otherwise leave the last card with only its border drawn. + .datatable-row, + .datatable-row:last-child { + background: var(--background) !important; + border: 1px solid var(--border); + border-radius: 12px; + display: block; + margin-bottom: 0.75em; + padding: 0.85em 1em; + } + + .dark .datatable-row, + .dark .datatable-row:last-child { + background: var(--background-alt) !important; + } + + .datatable-row td { + background-color: transparent !important; + border: 0; + display: block; + height: auto; + max-width: none; + min-width: 0; + padding: 0.4em 0; + text-align: left; + width: auto; + } + + .datatable-row td[data-label]::before { + color: var(--text-alt); + content: attr(data-label); + display: block; + font-size: 0.75em; + letter-spacing: 0.06em; + margin-bottom: 0.2em; + text-transform: uppercase; + } + + .datatable-row .name { + font-size: 1.05em; + font-weight: 600; + padding-top: 0; + + &::before { + display: none; + } } - .datatable-body td, - .datatable-head th { - padding: 0.5em; + .datatable-row .actions { + display: none; } } diff --git a/src/components/lists/KanbanBoard.vue b/src/components/lists/KanbanBoard.vue index 1c2a5b4a86..b48be164d7 100644 --- a/src/components/lists/KanbanBoard.vue +++ b/src/components/lists/KanbanBoard.vue @@ -107,7 +107,7 @@ - + - +

diff --git a/src/components/lists/ProductionAssetTypeList.vue b/src/components/lists/ProductionAssetTypeList.vue index 63cc2b4f3f..c87a727930 100644 --- a/src/components/lists/ProductionAssetTypeList.vue +++ b/src/components/lists/ProductionAssetTypeList.vue @@ -98,7 +98,13 @@
- +
- +

{{ entries.length }} {{ diff --git a/src/components/lists/QuotaShotList.vue b/src/components/lists/QuotaShotList.vue index 5ea2ec4c2d..cc07f82cd9 100644 --- a/src/components/lists/QuotaShotList.vue +++ b/src/components/lists/QuotaShotList.vue @@ -23,7 +23,13 @@ - + diff --git a/src/components/lists/SequenceList.vue b/src/components/lists/SequenceList.vue index a651419d9b..83e5a22859 100644 --- a/src/components/lists/SequenceList.vue +++ b/src/components/lists/SequenceList.vue @@ -446,7 +446,7 @@ - +

- +
- +
- + {{ entry.name }} - + {{ entry.short_name }} - + {{ entry.file_extension }} - + {{ entry.version }} - + {{ entry.monthly_cost }} - + {{ entry.inventory_amount }} {{ remainingSoftwareLicenses[entry.id] }} @@ -63,7 +80,11 @@
- +

{{ entries.length }} {{ $t('software_licenses.number', entries.length) }} @@ -108,20 +129,74 @@ defineEmits(['delete-clicked', 'edit-clicked']) } @media screen and (max-width: 768px) { - .name { - min-width: auto; - padding: 0.5em; + // Stack each row as a card, mirroring the AssetTypeList mobile layout. + :deep(.datatable-wrapper) { + background: transparent; + border: 0; + overflow-x: visible; + } + + .datatable, + .datatable-body { + display: block; + width: 100%; } - .extension, - .version { + .datatable-head { + display: none; + } + + // Override App.vue's global `:last-child { background: transparent !important }` + // rule, which would otherwise leave the last card with only its border drawn. + .datatable-row, + .datatable-row:last-child { + background: var(--background) !important; + border: 1px solid var(--border); + border-radius: 12px; + display: block; + margin-bottom: 0.75em; + padding: 0.85em 1em; + } + + .dark .datatable-row, + .dark .datatable-row:last-child { + background: var(--background-alt) !important; + } + + .datatable-row td { + background-color: transparent !important; + border: 0; + display: block; + height: auto; + max-width: none; + min-width: 0; + padding: 0.4em 0; + text-align: left; width: auto; - padding: 0.5em; } - .datatable-body td, - .datatable-head th { - padding: 0.5em; + .datatable-row td[data-label]::before { + color: var(--text-alt); + content: attr(data-label); + display: block; + font-size: 0.75em; + letter-spacing: 0.06em; + margin-bottom: 0.2em; + text-transform: uppercase; + } + + .datatable-row .name { + font-size: 1.05em; + font-weight: 600; + padding-top: 0; + + &::before { + display: none; + } + } + + .datatable-row .actions { + display: none; } } diff --git a/src/components/lists/StatusAutomationList.vue b/src/components/lists/StatusAutomationList.vue index 3be6d44065..08f94ecfc3 100644 --- a/src/components/lists/StatusAutomationList.vue +++ b/src/components/lists/StatusAutomationList.vue @@ -97,7 +97,11 @@ - +

{{ entries.length }} diff --git a/src/components/lists/StudioList.vue b/src/components/lists/StudioList.vue index d85bd722fd..43708c11ea 100644 --- a/src/components/lists/StudioList.vue +++ b/src/components/lists/StudioList.vue @@ -29,7 +29,12 @@ - +

{{ entries.length }} {{ $t('studios.number', entries.length, { n: entries.length }) }} diff --git a/src/components/lists/TaskList.vue b/src/components/lists/TaskList.vue index 6b51a6e70a..4ca14fde84 100644 --- a/src/components/lists/TaskList.vue +++ b/src/components/lists/TaskList.vue @@ -257,7 +257,12 @@ - +

- - {{ $t('task_status.fields.name') }} - {{ $t('task_status.fields.short_name') }} + + {{ $t('task_status.fields.name') }} + {{ $t('task_status.fields.is_default') }} @@ -38,43 +38,63 @@ class="datatable-body" item-key="id" tag="tbody" + :disabled="isMobile" @end="updateTaskStatusPriorities" v-model="taskStatuses" > - - diff --git a/src/components/lists/TaskTypeList.vue b/src/components/lists/TaskTypeList.vue index 560256e42d..3f25b894c5 100644 --- a/src/components/lists/TaskTypeList.vue +++ b/src/components/lists/TaskTypeList.vue @@ -27,29 +27,42 @@ class="datatable-body" item-key="id" tag="tbody" + :disabled="isMobile" @end="updatePriority" v-model="items" > - diff --git a/src/components/lists/TimeSpentTaskList.vue b/src/components/lists/TimeSpentTaskList.vue index c15f203f3f..ac9d28c3dc 100644 --- a/src/components/lists/TimeSpentTaskList.vue +++ b/src/components/lists/TimeSpentTaskList.vue @@ -1,6 +1,12 @@ @@ -164,9 +205,8 @@ import { formatSimpleDate } from '@/lib/time' import playlistsApi from '@/store/api/playlists' import BaseModal from '@/components/modals/BaseModal.vue' -import ModalFooter from '@/components/modals/ModalFooter.vue' import ButtonSimple from '@/components/widgets/ButtonSimple.vue' -import ComboboxBoolean from '@/components/widgets/ComboboxBoolean.vue' +import Checkbox from '@/components/widgets/Checkbox.vue' import DateField from '@/components/widgets/DateField.vue' const { t } = useI18n() @@ -182,12 +222,14 @@ const emit = defineEmits(['cancel', 'links-updated']) const shareLinks = ref([]) const expirationDate = ref(null) -const canComment = ref('true') +const canComment = ref(true) const loading = reactive({ create: false }) const errors = reactive({ create: false }) const openInviteToken = ref(null) const inviteState = reactive({}) +const confirmingRevoke = ref(null) +const isCreateFormVisible = ref(false) const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ @@ -311,6 +353,18 @@ const loadLinks = async () => { } } +const showCreateForm = () => { + errors.create = false + isCreateFormVisible.value = true +} + +const hideCreateForm = () => { + isCreateFormVisible.value = false + errors.create = false + expirationDate.value = null + canComment.value = true +} + const createLink = async () => { loading.create = true errors.create = false @@ -320,9 +374,10 @@ const createLink = async () => { : undefined await playlistsApi.createShareLink(props.playlist.id, { expiration_date: expDate, - can_comment: canComment.value === 'true' + can_comment: canComment.value }) await loadLinks() + hideCreateForm() } catch (err) { console.error(err) errors.create = true @@ -330,9 +385,14 @@ const createLink = async () => { loading.create = false } -const revokeLink = async token => { +const askRevoke = token => { + confirmingRevoke.value = token +} + +const confirmRevoke = async token => { try { await playlistsApi.revokeShareLink(props.playlist.id, token) + confirmingRevoke.value = null await loadLinks() } catch (err) { console.error(err) @@ -382,57 +442,141 @@ onMounted(() => { } .share-link-item { - margin-bottom: 1em; + background: var(--background-alt); + border: 1px solid var(--border); + border-radius: 10px; + margin-bottom: 0.75em; + padding: 0.75em 0.85em; +} + +.dark .share-link-item { + background: var(--background); } .share-link-row { - gap: 0; + align-items: center; + gap: 0.2em; .input { - font-size: 0.85em; - background: var(--background-alt); - color: var(--text); + background: var(--background); border: 1px solid var(--border); - border-radius: 10px; + border-radius: 8px; + color: var(--text); cursor: text; + flex: 1 1 auto; + font-size: 0.85em; + margin-right: 0.5em; padding-left: 1em; } - .copy-button, - .invite-button { - flex: 0 0 auto; - border-radius: 10px; - margin-left: -1px; - } - - .invite-button { - margin-left: 0.5em; - - &.active { - background: var(--background-selectable); - } + .dark & .input { + background: var(--background-alt); } + .copy-button, + .invite-button, .revoke-button { + border-radius: 8px; flex: 0 0 auto; - margin-left: 0.5em; - opacity: 0; - transition: opacity 0.15s; + margin: 0; } - &:hover .revoke-button { - opacity: 1; + .invite-button.active { + background: var(--background-selectable); } } .create-section { - .subtitle { - margin-bottom: 1em; + margin-top: 1.5em; + + .field { + margin-bottom: 0; } +} + +.add-row { + display: flex; + justify-content: center; +} + +.create-card { + background: var(--background-alt); + border: 1px solid var(--border); + border-radius: 10px; + padding: 1.25em 1em 1em; +} + +.dark .create-card { + background: var(--background); +} + +.create-card-title { + color: var(--text); + font-size: 1.1em; + font-weight: 600; + letter-spacing: 0.06em; + margin: 0 0 1.25em; + text-align: center; + text-transform: uppercase; +} + +.create-form { + align-items: center; + display: flex; + flex-direction: column; + gap: 1em; .field { - margin-bottom: 1em; + align-items: center; + display: flex; + flex-direction: column; + gap: 0.4em; + margin-bottom: 0; + text-align: center; } + + .field .label { + margin: 0; + } +} + +.form-actions { + align-items: center; + display: flex; + gap: 0.6em; + justify-content: center; + margin-top: 0.5em; +} + +.revoke-confirm { + align-items: center; + gap: 0.5em; +} + +.revoke-confirm-text { + color: $red; + font-size: 0.9em; + margin: 0; +} + +.empty-links { + color: var(--text-alt); + font-size: 0.9em; + margin: 0 0 1.25em; + text-align: center; +} + +.create-error { + color: $red; + font-size: 0.85em; + margin: 0.75em 0 0; + text-align: right; +} + +.close-row { + display: flex; + justify-content: flex-end; + margin-top: 1.5em; } .share-link-info { diff --git a/src/components/modals/ViewPlaylistModal.vue b/src/components/modals/ViewPlaylistModal.vue index 244c0efe43..d5799d63b3 100644 --- a/src/components/modals/ViewPlaylistModal.vue +++ b/src/components/modals/ViewPlaylistModal.vue @@ -124,14 +124,24 @@ const onPreviewChanged = async ({ }) } -const onAnnotationChanged = ({ preview, additions, deletions, updates }) => { - store.dispatch('updatePreviewAnnotation', { - taskId: preview.task_id, - preview, - additions, - deletions, - updates - }) +const onAnnotationChanged = async ({ + preview, + additions, + deletions, + updates +}) => { + try { + await store.dispatch('updatePreviewAnnotation', { + taskId: preview.task_id, + preview, + additions, + deletions, + updates + }) + playlistPlayer.value?.confirmAnnotationsSaved() + } catch { + playlistPlayer.value?.restoreFailedAnnotations() + } } const onAnnotationsRefreshed = preview => { diff --git a/src/components/pages/AssetLibrary.vue b/src/components/pages/AssetLibrary.vue index fd6310068a..d70ef983e5 100644 --- a/src/components/pages/AssetLibrary.vue +++ b/src/components/pages/AssetLibrary.vue @@ -1,5 +1,5 @@ - diff --git a/src/components/pages/Assets.vue b/src/components/pages/Assets.vue index ca9a07c54f..93af608052 100644 --- a/src/components/pages/Assets.vue +++ b/src/components/pages/Assets.vue @@ -64,12 +64,11 @@
@@ -442,8 +441,6 @@ export default { 'assetListScrollPosition', 'assetsCsvFormData', 'assetSearchText', - 'assetSearchFilterGroups', - 'assetSearchQueries', 'assetSorting', 'assetTypes', 'assetValidationColumns', @@ -467,9 +464,23 @@ export default { 'productionAssetTaskTypes', 'selectedAssets', 'taskTypeMap', - 'user' + 'user', + 'userFilters', + 'userFilterGroups' ]), + productionAssetSearchQueries() { + const productionId = this.currentProduction?.id + if (!productionId) return [] + return this.userFilters?.asset?.[productionId] || [] + }, + + productionAssetFilterGroups() { + const productionId = this.currentProduction?.id + if (!productionId) return [] + return this.userFilterGroups?.asset?.[productionId] || [] + }, + addThumbnailsModal() { return this.$refs['add-thumbnails-modal'] }, diff --git a/src/components/pages/Edit.vue b/src/components/pages/Edit.vue index 5b89ab9e8d..1563e5bc28 100644 --- a/src/components/pages/Edit.vue +++ b/src/components/pages/Edit.vue @@ -909,15 +909,20 @@ export default { if (isDifferentPreviewFile) this.sendUpdatePlayingStatus() }, - onAnnotationChanged({ preview, additions, deletions, updates }) { + async onAnnotationChanged({ preview, additions, deletions, updates }) { const taskId = preview.task_id - this.updatePreviewAnnotation({ - taskId, - preview, - additions, - deletions, - updates - }) + try { + await this.updatePreviewAnnotation({ + taskId, + preview, + additions, + deletions, + updates + }) + this.confirmAnnotationsSaved() + } catch { + this.restoreFailedAnnotations() + } }, onVideoLoaded() { diff --git a/src/components/pages/EntitySearch.vue b/src/components/pages/EntitySearch.vue index 4ad82ed909..3aede6d6e9 100644 --- a/src/components/pages/EntitySearch.vue +++ b/src/components/pages/EntitySearch.vue @@ -1,6 +1,6 @@ - diff --git a/src/components/pages/Playlist.vue b/src/components/pages/Playlist.vue index 680462f517..ad67d6f44a 100644 --- a/src/components/pages/Playlist.vue +++ b/src/components/pages/Playlist.vue @@ -1254,15 +1254,21 @@ export default { this.clearSilent() }, - onAnnotationChanged({ preview, additions, deletions, updates }) { + async onAnnotationChanged({ preview, additions, deletions, updates }) { const taskId = preview.task_id - this.updatePreviewAnnotation({ - taskId, - preview, - additions, - deletions, - updates - }) + const playlistPlayer = this.$refs['playlist-player'] + try { + await this.updatePreviewAnnotation({ + taskId, + preview, + additions, + deletions, + updates + }) + playlistPlayer?.confirmAnnotationsSaved() + } catch { + playlistPlayer?.restoreFailedAnnotations() + } }, // Search diff --git a/src/components/pages/ProductionNewsFeed.vue b/src/components/pages/ProductionNewsFeed.vue index 3c274cfa75..2abb1af61a 100644 --- a/src/components/pages/ProductionNewsFeed.vue +++ b/src/components/pages/ProductionNewsFeed.vue @@ -3,258 +3,53 @@
-
- -
- -
- - - -
- - -
-
- -
- - - -
- -
+ + +
- {{ $t('news.no_news') }} -
-
- + +

{{ $t('news.no_news') }}

+

{{ $t('news.no_news_hint') }}

+
@@ -262,7 +57,24 @@
-
+
+ +
+ - diff --git a/src/components/pages/Profile.vue b/src/components/pages/Profile.vue index 09c2893f50..816982beca 100644 --- a/src/components/pages/Profile.vue +++ b/src/components/pages/Profile.vue @@ -1,166 +1,140 @@ - - diff --git a/src/components/pages/STUDIO_REVIEW.md b/src/components/pages/STUDIO_REVIEW.md new file mode 100644 index 0000000000..e6325f1495 --- /dev/null +++ b/src/components/pages/STUDIO_REVIEW.md @@ -0,0 +1,97 @@ +# Studio Page — Code Review + +Date: 2026-04-13 + +Fichiers analyses : +- `src/components/pages/Studios.vue` +- `src/components/lists/StudioList.vue` +- `src/components/modals/EditStudiosModal.vue` +- `src/components/widgets/ComboboxStudio.vue` +- `src/components/widgets/StudioName.vue` +- `src/store/modules/studios.js` +- `src/store/api/studios.js` + +--- + +## 1. Clarte du code + +### Options API → Composition API + +Les 3 composants principaux (`Studios.vue`, `StudioList.vue`, `EditStudiosModal.vue`) sont encore en Options API alors que la convention du projet est ` diff --git a/src/components/pages/SoftwareLicenses.vue b/src/components/pages/SoftwareLicenses.vue index becf8613f6..b40698fd3c 100644 --- a/src/components/pages/SoftwareLicenses.vue +++ b/src/components/pages/SoftwareLicenses.vue @@ -51,6 +51,7 @@ import { useStore } from 'vuex' import csv from '@/lib/csv' import stringHelpers from '@/lib/string' +// eslint-disable-next-line no-unused-vars import SoftwareLicenseList from '@/components/lists/SoftwareLicenseList.vue' import DeleteModal from '@/components/modals/DeleteModal.vue' import EditSoftwareLicenseModal from '@/components/modals/EditSoftwareLicenseModal.vue' diff --git a/src/components/pages/Task.vue b/src/components/pages/Task.vue index c744d07daa..8a0de126c9 100644 --- a/src/components/pages/Task.vue +++ b/src/components/pages/Task.vue @@ -1394,15 +1394,21 @@ export default { return route }, - onAnnotationChanged({ preview, additions, deletions, updates }) { + async onAnnotationChanged({ preview, additions, deletions, updates }) { const taskId = this.task.id - this.updatePreviewAnnotation({ - taskId, - preview, - additions, - deletions, - updates - }) + const previewPlayer = this.$refs['preview-player'] + try { + await this.updatePreviewAnnotation({ + taskId, + preview, + additions, + deletions, + updates + }) + previewPlayer?.confirmAnnotationsSaved() + } catch { + previewPlayer?.restoreFailedAnnotations() + } }, onAddExtraPreviewClicked() { diff --git a/src/components/pages/TaskStatus.vue b/src/components/pages/TaskStatus.vue index d1b9830bfc..6b1567bb15 100644 --- a/src/components/pages/TaskStatus.vue +++ b/src/components/pages/TaskStatus.vue @@ -46,7 +46,7 @@ :active="modals.del" :is-loading="loading.del" :is-error="errors.del" - :text="deleteText()" + :text="deleteText" :error-text="$t('task_status.delete_error')" @cancel="modals.del = false" @confirm="confirmDeleteTaskStatus" @@ -54,234 +54,207 @@
- diff --git a/src/components/pages/TaskTypes.vue b/src/components/pages/TaskTypes.vue index 6124377876..d257e1ccdc 100644 --- a/src/components/pages/TaskTypes.vue +++ b/src/components/pages/TaskTypes.vue @@ -35,7 +35,7 @@ :active="modals.del" :is-loading="loading.del" :is-error="errors.del" - :text="deleteText()" + :text="deleteText" :error-text="$t('task_types.delete_error')" @cancel="modals.del = false" @confirm="confirmDeleteTaskType" @@ -43,265 +43,228 @@
- diff --git a/src/components/pages/budget/SalaryScale.vue b/src/components/pages/budget/SalaryScale.vue index ace3c2301d..3bd105e1a4 100644 --- a/src/components/pages/budget/SalaryScale.vue +++ b/src/components/pages/budget/SalaryScale.vue @@ -1,12 +1,12 @@