Coder Social home page Coder Social logo

thinknimble / tn-spa-bootstrapper Goto Github PK

View Code? Open in Web Editor NEW
8.0 8.0 9.0 2.59 MB

A production-ready Django SPA app on Heroku in 20-min or less!

Home Page: https://tn-spa-bootstrapper-staging.herokuapp.com/

License: MIT License

Python 31.44% Shell 3.50% JavaScript 9.06% HTML 11.72% Vue 8.82% Procfile 0.35% TypeScript 33.08% Makefile 0.65% Dockerfile 0.47% CSS 0.91%
bootstraping cookiecutter django python reactjs vuejs

tn-spa-bootstrapper's People

Contributors

brunogarciagonzalez avatar bwennuh avatar dan1229 avatar dependabot[bot] avatar eliasbiagioninc avatar eschwartz929 avatar franagustin avatar jdephil avatar johnpark24 avatar lakardion avatar matterandy avatar mayakeeley avatar moussa-m avatar moussa-tn avatar nc-fran avatar noriega2112 avatar okayitsmikael avatar oudeismetis avatar paribaker avatar r2dliu avatar vib795 avatar villagrat avatar whusterj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

tn-spa-bootstrapper's Issues

Support No Backend Opts

I tried to start a project but did not want a backend I figured I could just delete it after it was generated however when I was going through the steps I did not select a provider for static files so it failed

ERROR: Stopping generation because pre_gen_project hook script didn't exit successfully

Maybe either add selection for no backend or set one by default if non are selected.

React client: Remove apollo-link deprecated package

apollo-link packages have been deprecated by the apollo team : https://github.com/apollographql/apollo-link

Apparently they are already including the same functionalities in their v3 (which is already part of our react client)
https://www.apollographql.com/docs/react/migrating/apollo-client-3-migration/#apollo-link-

Seems like the only change required is to replace the imports to point to:

import {createHttpLink} from '@apollo/client/link/http'
import {setContext} from '@apollo/client/link/context'

Cypress failure for maintenance mode isn't clear

Cypress is designed to stay in a failure state until it's able to run against the latest version of the code deployed on Heroku.
There error given in that failure state isn't clear:
image

We should show a custom error instead and say something like:

If this error just happened, wait a few minutes as the Heroku deployment likely hasn't finished yet.
This test will automatically re-run when the app is ready to be tested.

If this error has been here for more than a few minute, check Heroku.
There was likely an error while building/deploying the application.

Add cookie to react lib

Cookies are needed for csrf I've seen us use this one

  1. create utils/cookie.ts
export default function getCookie(cname: string): string {
  const name = cname + '='
  const decodedCookie = decodeURIComponent(document.cookie)
  const ca = decodedCookie.split(';')
  for (let i = 0; i < ca.length; i++) {
    let c = ca[i]
    while (c.charAt(0) === ' ') {
      c = c.substring(1)
    }
    if (c.indexOf(name) === 0) {
      return c.substring(name.length, c.length)
    }
  }
  return ''
}

  1. Update services/axios-instance.ts to add the cookie to the header
import getCookie from '../utils/cookie'


