
# VUEX STORE MODULES

Locate in folder:
```
./store/modules/*
```

Module filename must be in **plural lower Camel case**.

Example:

```
productCategories.js
```

In order to use vuex modules in your components, use dependencies option.

Example:
```
export default {
    name: 'AttributeList',
    
    dependencies: ['attributeGroups'],
    
    // ...
}
```


## Actions, getters and mutations
Module factory automagically create actions, getters and mutations. Here an example of getters, actions and mutations created with a `products` module.

### Actions
**fetchProducts( fetchOptions )**
 - {boolean} fetchOptions.force - *Used to force a fetch of products even if they are all fetched*
 - {boolean} fetchOptions.criteria - *Module shoul have integral option at false to use backend search criteria*

**getProduct( id )**
 - {Number} id - *Can be product id OR payload with id and force params {id: 2, force: true}. use force to fetch of product even if it is already fetched*

**loadProduct( params )**
 - {Number} params.id - *Load the product if all products are fetched OR if this product is already in the store*
 - {Function} params.callback - *Callback executed after fetch or even if fetch is not executed*

**storeProduct( payload )**
 - {object} payload - *Payload of the new product*

**updateProduct( payload )**
 - {object} payload - *Payload must contain the product id*

**destroyProduct( payload )**
 - {object} payload - *Payload must contain the product id*

### Getters
**getProducts( )**
*return full set of fetched products*

getProductById( id )
*return the product corresponding this id OR null*


### Mutations
**PRODUCTS_LOADED**

**PRODUCT_LOADED**

**NEW_PRODUCT**

**UPDATE_PRODUCT**

**DELETE_PRODUCT**


## How to create a store
**Simple example for a product store**

File name should be: ```store/modules/products.js```
```
import Product from 'models/Product'

export const config = {
  moduleName: 'product', // singular name of module in snakecase
  model: Product
}
```

**Attribute complexe example with nested AttributeValue entities**

File name should be: ```store/modules/attributes.js```
```
import Attribute from 'models/Attribute'
import AttributeValue from 'models/AttributeValue'

export const config = {
  moduleName: 'attribute',
  model: Attribute,
  namespaced: false, // vuex namespaced option
  addEchoListener: true,
  getters: {
    getAttributeOfGroup: state => id => {
      return _.filter(state.items, {attribute_group_id: id !== null ? new Number(id) : null})
    }
  },
  hasMany: {
    attribute_value: {
      model: AttributeValue,
      mainModelAttribute: 'attribute_values',
      parentIdProp: 'attribute_id'
    }
  }
}
```

**Basic vuex example that not using factory** 

File name should be: ```store/modules/warehouseCarts.js```
```
export default {
  state: {
    // ...
  },

  getters: {
    // ...
  },

  actions: {
    // ...
  },

  mutations: {
    // ...
  }
}
```

## Store factory available parameters
### mandatory parameters
**moduleName**

singular name of module in snakecase (product, attribute_group, ...).

**model**
 - {LaravelModel} - See `models/info.md`

### optional parameters
**namespaced**
 - {boolean} default: false 
 
    Vuex option to register getters, actions and mutations in different namespace based on the path the module is registered.
For more informations view -> [Vuex modules](https://vuex.vuejs.org/guide/modules.html). 

**addEchoListener**
 - {boolean} default: true
 
   To add pusher event listening.

**integral**
 - {boolean} default: true
 
   To prevent store to load all items. Set this option to false when the store payload is too big. Ex. 1000 products and more. 
 
 **actions**
 - {object}

   To add custom actions.
 
 **getters**
 - {object}

   To add custom getters.

 **mutations**
 - {object}

   To add custom mutations.

**subscribe**
  - {function}

  To subscribe custum vuex plugins. For more informations view -> [vuex plugins](https://vuex.vuejs.org/guide/plugins.html)

**customEchoListener($store, clientId)**
  To create custom echo listener. Example:
  ```
  import Model from 'models/MyModel'

  export const config = {
    moduleName: 'module_name',
    model: MyModel,
    customEchoListener: ($store, clientId) => {
      Bus.$on(`created-${MyModel.resourceName}`, payload => {
          $store.commit(`NEW_MODEL`, payload)
          Bus.$emit(`NEW_MODEL`, payload)
      })
    },
    ...
  }
  ```
