Conversation
The typed client wraps the module's project, member and settings endpoints over the axios instance the host injects. The index page renders them with the host's own BasePage, BaseTable and BaseModal chrome: a debounced search and status filter, an actions dropdown for edit, archive and delete, and a create/edit modal that converts money to minor units and budgets to minutes on the way out and back. Every string the page renders comes from the module's own i18n bundle, and every colour from the host's semantic tokens.
`registerPage` mounts the index at /admin/modules/tasks-projects, where the sidebar entry already points, behind the module's own view-project ability. The page receives the host client, notifier and router as props, because a module bundle runs on the host's Vue instance but not on its injections.
A project carries one currency and its rates are compared in it, so filing one under a customer without naming a currency now reads the customer's own through the host company reader, and changing the customer moves the project with it. A currency the caller names always wins, and an explicit null still clears it.
Contributor
Author
|
Superseded by #14, which carries this stack consolidated into three commits on top of main. |
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.
The first UI slice of the module (M4, slice 1). The sidebar entry already
points at
/admin/modules/tasks-projects; until now that landed on the host's404 view. It now lands on a real projects index.
What is in it
resources/js/api.ts+resources/js/types/- endpoint constants andthin typed functions over the injected axios client for projects (list with
page,limit,status,search; create; update; archive; unarchive;delete), members, settings, and the host customer list the form reads.
pages/ProjectsIndexPage.vue-BasePage+BasePageHeaderwith a Hometo Projects breadcrumb, a filter toggle and a New project button; a
BaseFilterWrapperwhose search input is debounced into a server-sideBaseTablefetcher, with a status filter of Active / Archived / All; columnsfor name (colour swatch and identifier), status, customer, rate per hour and
due date, and an actions dropdown for edit, archive/restore and delete
(
window.confirmfor now).BaseEmptyPlaceholderwhen a company has noprojects at all.
components/ProjectFormModal.vue- create and edit in oneBaseModal.Rates are typed in major units and stored as minor units, budgets are typed
in hours and stored as minutes, and 422
errorsland under their fieldsthrough
BaseInputGroup.init.ts- registers the English bundle and the page throughextensions.registerPage, behindtasks-projects:view-project. The pagereceives the host client, notifier and router as props, since a module bundle
shares the host's Vue instance but not its Pinia or router injections.
ProjectService::createandupdatenow default a project'scurrency_idfrom its customer throughCompanyDataReader::findCustomer.A currency the caller names wins, and an explicit null still clears it.
Checks
pnpm run lint,pnpm exec tsc --noEmit,pnpm run build(withdist/committed),
composer run lint,composer run test(229 tests, 889assertions, 6 of them new),
validate-moduleandvalidate-package.Driven in the running dev stack with Playwright: the sidebar link lands on the
page, a project created through the modal appears in the table, search and the
status filter narrow the list, and archive, restore and delete all round-trip.
The console stays clean.
Notes and follow-ups
customer_idfor now; the name lookup is a laterslice, as is the project detail page the
routerprop is there for.unsortable rather than offering a control that does nothing.
BaseBadgecolours with!utilities:the host stylesheet is injected a second time after the module's, so an
unimportant token class loses to the badge's built-in colour.
https://claude.ai/code/session_01DCf36XDKprZifej8dc2r1E