Skip to content

Latest commit

 

History

History
421 lines (406 loc) · 20.7 KB

TODO.md

File metadata and controls

421 lines (406 loc) · 20.7 KB

#Standards ##Colors

  • Inactive border: border-gray-200
  • Active border: border-indigo-400 text-white
  • Active element: bg-indigo-400 text-white
  • Hover background: bg-gold-100
  • Text: text-gray-800
  • Primary color: indigo-500
  • Secondary color: gray-500
  • Danger color: red-500
  • Info background color: blue-100
  • Info icon color: blue-500
  • Warning color: yellow-500
  • Success color: green-100
  • OK color: green-500

#To do (v2020.2) ###Authn

  1. Allow user to request another activiation link
  2. Allow user to set for which events an email should be sent.
  3. Remove an account completely with an option to download all data and files for all projects etc. that would have been stored in the any of the owned workspaces.
  4. Complement User tests with the Settings stuff
  5. Delete settings when User model is deleted ###Clients ###Core
  6. Intercept 412 responses and fetch the desired object first rejecting the original alteration request with a generic message: "Object was externally modified, so your changes could not be applied. The modifications were loaded from the API, and should be visible."
  7. Support setting moment locale based on Laravel / browser locale. ###i12 ###Projects
  8. Write tests around ProjectRepository
  9. Delete Project in SPA
  10. Archive Project in SPA
  11. Update Project in SPA
  12. Write tests around Project API
  13. Close project. This stops timesheet entries being created against those projects (even historic timesheet entries cannot be started against closed projects). ###Public-Web ###Tasks ###Timesheets
  14. Make timesheet report graphs responsive (including ticks on X axis) ###UI-UX
  15. Make PmtechInput a global component
  16. Add FlashMessage component of some variety to show info, warning, success and global error messages.
  17. Update window title with title from routes in the afterEach guard ###Workspaces
  18. Add full member profile in order to understand email domain and country information for each user / subscriber. This can be used to determine the amount of users in a workspace and to determine whether or not VAT is to be applied to the billable amount.
  19. Make sure WorkspaceUpdated events are send (via Pusher) to web clients listening on the Workspace private channel. Make sure to have this covered in test cases.
  20. Complete WorkspacePolicy with reference to all Business Requirements
  21. Write WorkspaceController actions
  22. Create routes for workspace things - CRUD actions for API

#To do (v2020.3) ###Clients ###Core ###General ###Navigation ###Projects

  1. Add price attribute for projects
  2. Add reduction_percentage to Project
  3. When adding price to project, show estimate based on project tasks and profit_margin.
  4. Allow project member to overwrite cost from workspace member
  5. Allow project to overwrite profit_margin from workspace ###Tasks
  6. Add percent_completion to Task
  7. Add Completion field to GanttChart's GridTable
  8. Add Completion field to TaskProperties (if all tasks are at 100%, show a checked checkbox, otherwise show a number input min 0 max 100). If not all tasks have the same percent_completion value, do not allow editing of this field.
  9. Add nesting_level and parent_task_id to Task model
  10. Add actual duration, ended_at, started_at and work to Task model
  11. Add planned duration, ended_at, started_at and work to Task model
  12. ForceDelete Task in SPA only if task has no timesheet entries
  13. Reorder tasks (via buttons in toolbar)
  14. Send TaskUpdated event when task was updated
  15. When task is work-driven, update % complete according to approved timesheet records
  16. Mark task as 100% or completed. This stops timesheet entries being created against those tasks (even historic timesheet entries cannot be started against completed tasks). ###Timesheets ###UI/UX ###Users ###Workspace
  17. Add cost per workspace member
  18. Add profit_margin to workspace

#To do (v2021.1)