const csrfToken = getCookie('csrftoken')
const axiosInstance = axios.create({
  //baseUrl will be determined by the server proxy in vite.config.js
  headers: {
    'Content-Type': 'application/json',
    'X-CSRFToken': csrfToken,
  },

Add Docker Support

The Bootstrapper should support running applications under Docker. Ideally this will eliminate the need to support multiple operating systems when running the bootstrapper initialization process.

Upgrade Pillow

Change Pillow to version 9.0 to support python 3.10.5 (Heroku's 22 stack supports 3.9.13 & 3.10.5) the version 8.3.1 (in the BS) only supports up to 3.9 - there is also version 9.3 which also supports python 3.11

Cypress test example for Vue

Login and account creation now exist, so we should add Cypress test support with one or two thoughtful test examples.
For simplicity, Cypress should point at the Heroku Review App for a PR and should point to Staging when it is run against the main branch.

Add default 404 page for the Vue app

When generating a Vue/Django app with the bootstrapper, missing URL routes aren't handled correctly.
We should handle 404s properly with an acceptable default page for newly generated projects.

The `docker compose build` command fails on fresh projects, because there is no Pipfile.lock

To reproduce:

  1. Run the cookiecutter command as usual
  2. cd into your new project
  3. Run make build or docker compose build

The build will fail because Pipfile.lock does not exist.

To get Pipfile.lock to exist, you would have to run pipenv install locally, which means you have to make sure Python and pipenv are set up properly on your local. IMO this defeats the purpose of using docker to contain these dependencies.

Options to discuss:

  1. Add a Pipfile.lock - though, I think this was struck down
  2. Adjust the Dockerfile to not require Pipfile.lock

Pytest example for Django

Add Pytest support and write one or two thought tests as examples.
Should run automatically for all PRs.
These tests are for the generated project, but should be run on bootstrapper PRs as well (if we can) to validate that new bootstrapper changes don't break functionality in the generated apps.

Fix flake8 and black linting in generated projects

We have some pytest-cookies tests written for flake8 and black, but they are failing because the generated project is not compliant. Once we merge #12, we should quickly follow up with a PR fixing all the linting issues and then re-enable those tests.

React client: Add auth guard rather than using a public routes array

Rather than creating a separate array for specifying which are the public routes. We can leave public routes to be at the top of the router declaration, and add a Private routes auth guard instead. Similar to what we did in the The Drop:

Declaring private routes:

https://github.com/thinknimble/share-the-drop-web/blob/0d8be46067bfa169923f4f7506b1f6a1dc428eae/src/routes/index.tsx#L32-L89

Declaring Root Routes (thus, public)
https://github.com/thinknimble/share-the-drop-web/blob/0d8be46067bfa169923f4f7506b1f6a1dc428eae/src/routes/index.tsx#L91-L106

Drop Chakra UI from React client

I'm wondering whether having chakra-ui as default in React client is a good fit.

Feels like Chakra ui has a lot of functionalities (and overhead to learn specifics of the library itself) that many new projects might not need from the very beginning.

I see the Vue client does not have any component library as default but instead it has tailwind, which I believe is a perfect styling starter for any project.

If a given project strives for a component library then that specific project could add chakra-ui for their use.

PS: I've also had some trouble with testing components that used Chakra ( #133 has some links in the comments) so I might be a little bit triggered and biased regarding chakra, I'd love your thoughts here!

Some template tags from cookiecutter not rendering

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />

  <!-- NOTE: You can use the template tag %PUBLIC_URL% here. -->

  <!-- Standard title and description -->
  <title>SAMPLE</title>
  <meta name="description" content="SAMPLE project" />

  <!-- Favorite icons for web browsers and mobile devices -->
  <!-- Generate these using a SQUARE image at favicon-generator.org -->
  <link rel="icon" href="favicon.ico" type="image/x-icon" />
  <link rel="apple-touch-icon" sizes="57x57" href="/static/static/favicons/apple-icon-57x57.png" />
  <link rel="apple-touch-icon" sizes="60x60" href="/static/static/favicons/apple-icon-60x60.png" />
  <link rel="apple-touch-icon" sizes="72x72" href="/static/static/favicons/apple-icon-72x72.png" />
  <link rel="apple-touch-icon" sizes="76x76" href="/static/static/favicons/apple-icon-76x76.png" />
  <link rel="apple-touch-icon" sizes="114x114" href="/static/static/favicons/apple-icon-114x114.png" />
  <link rel="apple-touch-icon" sizes="120x120" href="/static/static/favicons/apple-icon-120x120.png" />
  <link rel="apple-touch-icon" sizes="144x144" href="/static/static/favicons/apple-icon-144x144.png" />
  <link rel="apple-touch-icon" sizes="152x152" href="/static/static/favicons/apple-icon-152x152.png" />
  <link rel="apple-touch-icon" sizes="180x180" href="/static/static/favicons/apple-icon-180x180.png" />
  <link rel="icon" type="image/png" sizes="192x192" href="/static/static/favicons/android-icon-192x192.png" />
  <link rel="icon" type="image/png" sizes="32x32" href="/static/static/favicons/favicon-32x32.png" />
  <link rel="icon" type="image/png" sizes="96x96" href="/static/static/favicons/favicon-96x96.png" />
  <link rel="icon" type="image/png" sizes="16x16" href="/static/static/favicons/favicon-16x16.png" />
  <link rel="manifest" href="/manifest.json" />
  <meta name="msapplication-TileColor" content="#ffffff" />
  <meta name="msapplication-TileImage" content="/ms-icon-144x144.png" />

  <!-- Theme color: Usually the app's brand color -->
  <meta name="theme-color" content="#F2615A" />

  <!-- Facebook Unfurling Meta Tags -->
  <meta property="og:type" content="website" />
  <meta property="og:url" content="%PUBLIC_URL%" />
  <meta property="og:title" content="{{ cookiecutter.project_name }}" />
  <meta property="og:description" content="Add a description for {{ cookiecutter.project_name }} in index.html!" />
  <meta property="og:image" content="%PUBLIC_URL%/static/meta-preview.png" />

  <!-- Twitter Unfurling Meta Tags -->
  <meta name="twitter:card" content="summary_large_image">
  <!-- TODO: Add the app domain here once live. -->
  <!-- <meta name="twitter:domain" value="" /> -->
  <meta name="twitter:title" value="{{ cookiecutter.project_name }}" />
  <meta name="twitter:description" value="Add a description for {{ cookiecutter.project_name }} in index.html!" />
  <meta name="twitter:image" content="%PUBLIC_URL%/static/meta-preview.png" />
  <meta name="twitter:url" value="%PUBLIC_URL%" />

  <!-- Optional: Add a Twitter handle -->
  <!-- <meta name="twitter:site" content="@MyTweets"> -->
  <script type="module" crossorigin src="/static/assets/index.ab0d53c0.js"></script>
  <link rel="stylesheet" href="/static/assets/index.dbdc8057.css">
</head>

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
  
  <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.
      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.
      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
</body>

</html>

Also quesiton is %PUBLIC_URL% supposed to render to something ?

Grapghql typo bug

Small typo leaves graphql in settings.py on the same line as another var causing a bug.

Change default variables for dev server

In all projects the backend proxy and api are served with the env variable VUE_APP_DEV_SERVER_BACKEND as this is the common verbiage we have been using lets replace this also in the axios config file

VUE_APP_DEV_SERVER_BACKEND=""

let base_url = process.env.VUE_APP_BASE_API_URL ? process.env.VUE_APP_BASE_API_URL :${window.location.protocol}//${window.location.hostname}

Update Signals

Currently the signals are imported inside the models.py according to django this is not advised.
https://docs.djangoproject.com/en/4.1/topics/signals/
One option is to import all signals in apps.py as such

class SomeAppConfig(AppConfig):
    default_auto_field = "django.db.models.BigAutoField"
    name = "some_project.some_app"

    def ready(self) -> None:
        # this import is required to register signals after the app is initialized
        # https://docs.djangoproject.com/en/4.1/topics/signals/
        import some_project.some_app.signals  # noqa

        return super().ready()

Alternatively a better approach is that you can import and connect to each signal @juliantn has an example

Remove test code and unwrap function

There was some left over test code in Home.vue that automatically tries to login a user. It was used to show the use of a custom helper called unwrap for the options api but is no longer needed

Rename This Repo?

The title says it all. Let's use this thread to brainstorm better names for this repo.

add formation to app.json

Add formation to app.json so that it does not use whatever is already on prod/staging,

  "formation": {
    "web": {
      "quantity": 1,
      "size": "free"
    }
  },

You will incur billing charges for dynos used based on the formation requested.

Move the `send_html_email` function somewhere more visible

I noticed that send_html_email is in the utils/misc.py file. I think that may lower awareness of this function too much, when we really should try to raise awareness of it. IMO, it's really, really useful and should be our default way of sending emails - everyone expects HTML emails these days. I'd recommend at least moving it to utils/emails.py or maybe even into the core Django app so it's more readily visible.

Open to suggestions. Maybe Django has a better built-in email sender nowadays?

Add favicons instructions back to the readme.md

It appears we have removed the instructions for favicons from the readme (there is a basic comment in the django route but it does not explain the process).
This is important because the urls for the favicons are hardcoded in a bootstrapped application, while we could use any favicon generator, the one that the routes are based off creates a bunch of different versions. If a user does not appropriately set up favicons and debug=False is set then the app will crash.

React Client improvements

Proposed

  • Upgrade to react 18
  • Move off of CRA in favor of Vite
  • Update Typescript version
  • Add basic .eslintrc and .prettierrc so that CI can run on this client

Moving to react 18

Unless we're using packages tied to react <18 (we can also upgrade them along with react!) we could definitely upgrade to the 18th version, it's been around for a while and seems stable enough.

Vite instead of CRA

CRA has been great for creating apps when there was no other big alternatives around, but has fallen behind both in performance and configurability compared to newer tools such as Vite.

The challenge in this step is probably set up a couple of things (such as jest, eslint) that CRA brings out of the box while Vite does not

Upgrade TS version

Typescript has just released 4.9 whereas we're using 3.9 in the project, we're a full major behind.

Hopefully this upgrade is seamless since there isn't that much code

No Heroku Bug

Error when not opting to use heroku

Traceback (most recent call last):
File "/var/folders/8k/gz24nc91754gwxlxlcvkdj80000gn/T/tmpy81uyn_.py", line 423, in
main()
File "/var/folders/8k/gz24nc91754gwxlxlcvkdj80000gn/T/tmpy81uyn_.py", line 262, in main
remove_heroku_files()
File "/var/folders/8k/gz24nc91754gwxlxlcvkdj80000gn/T/tmpy81uyn_.py", line 103, in remove_heroku_files
os.remove(file_name)

Jest unit test support for Vue

Add Jest support and write one or two thoughtful tests as examples.
Should run automatically for all PRs.
These tests are for the generated project, but should be run on bootstrapper PRs as well to validate that new bootstrapper changes don't break functionality in the generated apps.

Add index to view

Looks like the server is not serving index.html generated from the client.
`

        def index(request):
            {% if cookiecutter.client_app.lower() == 'None' %}
            return redirect(to="/docs/swagger/")
            {% else %}
            return render(request,'core/index-placeholder.html')
            {% endif %}

`

Remove tn-validators dependency

@thinknimble/tn-validators is still listed as a dependency for the project that the bootstrapper generates.
Pretty sure it's not used and can just be removed.

  • Remove the dependency
  • Confirm nothing breaks

Vue token management should be refactored

Per comments on #61

"I would suggest separating token management from the user model. I think it could potentially be dangerous to include an auth token in user payloads separate from authentication workflows. It just increases the likelihood that an auth token might show up in an API endpoint where it doesn't belong.

I'd also then create store actions for obtaining a token, verifying a token, and for logout. The /verify endpoint and action are especially necessary if using tokens that can expire - like JWTs - which need to be periodically renewed.
...
You also need to consider the case where an auth-protected page is accessed from an external link or page refresh. There might be a user in the store, but you should validate their API token and redirect them before showing the page.
...
I used a convenient composable that effectively added a layer of extra code but made it easier to use the store and not have to call commit/dispatch on each store mutation/action. It also meant I didn't have to keep importing the whole store, instead I would just import the constants I would need.
One caveat is it wont work in a regular js file so in the axios you still import the store but everywhere else you can just import the composable and declare the constants you want to use."

Run linting against all possible versions of project generation

Eventually it would be nice to run tests as well but a low hanging fruit is just linting so we can catch issues related to if/else cookiecutter blocks.
The idea here being that we generate X number of projects in Github Actions. Just generating the code in separate folders. Then run the linters against those folders.
This will help us catch issues where linting is fine, unless you answer yes/no to a certain step and then injected code has a linting problem.

Newly bootstrapped projects should not have CI/CD errors on day 1.

Admin Panel Core Model

Current implementation is broken (creating and setting passwords does so without the hashing algorithm), login authentication fails

TODO:

  • Copy from another project

Upgrade clients to Node 18 and upgrade packages

Our React and Vue apps currently use Node 14 and a corresponding NPM version. We should bump this up to something more recent like Node 18 and fix any corresponding package issues (node-sass usually has trouble with node version upgrades).

Auto-Generated Documentation

Discussion thread about auto-generating documentation.

What are the possible cases?

  1. Generating API Documentation (most immediately useful, we like Swagger for this)
  2. Generating Documentation about .env files
  3. Generating Documentation for local commands

What are the possible tools?

  • Static MD files
  • Sphinx
  • Read-the-docs (?)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.