Commit cc76259e authored by Marcel Amirault's avatar Marcel Amirault Committed by Marcia Ramos

Fix whitespace in ci docs

Many code blocks are 4spaced, and they render in GitLab
without coloring as a result, even though they are
fenced with a language label. If in a list, other items
will render as being in a code block too, even if not
meant to. This fixes all these issues for most docs in
/development, and cleans up other whitespace issues too
parent e7d9d32a
...@@ -111,18 +111,18 @@ For example, if you were to move `doc/workflow/lfs/lfs_administration.md` to ...@@ -111,18 +111,18 @@ For example, if you were to move `doc/workflow/lfs/lfs_administration.md` to
1. Copy `doc/workflow/lfs/lfs_administration.md` to `doc/administration/lfs.md` 1. Copy `doc/workflow/lfs/lfs_administration.md` to `doc/administration/lfs.md`
1. Replace the contents of `doc/workflow/lfs/lfs_administration.md` with: 1. Replace the contents of `doc/workflow/lfs/lfs_administration.md` with:
```md ```md
This document was moved to [another location](../../administration/lfs.md). This document was moved to [another location](../../administration/lfs.md).
``` ```
1. Find and replace any occurrences of the old location with the new one. 1. Find and replace any occurrences of the old location with the new one.
A quick way to find them is to use `git grep`. First go to the root directory A quick way to find them is to use `git grep`. First go to the root directory
where you cloned the `gitlab-ce` repository and then do: where you cloned the `gitlab-ce` repository and then do:
```sh ```sh
git grep -n "workflow/lfs/lfs_administration" git grep -n "workflow/lfs/lfs_administration"
git grep -n "lfs/lfs_administration" git grep -n "lfs/lfs_administration"
``` ```
NOTE: **Note:** NOTE: **Note:**
If the document being moved has any Disqus comments on it, there are extra steps If the document being moved has any Disqus comments on it, there are extra steps
...@@ -296,45 +296,45 @@ You can combine one or more of the following: ...@@ -296,45 +296,45 @@ You can combine one or more of the following:
1. **Linking to an anchor link.** Use `anchor` as part of the `help_page_path` 1. **Linking to an anchor link.** Use `anchor` as part of the `help_page_path`
method: method:
```haml ```haml
= link_to 'Help page', help_page_path('user/permissions', anchor: 'anchor-link') = link_to 'Help page', help_page_path('user/permissions', anchor: 'anchor-link')
``` ```
1. **Opening links in a new tab.** This should be the default behavior: 1. **Opening links in a new tab.** This should be the default behavior:
```haml ```haml
= link_to 'Help page', help_page_path('user/permissions'), target: '_blank' = link_to 'Help page', help_page_path('user/permissions'), target: '_blank'
``` ```
1. **Linking to a circle icon.** Usually used in settings where a long 1. **Linking to a circle icon.** Usually used in settings where a long
description cannot be used, like near checkboxes. You can basically use description cannot be used, like near checkboxes. You can basically use
any font awesome icon, but prefer the `question-circle`: any font awesome icon, but prefer the `question-circle`:
```haml ```haml
= link_to icon('question-circle'), help_page_path('user/permissions') = link_to icon('question-circle'), help_page_path('user/permissions')
``` ```
1. **Using a button link.** Useful in places where text would be out of context 1. **Using a button link.** Useful in places where text would be out of context
with the rest of the page layout: with the rest of the page layout:
```haml ```haml
= link_to 'Help page', help_page_path('user/permissions'), class: 'btn btn-info' = link_to 'Help page', help_page_path('user/permissions'), class: 'btn btn-info'
``` ```
1. **Using links inline of some text.** 1. **Using links inline of some text.**
```haml ```haml
Description to #{link_to 'Help page', help_page_path('user/permissions')}. Description to #{link_to 'Help page', help_page_path('user/permissions')}.
``` ```
1. **Adding a period at the end of the sentence.** Useful when you don't want 1. **Adding a period at the end of the sentence.** Useful when you don't want
the period to be part of the link: the period to be part of the link:
```haml ```haml
= succeed '.' do = succeed '.' do
Learn more in the Learn more in the
= link_to 'Help page', help_page_path('user/permissions') = link_to 'Help page', help_page_path('user/permissions')
``` ```
### GitLab `/help` tests ### GitLab `/help` tests
......
...@@ -36,8 +36,8 @@ For the Troubleshooting sections, people in GitLab Support can merge additions t ...@@ -36,8 +36,8 @@ For the Troubleshooting sections, people in GitLab Support can merge additions t
Include any media types/sources if the content is relevant to readers. You can freely include or link presentations, diagrams, videos, etc.; no matter who it was originally composed for, if it is helpful to any of our audiences, we can include it. Include any media types/sources if the content is relevant to readers. You can freely include or link presentations, diagrams, videos, etc.; no matter who it was originally composed for, if it is helpful to any of our audiences, we can include it.
- If you use an image that has a separate source file (for example, a vector or diagram format), link the image to the source file so that it may be reused or updated by anyone. - If you use an image that has a separate source file (for example, a vector or diagram format), link the image to the source file so that it may be reused or updated by anyone.
- Do not copy and paste content from other sources unless it is a limited quotation with the source cited. Typically it is better to either rephrase relevant information in your own words or link out to the other source. - Do not copy and paste content from other sources unless it is a limited quotation with the source cited. Typically it is better to either rephrase relevant information in your own words or link out to the other source.
### No special types ### No special types
...@@ -237,14 +237,14 @@ Do not include the same information in multiple places. [Link to a SSOT instead. ...@@ -237,14 +237,14 @@ Do not include the same information in multiple places. [Link to a SSOT instead.
- Use sentence case for titles, headings, labels, menu items, and buttons. - Use sentence case for titles, headings, labels, menu items, and buttons.
- Insert an empty line between different markups (e.g., after every paragraph, header, list, etc). Example: - Insert an empty line between different markups (e.g., after every paragraph, header, list, etc). Example:
```md ```md
## Header ## Header
Paragraph. Paragraph.
- List item 1 - List item 1
- List item 2 - List item 2
``` ```
### Tables overlapping the TOC ### Tables overlapping the TOC
...@@ -303,12 +303,12 @@ Check specific punctuation rules for [list items](#list-items) below. ...@@ -303,12 +303,12 @@ Check specific punctuation rules for [list items](#list-items) below.
- Be consistent throughout the list: if the majority of the items do not end in a period, do not end any of the items in a period, even if they consist of a complete sentence. The opposite is also valid: if the majority of the items end with a period, end all with a period. - Be consistent throughout the list: if the majority of the items do not end in a period, do not end any of the items in a period, even if they consist of a complete sentence. The opposite is also valid: if the majority of the items end with a period, end all with a period.
- Separate list items from explanatory text with a colon (`:`). For example: - Separate list items from explanatory text with a colon (`:`). For example:
```md ```md
The list is as follows: The list is as follows:
- First item: this explains the first item. - First item: this explains the first item.
- Second item: this explains the second item. - Second item: this explains the second item.
``` ```
**Examples:** **Examples:**
...@@ -520,16 +520,16 @@ To embed a video, follow the instructions below and make sure ...@@ -520,16 +520,16 @@ To embed a video, follow the instructions below and make sure
you have your MR reviewed and approved by a technical writer. you have your MR reviewed and approved by a technical writer.
1. Copy the code below and paste it into your markdown file. 1. Copy the code below and paste it into your markdown file.
Leave a blank line above and below it. Do NOT edit the code Leave a blank line above and below it. Do NOT edit the code
(don't remove or add any spaces, etc). (don't remove or add any spaces, etc).
1. On YouTube, visit the video URL you want to display. Copy 1. On YouTube, visit the video URL you want to display. Copy
the regular URL from your browser (`https://www.youtube.com/watch?v=VIDEO-ID`) the regular URL from your browser (`https://www.youtube.com/watch?v=VIDEO-ID`)
and replace the video title and link in the line under `<div class="video-fallback">`. and replace the video title and link in the line under `<div class="video-fallback">`.
1. On YouTube, click **Share**, then **Embed**. 1. On YouTube, click **Share**, then **Embed**.
1. Copy the `<iframe>` source (`src`) **URL only** 1. Copy the `<iframe>` source (`src`) **URL only**
(`https://www.youtube.com/embed/VIDEO-ID`), (`https://www.youtube.com/embed/VIDEO-ID`),
and paste it, replacing the content of the `src` field in the and paste it, replacing the content of the `src` field in the
`iframe` tag. `iframe` tag.
```html ```html
leave a blank line here leave a blank line here
...@@ -611,7 +611,7 @@ In most cases, content considered for a note should be included: ...@@ -611,7 +611,7 @@ In most cases, content considered for a note should be included:
#### When to use #### When to use
Use a note when there is a reason that most or all readers who browse the Use a note when there is a reason that most or all readers who browse the
section should see the content. That is, if missed, it’s likely to cause section should see the content. That is, if missed, it’s likely to cause
major trouble for a minority of users or significant trouble for a majority major trouble for a minority of users or significant trouble for a majority
of users. of users.
...@@ -747,24 +747,24 @@ a helpful link back to how the feature was developed. ...@@ -747,24 +747,24 @@ a helpful link back to how the feature was developed.
- For features that need to declare the GitLab version that the feature was introduced. Text similar - For features that need to declare the GitLab version that the feature was introduced. Text similar
to the following should be added immediately below the heading as a blockquote: to the following should be added immediately below the heading as a blockquote:
```md ```md
> Introduced in GitLab 11.3. > Introduced in GitLab 11.3.
``` ```
- Whenever possible, version text should have a link to the issue, merge request, or epic that introduced the feature. - Whenever possible, version text should have a link to the issue, merge request, or epic that introduced the feature.
An issue is preferred over a merge request, and a merge request is preferred over an epic. For example: An issue is preferred over a merge request, and a merge request is preferred over an epic. For example:
```md ```md
> [Introduced](<link-to-issue>) in GitLab 11.3. > [Introduced](<link-to-issue>) in GitLab 11.3.
``` ```
- If the feature is only available in GitLab Enterprise Edition, mention - If the feature is only available in GitLab Enterprise Edition, mention
the [paid tier](https://about.gitlab.com/handbook/marketing/product-marketing/#tiers) the [paid tier](https://about.gitlab.com/handbook/marketing/product-marketing/#tiers)
the feature is available in: the feature is available in:
```md ```md
> [Introduced](<link-to-issue>) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.3. > [Introduced](<link-to-issue>) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.3.
``` ```
### Removing version text ### Removing version text
...@@ -871,14 +871,14 @@ When there is a list of steps to perform, usually that entails editing the ...@@ -871,14 +871,14 @@ When there is a list of steps to perform, usually that entails editing the
configuration file and reconfiguring/restarting GitLab. In such case, follow configuration file and reconfiguring/restarting GitLab. In such case, follow
the style below as a guide: the style below as a guide:
```md ````md
**For Omnibus installations** **For Omnibus installations**
1. Edit `/etc/gitlab/gitlab.rb`: 1. Edit `/etc/gitlab/gitlab.rb`:
```ruby ```ruby
external_url "https://gitlab.example.com" external_url "https://gitlab.example.com"
``` ```
1. Save the file and [reconfigure] GitLab for the changes to take effect. 1. Save the file and [reconfigure] GitLab for the changes to take effect.
...@@ -888,17 +888,16 @@ the style below as a guide: ...@@ -888,17 +888,16 @@ the style below as a guide:
1. Edit `config/gitlab.yml`: 1. Edit `config/gitlab.yml`:
```yaml ```yaml
gitlab: gitlab:
host: "gitlab.example.com" host: "gitlab.example.com"
``` ```
1. Save the file and [restart] GitLab for the changes to take effect. 1. Save the file and [restart] GitLab for the changes to take effect.
[reconfigure]: path/to/administration/restart_gitlab.md#omnibus-gitlab-reconfigure [reconfigure]: path/to/administration/restart_gitlab.md#omnibus-gitlab-reconfigure
[restart]: path/to/administration/restart_gitlab.md#installations-from-source [restart]: path/to/administration/restart_gitlab.md#installations-from-source
``` ````
In this case: In this case:
...@@ -917,9 +916,9 @@ on this document. Further explanation is given below. ...@@ -917,9 +916,9 @@ on this document. Further explanation is given below.
- Every method must have the REST API request. For example: - Every method must have the REST API request. For example:
``` ```
GET /projects/:id/repository/branches GET /projects/:id/repository/branches
``` ```
- Every method must have a detailed - Every method must have a detailed
[description of the parameters](#method-description). [description of the parameters](#method-description).
...@@ -971,7 +970,7 @@ You can use the following fake tokens as examples. ...@@ -971,7 +970,7 @@ You can use the following fake tokens as examples.
| Token type | Token value | | Token type | Token value |
|:----------------------|:-------------------------------------------------------------------| |:----------------------|:-------------------------------------------------------------------|
| Private user token | `<your_access_token>` | | Private user token | `<your_access_token>` |
| Personal access token | `n671WNGecHugsdEDPsyo` | | Personal access token | `n671WNGecHugsdEDPsyo` |
| Application ID | `2fcb195768c39e9a94cec2c2e32c59c0aad7a3365c10892e8116b5d83d4096b6` | | Application ID | `2fcb195768c39e9a94cec2c2e32c59c0aad7a3365c10892e8116b5d83d4096b6` |
| Application secret | `04f294d1eaca42b8692017b426d53bbc8fe75f827734f0260710b83a556082df` | | Application secret | `04f294d1eaca42b8692017b426d53bbc8fe75f827734f0260710b83a556082df` |
......
...@@ -14,28 +14,29 @@ See also the [corresponding UX guide](https://design.gitlab.com/#/components/dro ...@@ -14,28 +14,29 @@ See also the [corresponding UX guide](https://design.gitlab.com/#/components/dro
1. Use the HTML structure provided by the [docs][bootstrap-dropdowns] 1. Use the HTML structure provided by the [docs][bootstrap-dropdowns]
1. Add a specific class to the top level `.dropdown` element 1. Add a specific class to the top level `.dropdown` element
```Haml ```Haml
.dropdown.my-dropdown .dropdown.my-dropdown
%button{ type: 'button', data: { toggle: 'dropdown' }, 'aria-haspopup': true, 'aria-expanded': false } %button{ type: 'button', data: { toggle: 'dropdown' }, 'aria-haspopup': true, 'aria-expanded': false }
%span.dropdown-toggle-text %span.dropdown-toggle-text
Toggle Dropdown Toggle Dropdown
= icon('chevron-down') = icon('chevron-down')
%ul.dropdown-menu %ul.dropdown-menu
%li %li
%a %a
item! item!
``` ```
Or use the helpers Or use the helpers
```Haml
.dropdown.my-dropdown ```Haml
= dropdown_toggle('Toogle!', { toggle: 'dropdown' }) .dropdown.my-dropdown
= dropdown_content = dropdown_toggle('Toogle!', { toggle: 'dropdown' })
%li = dropdown_content
%a %li
item! %a
``` item!
```
[bootstrap-dropdowns]: https://getbootstrap.com/docs/3.3/javascript/#dropdowns [bootstrap-dropdowns]: https://getbootstrap.com/docs/3.3/javascript/#dropdowns
......
...@@ -30,8 +30,8 @@ To improve the time to first render we are using lazy loading for images. This w ...@@ -30,8 +30,8 @@ To improve the time to first render we are using lazy loading for images. This w
the actual image source on the `data-src` attribute. After the HTML is rendered and JavaScript is loaded, the actual image source on the `data-src` attribute. After the HTML is rendered and JavaScript is loaded,
the value of `data-src` will be moved to `src` automatically if the image is in the current viewport. the value of `data-src` will be moved to `src` automatically if the image is in the current viewport.
- Prepare images in HTML for lazy loading by renaming the `src` attribute to `data-src` AND adding the class `lazy`. - Prepare images in HTML for lazy loading by renaming the `src` attribute to `data-src` AND adding the class `lazy`.
- If you are using the Rails `image_tag` helper, all images will be lazy-loaded by default unless `lazy: false` is provided. - If you are using the Rails `image_tag` helper, all images will be lazy-loaded by default unless `lazy: false` is provided.
If you are asynchronously adding content which contains lazy images then you need to call the function If you are asynchronously adding content which contains lazy images then you need to call the function
`gl.lazyLoader.searchLazyImages()` which will search for lazy images and load them if needed. `gl.lazyLoader.searchLazyImages()` which will search for lazy images and load them if needed.
...@@ -96,26 +96,26 @@ bundle and included on the page. ...@@ -96,26 +96,26 @@ bundle and included on the page.
DOM has loaded, you should attach an event handler to the `DOMContentLoaded` DOM has loaded, you should attach an event handler to the `DOMContentLoaded`
event with: event with:
```javascript ```javascript
import initMyWidget from './my_widget'; import initMyWidget from './my_widget';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initMyWidget(); initMyWidget();
}); });
``` ```
- **Supporting Module Placement:** - **Supporting Module Placement:**
- If a class or a module is _specific to a particular route_, try to locate - If a class or a module is _specific to a particular route_, try to locate
it close to the entry point it will be used. For instance, if it close to the entry point it will be used. For instance, if
`my_widget.js` is only imported within `pages/widget/show/index.js`, you `my_widget.js` is only imported within `pages/widget/show/index.js`, you
should place the module at `pages/widget/show/my_widget.js` and import it should place the module at `pages/widget/show/my_widget.js` and import it
with a relative path (e.g. `import initMyWidget from './my_widget';`). with a relative path (e.g. `import initMyWidget from './my_widget';`).
- If a class or module is _used by multiple routes_, place it within a - If a class or module is _used by multiple routes_, place it within a
shared directory at the closest common parent directory for the entry shared directory at the closest common parent directory for the entry
points that import it. For example, if `my_widget.js` is imported within points that import it. For example, if `my_widget.js` is imported within
both `pages/widget/show/index.js` and `pages/widget/run/index.js`, then both `pages/widget/show/index.js` and `pages/widget/run/index.js`, then
place the module at `pages/widget/shared/my_widget.js` and import it with place the module at `pages/widget/shared/my_widget.js` and import it with
a relative path if possible (e.g. `../shared/my_widget`). a relative path if possible (e.g. `../shared/my_widget`).
- **Enterprise Edition Caveats:** - **Enterprise Edition Caveats:**
For GitLab Enterprise Edition, page-specific entry points will override their For GitLab Enterprise Edition, page-specific entry points will override their
...@@ -161,7 +161,7 @@ General tips: ...@@ -161,7 +161,7 @@ General tips:
- Use code-splitting dynamic imports wherever possible to lazy-load code that is not needed initially. - Use code-splitting dynamic imports wherever possible to lazy-load code that is not needed initially.
- [High Performance Animations][high-perf-animations] - [High Performance Animations][high-perf-animations]
------- ---
## Additional Resources ## Additional Resources
......
This diff is collapsed.
# Vuex # Vuex
To manage the state of an application you should use [Vuex][vuex-docs]. To manage the state of an application you should use [Vuex][vuex-docs].
_Note:_ All of the below is explained in more detail in the official [Vuex documentation][vuex-docs]. _Note:_ All of the below is explained in more detail in the official [Vuex documentation][vuex-docs].
## Separation of concerns ## Separation of concerns
Vuex is composed of State, Getters, Mutations, Actions and Modules. Vuex is composed of State, Getters, Mutations, Actions and Modules.
When a user clicks on an action, we need to `dispatch` it. This action will `commit` a mutation that will change the state. When a user clicks on an action, we need to `dispatch` it. This action will `commit` a mutation that will change the state.
_Note:_ The action itself will not update the state, only a mutation should update the state. _Note:_ The action itself will not update the state, only a mutation should update the state.
## File structure ## File structure
When using Vuex at GitLab, separate this concerns into different files to improve readability: When using Vuex at GitLab, separate this concerns into different files to improve readability:
``` ```
...@@ -21,10 +24,12 @@ When using Vuex at GitLab, separate this concerns into different files to improv ...@@ -21,10 +24,12 @@ When using Vuex at GitLab, separate this concerns into different files to improv
├── state.js # state ├── state.js # state
└── mutation_types.js # mutation types └── mutation_types.js # mutation types
``` ```
The following example shows an application that lists and adds users to the state. The following example shows an application that lists and adds users to the state.
(For a more complex example implementation take a look at the security applications store in [here](https://gitlab.com/gitlab-org/gitlab-ee/tree/master/ee/app/assets/javascripts/vue_shared/security_reports/store)) (For a more complex example implementation take a look at the security applications store in [here](https://gitlab.com/gitlab-org/gitlab-ee/tree/master/ee/app/assets/javascripts/vue_shared/security_reports/store))
### `index.js` ### `index.js`
This is the entry point for our store. You can use the following as a guide: This is the entry point for our store. You can use the following as a guide:
```javascript ```javascript
...@@ -47,6 +52,7 @@ export default createStore(); ...@@ -47,6 +52,7 @@ export default createStore();
``` ```
### `state.js` ### `state.js`
The first thing you should do before writing any code is to design the state. The first thing you should do before writing any code is to design the state.
Often we need to provide data from haml to our Vue application. Let's store it in the state for better access. Often we need to provide data from haml to our Vue application. Let's store it in the state for better access.
...@@ -66,9 +72,11 @@ Often we need to provide data from haml to our Vue application. Let's store it i ...@@ -66,9 +72,11 @@ Often we need to provide data from haml to our Vue application. Let's store it i
``` ```
#### Access `state` properties #### Access `state` properties
You can use `mapState` to access state properties in the components. You can use `mapState` to access state properties in the components.
### `actions.js` ### `actions.js`
An action is a payload of information to send data from our application to our store. An action is a payload of information to send data from our application to our store.
An action is usually composed by a `type` and a `payload` and they describe what happened. An action is usually composed by a `type` and a `payload` and they describe what happened.
...@@ -110,6 +118,7 @@ In this file, we will write the actions that will call the respective mutations: ...@@ -110,6 +118,7 @@ In this file, we will write the actions that will call the respective mutations:
``` ```
#### Actions Pattern: `request` and `receive` namespaces #### Actions Pattern: `request` and `receive` namespaces
When a request is made we often want to show a loading state to the user. When a request is made we often want to show a loading state to the user.
Instead of creating an action to toggle the loading state and dispatch it in the component, Instead of creating an action to toggle the loading state and dispatch it in the component,
...@@ -136,6 +145,7 @@ By following this pattern we guarantee: ...@@ -136,6 +145,7 @@ By following this pattern we guarantee:
1. Actions are simple and straightforward 1. Actions are simple and straightforward
#### Dispatching actions #### Dispatching actions
To dispatch an action from a component, use the `mapActions` helper: To dispatch an action from a component, use the `mapActions` helper:
```javascript ```javascript
...@@ -154,6 +164,7 @@ import { mapActions } from 'vuex'; ...@@ -154,6 +164,7 @@ import { mapActions } from 'vuex';
``` ```
### `mutations.js` ### `mutations.js`
The mutations specify how the application state changes in response to actions sent to the store. The mutations specify how the application state changes in response to actions sent to the store.
The only way to change state in a Vuex store should be by committing a mutation. The only way to change state in a Vuex store should be by committing a mutation.
...@@ -193,6 +204,7 @@ Remember that actions only describe that something happened, they don't describe ...@@ -193,6 +204,7 @@ Remember that actions only describe that something happened, they don't describe
``` ```
### `getters.js` ### `getters.js`
Sometimes we may need to get derived state based on store state, like filtering for a specific prop. Sometimes we may need to get derived state based on store state, like filtering for a specific prop.
Using a getter will also cache the result based on dependencies due to [how computed props work](https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods) Using a getter will also cache the result based on dependencies due to [how computed props work](https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods)
This can be done through the `getters`: This can be done through the `getters`:
...@@ -219,6 +231,7 @@ import { mapGetters } from 'vuex'; ...@@ -219,6 +231,7 @@ import { mapGetters } from 'vuex';
``` ```
### `mutation_types.js` ### `mutation_types.js`
From [vuex mutations docs][vuex-mutations]: From [vuex mutations docs][vuex-mutations]:
> It is a commonly seen pattern to use constants for mutation types in various Flux implementations. This allows the code to take advantage of tooling like linters, and putting all constants in a single file allows your collaborators to get an at-a-glance view of what mutations are possible in the entire application. > It is a commonly seen pattern to use constants for mutation types in various Flux implementations. This allows the code to take advantage of tooling like linters, and putting all constants in a single file allows your collaborators to get an at-a-glance view of what mutations are possible in the entire application.
...@@ -227,6 +240,7 @@ export const ADD_USER = 'ADD_USER'; ...@@ -227,6 +240,7 @@ export const ADD_USER = 'ADD_USER';
``` ```
### How to include the store in your application ### How to include the store in your application
The store should be included in the main component of your application: The store should be included in the main component of your application:
```javascript ```javascript
...@@ -241,6 +255,7 @@ The store should be included in the main component of your application: ...@@ -241,6 +255,7 @@ The store should be included in the main component of your application:
``` ```
### Communicating with the Store ### Communicating with the Store
```javascript ```javascript
<script> <script>
import { mapActions, mapState, mapGetters } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
...@@ -298,29 +313,33 @@ export default { ...@@ -298,29 +313,33 @@ export default {
1. Do not call a mutation directly. Always use an action to commit a mutation. Doing so will keep consistency throughout the application. From Vuex docs: 1. Do not call a mutation directly. Always use an action to commit a mutation. Doing so will keep consistency throughout the application. From Vuex docs:
> why don't we just call store.commit('action') directly? Well, remember that mutations must be synchronous? Actions aren't. We can perform asynchronous operations inside an action. > why don't we just call store.commit('action') directly? Well, remember that mutations must be synchronous? Actions aren't. We can perform asynchronous operations inside an action.
```javascript ```javascript
// component.vue // component.vue
// bad // bad
created() { created() {
this.$store.commit('mutation'); this.$store.commit('mutation');
} }
// good
created() {
this.$store.dispatch('action');
}
```
// good
created() {
this.$store.dispatch('action');
}
```
1. Use mutation types instead of hardcoding strings. It will be less error prone. 1. Use mutation types instead of hardcoding strings. It will be less error prone.
1. The State will be accessible in all components descending from the use where the store is instantiated. 1. The State will be accessible in all components descending from the use where the store is instantiated.
### Testing Vuex ### Testing Vuex
#### Testing Vuex concerns #### Testing Vuex concerns
Refer to [vuex docs][vuex-testing] regarding testing Actions, Getters and Mutations. Refer to [vuex docs][vuex-testing] regarding testing Actions, Getters and Mutations.
#### Testing components that need a store #### Testing components that need a store
Smaller components might use `store` properties to access the data. Smaller components might use `store` properties to access the data.
In order to write unit tests for those components, we need to include the store and provide the correct state: In order to write unit tests for those components, we need to include the store and provide the correct state:
...@@ -363,6 +382,7 @@ describe('component', () => { ...@@ -363,6 +382,7 @@ describe('component', () => {
``` ```
#### Testing Vuex actions and getters #### Testing Vuex actions and getters
Because we're currently using [`babel-plugin-rewire`](https://github.com/speedskater/babel-plugin-rewire), you may encounter the following error when testing your Vuex actions and getters: Because we're currently using [`babel-plugin-rewire`](https://github.com/speedskater/babel-plugin-rewire), you may encounter the following error when testing your Vuex actions and getters:
`[vuex] actions should be function or object with "handler" function` `[vuex] actions should be function or object with "handler" function`
......
This diff is collapsed.
...@@ -6,44 +6,44 @@ We developed a number of utilities to ease development. ...@@ -6,44 +6,44 @@ We developed a number of utilities to ease development.
- Deep merges an array of hashes: - Deep merges an array of hashes:
``` ruby ``` ruby
Gitlab::Utils::MergeHash.merge( Gitlab::Utils::MergeHash.merge(
[{ hello: ["world"] }, [{ hello: ["world"] },
{ hello: "Everyone" }, { hello: "Everyone" },
{ hello: { greetings: ['Bonjour', 'Hello', 'Hallo', 'Dzien dobry'] } }, { hello: { greetings: ['Bonjour', 'Hello', 'Hallo', 'Dzien dobry'] } },
"Goodbye", "Hallo"] "Goodbye", "Hallo"]
) )
``` ```
Gives: Gives:
``` ruby ``` ruby
[ [
{ {
hello: hello:
[ [
"world", "world",
"Everyone", "Everyone",
{ greetings: ['Bonjour', 'Hello', 'Hallo', 'Dzien dobry'] } { greetings: ['Bonjour', 'Hello', 'Hallo', 'Dzien dobry'] }
] ]
}, },
"Goodbye" "Goodbye"
] ]
``` ```
- Extracts all keys and values from a hash into an array: - Extracts all keys and values from a hash into an array:
``` ruby ``` ruby
Gitlab::Utils::MergeHash.crush( Gitlab::Utils::MergeHash.crush(
{ hello: "world", this: { crushes: ["an entire", "hash"] } } { hello: "world", this: { crushes: ["an entire", "hash"] } }
) )
``` ```
Gives: Gives:
``` ruby ``` ruby
[:hello, "world", :this, :crushes, "an entire", "hash"] [:hello, "world", :this, :crushes, "an entire", "hash"]
``` ```
## [`Override`](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/utils/override.rb) ## [`Override`](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/utils/override.rb)
...@@ -53,9 +53,9 @@ We developed a number of utilities to ease development. ...@@ -53,9 +53,9 @@ We developed a number of utilities to ease development.
`ENV['STATIC_VERIFICATION']` is set to avoid production runtime overhead. `ENV['STATIC_VERIFICATION']` is set to avoid production runtime overhead.
This is useful to check: This is useful to check:
- If we have typos in overriding methods. - If we have typos in overriding methods.
- If we renamed the overridden methods, making original overriding methods - If we renamed the overridden methods, making original overriding methods
overrides nothing. overrides nothing.
Here's a simple example: Here's a simple example:
...@@ -94,47 +94,47 @@ We developed a number of utilities to ease development. ...@@ -94,47 +94,47 @@ We developed a number of utilities to ease development.
- Memoize the value even if it is `nil` or `false`. - Memoize the value even if it is `nil` or `false`.
We often do `@value ||= compute`, however this doesn't work well if We often do `@value ||= compute`, however this doesn't work well if
`compute` might eventually give `nil` and we don't want to compute again. `compute` might eventually give `nil` and we don't want to compute again.
Instead we could use `defined?` to check if the value is set or not. Instead we could use `defined?` to check if the value is set or not.
However it's tedious to write such pattern, and `StrongMemoize` would However it's tedious to write such pattern, and `StrongMemoize` would
help us use such pattern. help us use such pattern.
Instead of writing patterns like this: Instead of writing patterns like this:
``` ruby ``` ruby
class Find class Find
def result def result
return @result if defined?(@result) return @result if defined?(@result)
@result = search @result = search
end
end end
``` end
```
We could write it like: We could write it like:
``` ruby ``` ruby
class Find class Find
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
def result def result
strong_memoize(:result) do strong_memoize(:result) do
search search
end
end end
end end
``` end
```
- Clear memoization - Clear memoization
``` ruby ``` ruby
class Find class Find
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
end end
Find.new.clear_memoization(:result) Find.new.clear_memoization(:result)
``` ```
## [`RequestCache`](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/cache/request_cache.rb) ## [`RequestCache`](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/cache/request_cache.rb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment