Repository navigation
Fix settings list reorders, CSV imports, and the action panel - #2284
Merged
Merged
Conversation
A login log whose person is missing from the person map handed an undefined person to PeopleAvatar and PeopleName, whose person prop is required. Neither widget showed anything, but Vue warned in dev builds, and the login logs spec printed these warnings in the test output. The person cell renders them only when the person is known.
With only empty cells selected in an entity list, the action panel opened the bar used last, by default the status bar, with no task to act on. Its status list stayed empty: "Change status" threw on reading the id of its first status and kept spinning. A selection left with empty cells only kept its open bar too, and a status change from there sent Zou an empty request. The panel now opens the task creation for such a selection, or no bar for users who cannot create tasks, and picks its bar again when the selection gains or loses its tasks. Without any status to apply, the status change does nothing.
Nothing reads it, and it mapped state.taskStatuseses, a misspelled key: its first read would have thrown.
Removing task statuses quickly could crash the production settings: a reload that put back a status still being removed shifted the rows while the next Remove button was held. On the release, SortableJS reported the held row as moved although no drag had started, and vuedraggable threw on it, which is the error Sentry reported. Sortable then stayed stuck: no list of the page could be dragged until leaving it, and the row showed out of order. The task status and task type lists of the production and template settings no longer start a drag from their buttons.
Four mutations rebuilt the sequence search index into the state, while the search reads the cached one. A sequence edited from the list was found under its old name only, one renamed or added by another user was not found, and after a load without tasks the search kept the index of the previous list. They now rebuild the cached index, like the other changes of the list.
A sequence renamed by another user kept its old name in the list: the update only reached the raw object of the cache, which the displayed list does not watch. It now goes through the displayed sequence too, as for the episodes.
A shot renamed by another user kept its old name in the list: the update only reached the raw object of the cache, which the displayed list does not watch. It now goes through the displayed shot too, as for the sequences.
An edit renamed by another user kept its old name in the list: the update only reached the raw object of the cache, which the displayed list does not watch. It now goes through the displayed edit too, as for the sequences.
…duction A search typed in the sequence list of one production came back in another one: on a production switch, the sequences store reset a shot search key it does not read, and the episodes store reset nothing. The back link of a sequence or episode page opened from My Tasks then filtered the list of the new production with the old search. Both stores now clear their search on a production switch, as the shots, assets, and edits stores do.
With only empty cells selected in an asset, shot, or edit list, the action panel offered to delete assets, shots, or edits. Its bar read "Delete the 0 selected assets" and opened the permanent deletion modal, which deleted nothing once DELETE was typed and stayed open. The deletion entries now need a selected line, the only thing their bars act on.
The action panel reopened the bar used last on any task selection, even when its menu did not offer it. One click on Delete assets then opened "Delete the 0 selected assets" on every task selection of the assets, shots, and edits pages, which share that bar, and a stored Create tasks opened an empty bar. The menu entries now read their conditions from one list of the bars offered to the selection, and the bar used last reopens only when it is in that list. Otherwise the panel opens as if no bar had been used.
With tasks selected and no empty cell, the action panel offered Create tasks. Its bar read "Create a task for each empty cell" and its button did nothing. The bar also stayed open once the created tasks had taken the place of the empty cells in the selection. The entry now needs an empty cell in the selection, and a bar the selection no longer offers gives way to the one the panel opens for it.
The episode list opened with a search in its URL showed that search in its field but listed every episode: the page wrote the search back to the URL, which changed no route, so nothing applied it. Opened without a search, the list kept the one of an earlier visit in the store, which the back link of an episode page then brought back. The page now applies the search of the URL to the list once loaded, as the sequence and shot pages do. A task named by task_id in the URL now stays selected too: writing the search back cleared the selection 10 ms after the list opened.
CLEAR_SHOTS and LOAD_SHOTS_START reset displayedTimeSpent, displayedEstimation, and displayedFrames, keys nothing reads, and left the drawing count alone. The store kept the totals of the previous list until the page applied its search again, which hid the mistake. Both mutations now reset the totals through setListStats, which writes the keys the list reads.
Reordering task types or statuses in the production settings could crash or save the wrong order. Each reorder or removal reloads the production, and a reload that came while a row was held rebuilt the list under it. On the drop, vuedraggable moved the row found at the index the dragged row had before: an undefined one, which threw (the error Sentry reported) and left the list unusable until the page was left, or another row, saved without a word. The dragged row could also stay on the page as a copy whose Remove button did nothing. The lists now wait for the release of a held row before rebuilding, and after a drop for the reload that follows the save. The status list rebuilds at once when that save fails, since no reload follows then.
vuedraggable reads item-key as a property name, so "taskType.id" gave every task type row an undefined key and Vue matched the rows by their position. A reload or a drop that moved the rows rebuilt the ones whose task type changed places, which took the focus out of their bitrate fields. The rows now follow their task type.
A task type reorder dropped while another was being saved raised a flag that nothing lowered. Each later save then sent its order a second time, and kept sending it while the server took more than a second to answer. The save that the flag asks for now lowers it.
A task type reorder dropped less than a second after the previous one, or while it was being saved, was never sent: the next reload put the rows back in the saved order. A reorder dropped during a save now waits for it, then only the last order is sent, and the list reloads once every order is saved.
…a drag Each change to a production template reloads the whole template. When a task type or status was removed or added just before a drag, the reload rebuilt the list under the dragged row: the drop threw and left the list unusable until the page was left, or saved another row at the place the dragged one was dropped. The task type and status lists of a template now wait for the release of a held row before rebuilding. A row removed during the drag stays out of the saved order, since Zou links again what a template reorder names. After a drop, the lists wait for the reload of the template, which now follows a failed reorder too.
The global task type and status lists rebuilt themselves on every change of the store, a row being dragged included: the answers to the saves of a status reorder, or a task type another user deleted. The drop then threw and left the list unusable until the page was left, or moved another row than the dragged one. Both lists now wait for the release of a held row before rebuilding. A row deleted during the drag stays out of the saved order: the task type page put it back in the store, and the save of a deleted status fails.
Move the queue that saves the task type orders of the production settings to func: one save at a time, then only the last order waiting. The global task type and status pages need it too. A failed save no longer drops the order waiting behind it, and a save that throws at once no longer stops every later one.
A global task type reorder dropped less than a second after the previous one, or while it was being saved, was never sent: the list showed the new order, the server kept the old one. After a failed save, no later reorder was sent until the page was reloaded. A reorder dropped during a save now waits for it, then only the last order is sent, and a failed save no longer blocks the next ones.
A global status reorder saves each status on its own. A reorder dropped while the statuses of the previous one were being saved saved its own at the same time: the order kept mixed both, statuses could share a priority, and the list showed neither order once reloaded. The statuses of a reorder now wait for those of the previous one in the same list, and only the last reorder waiting in a list is saved. The new order goes to the store at once, as on the task type page: the list no longer steps through each saved status, and a failed save no longer leaves it as it was during the drag.
The comment rendering had no emoji test. Pin the shortcodes the marked-emoji extension converts, in text, formatting, links and blocks, and the places it leaves alone: code, URLs, escaped colons and unknown names.
The column menu of the entity lists took the metadata columns again only when their number changed. On a page load, it took those of the first production by name, which the store holds before the route sets the production shown: a production with as many columns kept them in its menu, and so did a switch between two such productions. A reorder then sent the ids of the other production, which Zou refused as a whole, so the order was never saved. Productions made from one template show the same names, so nothing told the user. A column added or deleted by another user during a drag rebuilt the menu under it: the drop threw on a deleted column, and on an added one it moved another column than the dragged one and saved that order. The menu now takes the columns again whenever they or their order change, waits for the release of a held row to do so, and saves only the columns still listed.
A CSV file gone from the disk before the browser read it left the import modal of the production creation and of the asset, shot, and edit lists loading forever, without any message: the paste tab could not be confirmed anymore either, and the failure reached Sentry as an unhandled error. An empty file did the same on every CSV import. The task type, breakdown, and people pages caught the read failures, but with a console.error that also hid their bugs from Sentry. Every CSV import now says that the file could not be read, or that it is empty, and stays usable: picking the same file again tries it again, and Preview waits for that pick, since the failed file would fail the same way. The modal leaves the upload errors to the preview and the page. A file the browser could not read is only logged; any other failure stays unhandled, so a bug still reaches Sentry. The task type import also opens again without the error of a past failure. The header capitalization dropped from processCSV changed nothing and threw on an empty file.
A drop of text or of a link holds no file, yet the widget emitted a selection for it, undefined for a single file: the CSV import modals then failed to read it. The widget now ignores such a drop.
The entity lists reset the page cursor on every key release, mouse release and mouse exit of the page, even with no grab running. Once an outside script had taken the body out of the page, each of these events threw, which is the error Sentry reported on the Sequences page. The reset now only runs to end a grab, as useGrabList already does.
When Zou refused the assets or shots CSV of a new production, the page went on to the production anyway: the error it had just set never showed, and the user found an empty or partial list with no word of the failure. The catches also hid any bug from Sentry. A refused import now keeps the page, with Zou's reason and the number of rows imported first, or with the notice that a timed out import goes on in the background. Once the production exists, the button opens it instead of creating a second one, and the import buttons are disabled, since a file picked then would never be uploaded. A failure of its setup then says that the production has been created, rather than that its creation failed. A failed request is only logged; any other failure stays unhandled, so a bug still reaches Sentry. The production opens on the page of the type Zou gave it: the type of its template, if any, and not the one the form shows by then.
The schedule reset the page cursor on every mouse release, touch end and mouse exit of the page, even with no move, resize or grab running. Once an outside script had taken the body out of the page, each of these events threw, as in the entity lists. The reset now only follows an interaction. The rest of the handler still runs on every release: a click below the rows starts nothing, and it must still clear the selection.
A CSV imported in the assets or shots step of the production creation was uploaded even once the production type had hidden that step: shots imported before a switch to "Only assets" were created in a production that never shows them, and assets in an "Only shots" one. The shots guard read a field the page never sets, and the assets had none. The creation now uploads only the imports of the steps on screen.
The production creation still mounted the modal that added shots by hand, with its handlers and the lists they filled, but nothing has opened it since 3ee3a7f removed its commented-out button. The shots it collected would have counted as shots to import, and none was ever sent to Zou. The unused flag of an asset modal and the labels of the two removed buttons, in every locale, go too.
Three error paths of the clients tab spec, and the failed overview load of the open productions spec, let their logged error reach the console. Spy on console.error in those four tests, checking that each failure is logged.
After a drop, the task type lists of the production settings wait for the reload that follows the save to rebuild. A failed save brings no reload: the list kept what it showed during the drag, a task type removed meanwhile included, until the next change of the production. A failed save now reloads the production too, since Zou may hold an order dropped and saved after the failed one, and the lists rebuild from it, or from the store as it was when that reload fails as well.
A task type reorder that waited for the previous save was sent to the production shown once that save ended. After a switch to another production in between, it reordered the links of that production to the task types both share, without a word. A drop for another production, or another entity, also took the place of an order still waiting, which was then never sent. The order now keeps the production it was made in, and the task types of each entity of a production have their own queue of saves.
With only empty cells selected, the action panel lists no custom action. When tasks then joined the selection, the panel chose its bar before listing their custom actions: the custom action bar used last did not count as offered, and the status bar opened instead. The panel now lists the statuses and custom actions of the selection before choosing its bar.
Recent specs printed router-link warnings and unchecked errors on every run, unnoticed: in an agent session Vitest picks its minimal reporter, which drops stderr. Say how to see that output and how to fix its usual causes.
Since Zou 1.0.53, a password reset request gets the same answer whatever the account, so that nobody can tell which accounts exist. The page still checked failed answers for an "inactive" message that Zou no longer sends. Remove that branch and the login.reset_password_inactive key from every locale.
The entity list spec host emitted keep-task-panel-open without declaring it, and the two client access reset tests compared component instances with toBe, which enumerates their keys when they differ: 14 Vue warnings in all. The clients tab reset test also let its save error reach the console. Declare the event like the entity lists do, check instead that the old component was unmounted, and spy on console.error in that test, checking that the failure is logged.
When a change to a template failed, the page kept showing it. A new metadata column stayed in the list and was sent twice on the next try, which saved two identical columns, and a column whose removal failed vanished from the list. The page now reloads the template after any failed change, as it already did after a task type or status reorder.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Solution