#To do (unassigned to release)

  1. When user accepted invitation to join or was added to a workspace, the workspace owner should be notified that the user now needs access to projects in order to collaborate with other project members.
  2. Bruteforce POST login protection - Make sure that users cannot fail login attempts more than 5 times in 5 seconds
  3. Add Brute Force protection around registration route as well.
  4. Submit weekly timesheet
  5. Lock timesheet entries after submitting
  6. Add hourly cost to workspace or project members
  7. Add type to project - hourly, fixed, retainer
  8. Currency per workspace and apply xe exchange rate between project and workspace defined in the workspace yet
  9. Unit test NotificationRepository
  10. Write Notification routes and Controller methods
  11. Unit test Notification API
  12. Create Notification controller, migration and model
  13. Write NotificationRepository
  14. Project Dashboard to list all tasks' main details (name) and total hours recorded against each task
  15. Add Currency model / migration
  16. Link Workspace and Project to Currency
  17. Automatically convert to workspace currency any project that has financial details in a different currency (payable and submitted invoices). Use the package mentioned in Laravel News "Laravel Exchange Rates is a package by Ash Allen for interacting with the exchangeratesapi.io API.".
  18. Implement logic in Login SPA Component to go to the back URL
  19. Listen to private broadcast channel for each project in Vuex
  20. GanttChart should only update API if the task was truly altered
  21. Global "loading" div with incrementLoading and decrementLoading vuex committers
  22. Replace App.vue loading with a full modal div that shows whenever there are Axios requests in progress for longer than 2 seconds
  23. GridTable to support sortable flag in field definition and sorting by multiple sortable fields
  24. GridTable to support notion of visible and hidden columns. Right click shows a popup menu where one can select to make hidden columns visible; also one can make visible columns hidden
  25. BR000003 - Add project to workspace should send Notification to Workspace Owner
  26. BR000004 - Even though tasks can be archived or deleted, this cannot happen when there are timesheet entries against a task.
  27. BR000005 - Even though projects can be archived or deleted, this cannot happen when there are timesheet entries against a project.
  28. BR000010 - Users with the role "Line Manager" or "Project Manager" can approve submitted timesheets
  29. BR000011 - Approved timesheet entries can only be archived by users with the role "Programme Manager" or "Portfolio Manager"
  30. BR000012 - Lock timesheet entries after submitting so that they cannot be edited by the user, but only approved / rejected by the respective Manager users
  31. BR000014 - Write cypress tests to make sure that the correct confirmation messages are shown.

#To do (Good first issue)

#In Progress

  1. Rewrite repositories to implement a common interface and derive from a common parent class
  2. v2020.2 - Core -

