When displaying the schedule, scroll it such that the now line is on the
left to make what is displayed by default the most immediately useful
information.
Pull out the list of events into its own page sorted by name and show
the event slots in chronological order on the schedule page, with past
slots hidden by default. This makes the content underneath the schedule
the most immediately useful to have in the moment, while the full list
is kept separately and in a predictable order.
It used to be that the assigned property was not present for clients who
are not crew, but this changed with the client state refactor. It makes
more sense to only show the crew field if there are any crew present.
When async components are added dynamically to the tree via v-for list
that change their order and position gets messed up. I am not sure what
causes this, so I will just work around the issue for now and not use
async components.
Components that need async data loaded will instead depend on the parent
page fetching this data during its setup.
Use the authentication method system for the demo login and the
generated accounts. This makes it possible to toggle it off on
production systems as these shouldn't have it enabled at all.
Add the concept of authentication methods that authenticate an account
where using the telegram login widget is one such method. If a login is
done with an authentication method that's not associated with any
account the session ends up with the data from the authentication
method in order to allow registering a new account with the
authentication method.
This has to be stored on the session as otherwise it wouldn't be
possible to implement authentication methods such as OAuth2 that takes
the user to a third-party site and then redirects the browser back.
I firmly believe in free software.
The application I'm making here have capabilities that I've not seen in
any system. It presents itself as an opportunity to collaborate on a
tool that serves the people rather than corporations. Whose incentives
are to help people rather, not make the most money. And whose terms
ensure that these freedoms and incentives cannot be taken back or
subverted.
I license this software under the AGPL.
Allow a shift to have no role associated with it in order to simplify
conflict resolution around situations like a shift being created while
the role it was assoiated with was deleted. This also allows for shifts
that are freestanding to be created in case having a role doesn't make
sense for it.
Add a save dialog at the bottom of the screen that is present whenever
there are unsaved changes. This dialog provides a diff between the
client and server state so that the user can easily confirm the changes
they are about to make are the correct changes before applying them to
the server.
Array.sort() sorts by UTF-16 code points even when the items in the
array are numbers. Fix the schedule breaking when events cross
different powers of 10 in Unix time which caused the junctions to no
longer be sorted by the numeric value of their Unix time.
When modifying the set instead of replacing it with a new set the change
detection logic in Vue.js doesn't properly propagate the change, causing
certain computed properties that depend on them to go stale.
Fix by creating a new set here, which will emit a modelValue:update
event which will propagate through the v-model bindings.
Instead of having to type in exactly the name of events or shifts and
then hope you remembered it right, replace these interactions with the
custom select component that gives a complete list of the available
choices and allows quickly searching for the right one.
When editing the slots of events and shifts there are certain situations
where the event or shift a slot should belong to becomes unclear or
difficult to reliably assign. For example when adding a new slot in the
UI it may be desirable to do so before the user has input the event
or shift the slot should belong to.
In these cases, not being able to store the slot into the schedule makes
the UI logic needlessly complicated. Allow slots to be added that do
not have its assiated relation linked up to make editing and handling
such scenarios easier.
The selection of locations, events, roles, shifts and users using the
native <select> element makes for awkward and difficult interactions.
Add an alternative select control that fixes the issues with the poor
handling and navigation of the control when having many options.
The custom select component can handle the selection of either one or
many entity from a ClientMap of entiteis with a name. Typing into the
text box searches the entities by name, arrow keys can navigate and
enter confirms the chosen entity by toggling it's presence in the
selection.
Instead of merging overlapping events and shifts when displaying them in
the timetable which causes a very confusing display, add new rows when
events overlap so that each event can be fully displayed without any
overlapping in the table.
Use a single mutable location, event, slot, etc, for each unique
resource that keeps track of the local editable client copy and
the server copy of the data contained in it.
This makes it much simpler to update these data structures as I can take
advantage of the v-model bindings in Vue.js and work with the system
instead of against it.
Rename accounts to users to be consistent with the new naming scheme
where account only referes to the logged in user of the session and
implement live updates of users via a user store which listens for
updates from the event stream.
The hour headers indicate the time on the left line of the cell, this
makes them confusing to read. Shift the displayed hour to be in the
middle of the left line of the cell so that it is clear which line is
the start of which hour.
Start component names with the kind of element it creates on the page
(button, input, table, card, etc), then follow it with an hierarchy like
set of parts describing what part of the system it operates on.
This makes related components stick together in the directory listing of
components and auto-complete work better.
Use the ClientSchedule data structure for deserialising and tracking
edit state on the client instead of trying to directly deal with the
ApiSchedule type which is not build for ease of edits or rendering.
Rename and refactor the types passed over the API to be based on an
entity that's either living or a tombstone. A living entity has a
deleted property that's either undefined or false, while a tombstone
has a deleted property set to true. All entities have a numeric id
and an updatedAt timestamp.
To sync entities, an array of replacements are passed around. Living
entities are replaced with tombstones when they're deleted. And
tombstones are replaced with living entities when restored.
The EventCard logic assume interestedIds not being present means the
account can't set events as interested. Fix this logic by checking if
the account is valid instead and always have interestedIds present on
the account store.
Some functions in luxon default to the system's locale while other
functions default to "en-US". Explicitly set the locale everywhere
the luxon objects are created to avoid possible mismatches and
unexpected behaviour should the system's locale be different.
Replace the convoluted useAccountSession composable with a pinia store
that in addition allows for the consolidation of all session related
functions to grouped into one module.
Render the timeslots as an editable table of times with associated
event. When the event it's linked to is edited the time slot is removed
from the original event it belonged to and added to the possibly new
event it now belongs to. This gives a somewhat intutive editing
experience when editing time slots linked to events with multiple times.