- On your local machine, in the
particle-accelerator
repository:- Pull the latest code ready for release:
git checkout main && git pull origin main
- Decide on an appropriate version number for the new version
- Update
CHANGELOG.md
by moving everything inUnreleased
to a section for the new version - Make a new commit directly on
main
which updates the CHANGELOG - Tag the new commit - for example, if the version number is v1.0.0, use
git tag v1.0.0
- Push the new version to GitHub:
git push origin main --tags
- Update the
production
branch:git checkout production && git merge main && git push origin production
- Pull the latest code ready for release:
- Make any changes to the environment variables
- Navigate to Digital Ocean --> Apps --> particle-accelerator
- Navigate to Settings --> Components: particle-accelerator
- Beside "Environment Variables", click "Edit"
- Make changes
- Click "Save"
- Deploy on Digital Ocean
- In Digital Ocean --> Apps --> particle-accelerator
- Click Actions --> Deploy
- Make any changes to the environment variables
- Navigate to Digital Ocean --> Apps --> dev-particle-accelerator
- Navigate to Settings --> Components: dev-particle-accelerator
- Beside "Environment Variables", click "Edit"
- Make changes
- Click "Save"
- Update the branch that will be deployed anytime a new commit is made
- Navigate to Digital Ocean --> Apps --> dev-particle-accelerator
- Navigate to Settings --> Components: dev-particle-accelerator
- Beside "Source", click "Edit"
- Select the branch that you want to have automatically deployed from the "Branch" dropdown list
- Click "Save"
- Make any changes to the environment variables in
.env
- Make sure to have
REACT_APP_ENV=local
in.env
- Run
npm ci
to download dependencies - Run
npm start
to build and deploy to http://localhost:3000
The PA started as the 'Particle Accelerator' and was only meant to activate Borons, and check them with the Device Lookup page (then called the Validator). At this time, the PA was also an Electron app and ran on the desktop. As time progressed, it was deemed more viable for the PA to become a React web app, so the original Electron react was flipped over to the browser. A navigation bar was added, and from there, features were rapidly added. Due to the very primitive nature of the first releases of the PA, there may exist some pockets of code that don't quite fit the style of the rest of the project.
Nearly all of the tools in the PA work on the following basis:
- User inputs information
- User clicks 'submit'
- A react hook containing the status of the request is set to
loading
or something of the like, which updates a badge/spinner to indicate loading to the user - A request for the data/operation/etc is handled with
async/await
while the user waits - Based on the response from the operation in step 4, the hook containing the status is updated to show the user the result of their input.
- Whatever data is returned is supplied to a hook/function/variable, etc.
-
The props in the Accelerator are passed on the following hierarchy:
App.js
RouterInterface.jsx
Navigation.jsx
orFrame.jsx
- (from
Frame.jsx
) ->views
- (from
Frame.jsx
andviews
) -> other individual components
-
Passing props between all of the various levels is somewhat tedious.
-
I enclosed every
setState
within an arbitrarychangeState
function. I'm unsure how necessary this was but various guides have advised for this approach. (https://webomnizz.com/change-parent-component-state-from-child-using-hooks-in-react/)
- Files and components are organized in four main folders.
components
- Every subcomponent is stored in a subdirectory labelled after the parent component, unless it is ageneral
component.utilities
- Every 'middle-end' function that assists the accelerator, as well as classes and constants.views
- Every view seen byFrame.jsx
pdf
- Components that produce the button labelsstylesheets
-.css
files for particular uses.graphics
- SVGs for use in various pagesupper-level-components
- components (andPages.js
) for use in the higher level abstractions of the program (Frame.jsx
,Navigation.jsx
,PageNotFound.jsx
,Pages.js
, andRouterInterface.jsx
)
Environment Variables in the PA are done in DigitalOcean. Each environment variable must be preceded by REACT_APP_
, for example: REACT_APP_TWILIO_MESSAGING_SID
. Environment variables are to be added at the component level, not the app level.
A .env.example
file can also be found in this repo.
token
meansparticleToken
if not defined. This is an artefact from when the program used to only deal with tokens from Particle.
- The PA makes use of CSS in three main ways:
- (main, desirable, way) css-in-js
styles
constants containing CSS. - Stylesheets in the
stylesheets
directory: used only for styling hovers and clicking properties, or existing components (harder to do in css-in-js) - Inline styles, which are regretted and frowned upon. A future make-work project would be to remove the heavy usage of inline styles in this project.
- (main, desirable, way) css-in-js
The PA attempts to use Clickup [the PA Tracker] as a primitive database. This is done in two main ways:
- The Device Manager allows the user to pull devices from the tracker into local memory on demand
- At every step of the provisioning process, the PA will only update fields on an ActivatedDevice if the operation on the clickup backend is successful. Therefore, they PA tracker and the PA will stay in sync. Discrepancies will only arise if edits are made on the clickup end, but a device can always be popped and readded from the local memory to prevent this.
-
Create a new page in the
Pages.js
file. The format is the following:// ... const Pages = { developerName: { displayName: 'Name for navigation and identification', paths: ['/array', '/of', '/the', '/desired', '/routes', '/for/the/page'], authorizations: { // Whether clickup or particle are required to access the page or not // Should always be declared whether true or false. clickup: true, particle: false, }, // Whether the page will have a loginState badge in the navbar. Generally not touched. loginBadge: false, }, }
-
If the page has
loginBadge: true
, then one must add the variables for the device inNavigation.jsx
:loginButtonConfig[Pages.developerName.displayName] = { // Hook to display what the current login state for that account is. loginState: hook, // Function to change the token (in case one would like to add a logout button to the badge) // Should probably be deprecated. changeToken: function, // Username to display on the badge if login is successful userName: hook, }
-
Add the component to the component config object in
Frame.jsx
viewConfig[Pages.developerName.displayName] = <ComponentName properties={goHere} />
- Add a better encryption mechanism for the entire site (Google OAuth?)
- [moderate] Verify the AWS and database adding and switch the variables to prod
- [good cost-benefit] Synthesize the database inserts, AWS functionality, and phone number adding into one cohesive tool to register buttons.
- [large endeavour] Automated sensor testing with the
getEventStream
function in Particle andChart.js
- [good cost-benefit] More streamlined sensor activation, less configuration, automatic sensor_XX incrementing, essentially just using the scanner and the return character to do everything
- [moderate] Make the validator look nice again
- [moderate] Toggle between Dev/Prod/Staging modes, etc.
- [large endeavour] Back the application with a database
- [decent cost-benefit] Create a (desktop application) serial tool that interfaces with an accelerator endpoint to automatically register every button
- OAuth2 Flow for Particle
- Create automated tests for the entire application, unit, integration, end-to-end, etc.
- Remove all instances of inline CSS