#Done

  1. BR000001 - Setup a "Default" workspace when a user registers
  2. BR000002 - Allow AccountActivation email to be regenerated upon user request
  3. BR000006 - Any project_user can create a timesheet entry against any task in the project or against the project it self
  4. BR000007 - Any workspace_user can create a timesheet entry against that workspace.
  5. BR000008 - TimesheetEntries can be created against a project as such or a task or simply in the workspace
  6. BR000009 - Users can edit only their own timesheet entries
  7. BR000013 - Workspace names should be unique for the ownerUser
  8. BR000014 - If a user deletes / archives his / her last owned workspace, warn the user specifically that that is the last owned workspace. The user can always create a new workspace any time (s)he wants.
  9. BR000015 - Client name must unique inside a workspace
  10. BR000016 - TimesheetEntry.started_at must be before TimesheetEntry.ended_at
  11. BR000017 - Two timesheet entries for the same user (regardless of workspace / project / task) may not overlap.
  12. BR000018 - When POSTing a new timesheet entry, any still running timesheet entries must be stopped by setting their ended_at attribute to one second before the new entry's started_at attribute.
  13. BR000019 - Timesheet entries can only be created through the API when a user is logged in.
  14. BR000020 - A user must have at least 1 owned Workspace at all times, unless the user is deleting its account.
  15. BR000021 - Only workspace users can retrieve workspace details from the API
  16. BR000022 - Project names must be unique within a workspace
  17. Create workspaces table - id (uuid), owner_user_id, name
  18. Create Workspace model
  19. Create relationship between User and Workspace models
  20. Create WorkspaceRepository - CRUD actions
  21. Write tests around the WorkspaceRepository
  22. Create TE Seeder
  23. Hide id, user_id, in Settings
  24. User model $with settings
  25. Create a user Settings Model and table (id (int), user_id, last_visited_view)
  26. Create settings record when a user is created.
  27. Create SettingsRepository
  28. Create command to create user settings if the user doesn't have it yet
  29. Login via the SPA - Login screen, logic, and redirect
  30. Make sure browser refresh (F5) works with Laravel routing into SPA
  31. Allow user to logout from SPA
  32. Allow last_visited_view update in Settings through SettingsController
  33. Add Project model / controller / migration
  34. projects table has workspace_id, color, name
  35. Implement relationships in Project model
  36. Write ProjectRepository
  37. Project API list projects for workspace
  38. Project API add project to workspace
  39. Load projects from API when changing into new workspaces router view
  40. WorkspaceDashboard should display a call to action if there are no projects
  41. Create new Project in SPA
  42. Add "color" and "id" to the visible properties of the Project model
  43. Workspace Dashboard should list each project's main details and show an "Add project" button
  44. Send WorkspaceUpdated notification via Pusher when project is added
  45. Add vue-router links for projects (nested under workspaces)
  46. Add Task model / controller / migration
  47. Write TaskRepository
  48. Write tests around TaskRepository
  49. Allow task index to be paginated
  50. Create new Task in SPA
  51. Order tasks in the index by their wbs by default
  52. Add TimesheetEntry model / controller / migration
  53. Write TimesheetEntryRepository
  54. Write tests around TimesheetEntryRepository
  55. Write TimesheetEntry API and corresponding tests
  56. Create timesheet entry editor form
  57. Write Authorization policy around timesheet entries
  58. Display 5 days worth of timesheet entries in the TimesheetEditor
  59. Create user_workspace and project_user
  60. Implement Project Selector for Timesheet Entry Editor
  61. The TimesheetEntryEditor should display the correct project details
  62. Implement Task Selector for Timesheet Entry Editor
  63. Show duration for Timesheet Entry Editors that are not running a new entry
  64. Start new timesheet entry from history
  65. Allow Timesheet Index By Day to be collapsed / expanded
  66. Style Timesheet Entry Editor
  67. Style Timesheet Index By Day
  68. Update API as and when "description" is updated in TimesheetEntryEditor with a delay of 2 seconds.
  69. Updates in any input in the Timesheet Entry Editor should result in a PUT request to update the API
  70. Style navigation horizontall on the top , but make it responsive
  71. Add dropdown menu "Timesheets" into menu bar (see https://tailwindcss.com/course/making-the-dropdown-interactive/)
  72. FilteringDropdownControl should highlight (bg-indigo-400) the selected entry and scroll it into view, whilst keeping the down and up keys working
  73. Disable TimesheetEntryStartButton when the description is empty
  74. TimesheetEntryEditor needs to change between TimesheetEntryStartButton and (new) TimesheetManualSaveButton components
  75. Implement Date/Time picker
  76. Use DateTimePicker in TimesheetManualSaveButton
  77. Use DateTimePicker in the TimesheetEntryStartButton to display historical started_at time
  78. Use DateTimePicker in the TimesheetEntryEditor for setting a new started_at time
  79. Style the running timesheet entry a bit better and include a DateTimePicker to reset the start time.
  80. Instead using a global onBlur event, use backdrops to capture "outside" click events for any element that has a popup (see https://tailwindcss.com/course/making-the-dropdown-interactive/ at about 04:40). See also TimesheetDropdownNavItem.
  81. Migrate to Laravel Airlock
  82. When a user creates a new project, that user should be associated with that project in project_user
  83. Add Logout to person's dropdown menu on the far right...
  84. When logging out, the authenticated Vuex state needs to change
  85. Generate timesheet report per workspace. Drill down per user, project or task
  86. When clicking the start button, after selecting project & task, the selection for project and task disappears
  87. When adding a project, the vuex store needs to reload its projects (through a Workspace Update Notification via Pusher?)
  88. Export timesheet report
  89. Style input boxes according to https://codesandbox.io/s/vue-template-lldw2?from-embed
  90. Implement a generic error handler (also in the API)
  91. Style and implement front-end
  92. Style back-end
  93. Make sure Laravel Airlock can authorize broadcasting private channel access
  94. Let the user create a new workspace in SPA
  95. Let the user switch between workspaces
  96. Update Task in SPA
  97. Look and feel of activation email - Just verify it, modify it if needed - Depends on the look and feel of the main site... Currently left blank without styles, really.
  98. Start writing e2e UI tests using cypress.io
  99. Migrate data from current www.project-management.tech to new www.project-management.tech implementation
  100. Let the user archive a workspace in SPA
  101. Let the user delete a workspace in SPA
  102. Let the user edit the workspace name in SPA
  103. Invite users (new and existing) to the workspace
  104. Let the user assign ownership of a workspace to another user
  105. When the workspace has more than 5 members the owner needs to pay
  106. When an email address registers again, but was not verified, send the whole verification email again (also create a cache entry).
  107. When an email address registers again, and it was verified before, the request should send an Unauthorized. response.
  108. Add Client model / migration / controller / repository
  109. Allow user to add client in SPA
  110. Projects can be associated with a client
  111. Add project allows user to pick a client
  112. Timesheet report can be drilled down by Client
  113. Support i18n in terms of month and day names
  114. Support Clicking Year to show a list of 10 decades (based on the current Year). Each decade can be clicked to pick a specific year in that decade
  115. Support Clicking Month to show a list of months that can be picked
  116. Support Clicking Hour to show a list of all hours that can be picked
  117. Support Clicking Minute / Second to show a list of 12 minutes / seconds (5 minutes / seconds between each, i.e. 0 5 10 15 etc) that can be picker
  118. Support proper config merging (defaultConfig in data, passedConfig in props and a new, merged, config in data which is passed on to subcomponents)
  119. Rename FilteringDropdownControl to ComboControl
  120. Support native hover events to recalculate highlightedEntryIdx and highlightedEntryId based on those hover events
  121. Receive a lot of 419 errors after 1 hour of not interacting with the site. Implement silent keep-alive or increase lifetime of session / Airlock cookie.
  122. Allow user to switch workspaces in xs / sm screens
  123. Add abbreviation and start_date attributes to project Model
  124. Show a small TimesheetEntryEditor in the bottom right hand corner when the user has a timesheet entry started and is not visiting the timesheet editor.
  125. Make sure the ComboControl filtering matches case-insensitively a regex, rather than just the start
  126. Remove members from workspace
  127. Create simple analytics where we store only the user agent and screen size information in the database.
  128. Implement SettingsRepository and use it in SettingsController
  129. Write tests around SettingsRepository and SettingsController
  130. UserRepository should not create Settings object. That has to be done in a UserObserver class.
  131. Add dropdown menu "Projects" into menu bar (see https://tailwindcss.com/course/making-the-dropdown-interactive/)
  132. Order projects in the index by their name by default
  133. Allow project index to be ordered by name, progress, etc.
  134. Add test that Settings are created when account was verified
  135. Add E-Tag support
    1. In middleware to verify against put requests
    2. In middleware to add to the response headers
    3. In models being updated out of the Vuex Store
  136. Complete CRUD actions in UserRepository - And write corresponding test cases
  137. GridTable to support clicking on row headers to select entire row. Multiple selections are possible through use of Shift-Click and Ctrl-Click
  138. Add toolbar with task and project related buttons just above the Gantt Chart
  139. Allow task to be work-driven
  140. GridTextEditor needs to send input updates more frequently than onBlur
  141. GridTable needs GridPercentageEditor
  142. Protect tasks with e-tags (so that multiple clients can view tasks...)
  143. Listen to private broadcast channel for each task in Vuex
  144. WorkspaceRepository::get should be allowed to return NULL
  145. Project and Workspace id cannot be updated through their respective repositories
  146. v2020.2
    1. Core
      1. Upgrade to Laravel 7.
      2. Repository findBy methods need to distinguish between find first and find all.

#Details ##BR000001 The workspace should only be created when the user verifies the email address. ##Login via the SPA - Login screen, logic, and redirect Correct login works and we can redirect already. Needs tweaking to correct URL (/members/workspaces/:id), so we need to verify the user profile settings for the last visited Vue view, and if none, we need to check the list of workspaces to go to the one workspace, if not -> we simply go to the first workspace in the list. ##Send WorkspaceUpdated notification via Pusher Only send the id of the affected Workspace. Load the workspace from the API. If it is the current workspace, also dispatch "workspaceChanged". ##ETag support Supporting ETags on API endpoints is fairly straightforward: grab the response from the request pipeline, and calculate some kind of strong hash (eg. sha1). Compare that value against the value of the request header If-None-Match and send appropriate back to the API caller. This is what Laravel's built-in Cache-Control (via cache.headers middleware) supports.

However, if one wants to store a number of Laravel Models in a Vuex store for easy access and retrieval without the need to keep going back to the API to retrieve these models a number of times, we need some mechanism to retrieve an ETag for each individual model in that index.

There's two ways to go about it:

  1. Only send IDs as index response, and let the SPA fire off a number of GET requests as necessary to retrieve each Model's ETag.
  2. Calculate ETag hash values on individual objects.

Option 1. has the potential to violate Laravel's throttle middleware, and thus each of those subsequent GET requests would need to be fired off at a rate of one request per second. This is not practicle in large-ish applications.

Option 2. can be implemented in various ways. I've looked at:

  1. jsonSerialization overload
  2. Response Facade extension
  3. API Middleware

Option 1. would work in terms of generating the ETag for each individual object, it would be called any time the API wants a serialized view of the model. This would open a potentially catastrophic amount of hash calculation that may slow the API right down. Also, it is not entirely clear how an index API call would provide back all the individual ETags.

Option 2. would work as well, and is, in fact, proposed by @fideloper, see https://fideloper.com/laravel4-etag-conditional-get.

Option 3. is a direct result of that article because I started looking into the $response object as a whole, and saw, much to my surprise, that we have a member original in the Response instance that we can get to by calling $response->getOriginalContent(). For GET requests, then, where the response has an Eloquent Collection, we can calculate ETags for each Model in that collection, just before the response is sent to the API consumer. We can put the Model's ID in combination with the ETag in the response headers, and we can list multiple combinations like that by using the semicolon to separate entities. All we have to do now, when we commit an index response to Vuex, is parse the ETag header, and store the ETag with the individual object in Vuex. Thus we can use that ETag value next time the SPA uses the DELETE, GET or PUT method on the given model. We can then also implement a response interceptor that verifies for 304 responses or for 412 in case of mid-air collisions.