Skip to content

The web interface for everyone's favorite prescribed burn monitoring UAV

Notifications You must be signed in to change notification settings

Underwaterr/hello-decco

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

627 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hello Decco

Welcome to Hello Decco!

Project Style Guide

Follow these guidelines to implement global styling and keep a consistent aesthetic throughout the product.

Vite and preprocessing

Global styling sheets are in the following structure:

├── src
│   ...
├── scss
│   ├──_variables.scss
|   ├──fonts.scss
|   ├──global.scss
|   ├──style.scss
|   ├──mixins/
│   │   └── **mixin files
|   |
|   ...

Vite is configured to preprocess Sass files and inject the content of global.scss into every Sass file processed. This ensures that the styles defined in global.scss are available globally throughout the project.

global.scss imports and consolidates all of the other files in this directory. To add a new global styling sheet, make sure to import it into global.scss.

Global variables and mixins

Variables

  • $brand-NAME OF COLOR : naming convention for brand guide colors and variations
  • $color-APPLICATION OF COLOR : naming convention for secondary colors
  • $gradient-APPLICATION OF GRADIENT : naming convention for gradients

Mixins can be created for needs that may be repeated. When applicable, use existing mixins to maintain consistency.

All variables and mixins are injected globally into every scss file Vite touches. That means they are available all the way to the component level as long as the language is set to 'scss'.

Global Fonts

Fonts are assigned to HTML elements in the fonts.scss file. These are globally assigned. In the rare case you need to customize a font for a particular component, create a new global class in style.scss and assign the font in fonts.scss

Global Classes

Global and default stylings are set in style.scss. These are applied directly to HTML Elements:

button {
  padding: 0.25rem;
  outline: 0;
  display: inline-block;
  text-align: center;
  border-radius: .25rem;
  transition:
    color .15s ease-in-out,
    background-color .15s ease-in-out,
    border-color .15s ease-in-out,
    box-shadow .15s ease-in-out;
  color: black;
  background-color: white;
}

and to custom classes:

.command {
  border: 2px solid $color-warning-accent;
}

If a design element is being reused over several components and needs to be stylistically consistent, a global class should be created and applied.

Layout

  • .move-right : align contents to the right
  • .move-center : align contents to the center
  • .column: align contents in a column
  • .sticky-header : creates a static header at the top of the container that will remain visible while scrolling
  • #modal : absolutely positioned overlay at the top of the view window
  • .dashboard-panel : a styled divider for grouped elements on the dashboard

Buttons

There are global styles for buttons that will be applied to all HTML buttons. There are also some applicable classes:

  • .command : custom class for buttons that send direct commands to the drone. These are marked with warning colors.
  • .select : custom class for buttons that are part of a list of items to select from.

Unique Components

  • .console : a display to mimic a terminal window
  • .table : consistent styling for a table element
  • .burn-unit-map-label : any kind of permanent label on the map associated with a burn unit

Overriding Global Styles

If you need to customize the global styles for a specific component or section, you can override the global styles locally. To do this, follow these steps:

  1. Identify the specific global class you want to override.
  2. Create a new class or apply styles directly to the HTML element within the component or section.
  3. Add the necessary CSS rules to override the global styles.
  4. Ensure that the local modifications are scoped to the component or section to avoid unintended impacts on other parts of the project.

Example:

<!-- Override table background color locally -->
table.table.my-custom-table
  <!-- Table content -->

Testing

Running Tests

We use vitest for testing. Follow the steps below to run the tests:

  1. Open a terminal and navigate to the project root directory.

  2. Run the following command:

    npm test

    This will execute the tests and display the results and the coverage in the terminal.

    If you are writing new tests and would like vitest to enter a watch mode that waits for file changes and reruns the relevant tests, set watch to true in the vite.config.js:

    //...
     test: {
         coverage: {
             enabled: true,
             provider: 'istanbul'
         },
         environment: 'jsdom',
         globals: true,
         watch: false,
     }
     //additional config...

Writing Tests

Tests are written using the vitest testing framework. Follow these steps to create new tests:

  1. Navigate to the src/__tests__ directory.

  2. Follow the file structure of the main app.

  3. Create a new test file, for example, MyComponent.spec.js.

  4. Write your test cases. The vitest suite of tools is available globally, so there's no need to import them. They are very similar to Jest tools. See the docs here.

    The vue test-utils give the ability to mount a single component in a local Vue instance. The createApp method creates a new, empty local instance and then we can mount the desired component to it with the mount method.

    The pinia instance allows us to create a clean, isolated pinia instance for testing. Here's an example of a basic test file:

    import { mount } from '@vue/test-utils'
     import { createTestingPinia } from '@pinia/testing'
     import { createApp } from 'vue';
    
     import Login from '@/components/Login/Login.vue'
    
     let localVue = createApp({ template: '<div></div>' })
    
     let pinia = createTestingPinia()
    
     let wrapper = mount(Login, { localVue })
    
     describe('Authentication flow', () => {
         test('initializes displays login page', () => {
         let loginForm = wrapper.find('#login')
         expect(loginForm.exists()).toBe(true)
         })
     })

    Tests for pinia stores act a little different. You actually import the store like in a component and then the setActivePinia method creates a fresh pinia instance for each block of tests.

    Here's an example of a basic test file for a pinia store:

     import { setActivePinia, createPinia } from 'pinia'
     import { useUserStore } from '../../stores/UserStore'
    
     describe('User Store', () => {
         let userStore
     
         beforeEach(() => {
         // creates a fresh pinia and makes it active
         // so it's automatically picked up by any useStore() call
         setActivePinia(createPinia())
         userStore = useUserStore()    
         })
    
         it('initializes', () => {
             expect(userStore.isLoggedIn).toBe(null)
             expect(userStore.email).toBe(null)
         })
    
         it('logs in', () => {
             userStore.logIn()
             expect(userStore.isLoggedIn).toBe(true)
             expect(userStore.email).toBe(null)
         })
    
         it('logs out', () => {
             userStore.logIn()
             userStore.logOut()
             expect(userStore.isLoggedIn).toBe(false)
             expect(userStore.email).toBe(null)
         })
     })

About

The web interface for everyone's favorite prescribed burn monitoring UAV

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 59.0%
  • Vue 31.8%
  • SCSS 5.5%
  • CSS 3.3%
  • Other 0.4%