Commit e771a05f authored by Russell Dickenson's avatar Russell Dickenson Committed by Amy Qualls

Remove future tense from Frontend Guide

parent c5634246
...@@ -22,7 +22,7 @@ The value is irrelevant. ...@@ -22,7 +22,7 @@ The value is irrelevant.
The DropLab class has no side effects, so you must always call `.init` when the The DropLab class has no side effects, so you must always call `.init` when the
DOM is ready. `DropLab.prototype.init` takes the same arguments as `DropLab.prototype.addHook`. DOM is ready. `DropLab.prototype.init` takes the same arguments as `DropLab.prototype.addHook`.
If you don't provide any arguments, it will globally query and instantiate all If you don't provide any arguments, it globally queries and instantiates all
DropLab-compatible dropdowns. DropLab-compatible dropdowns.
```html ```html
...@@ -103,7 +103,7 @@ droplab.addHook(trigger, list); ...@@ -103,7 +103,7 @@ droplab.addHook(trigger, list);
### Dynamic data ### Dynamic data
Adding `data-dynamic` to your dropdown element will enable dynamic list Adding `data-dynamic` to your dropdown element enables dynamic list
rendering. rendering.
You can template a list item using the keys of the data object provided. Use the You can template a list item using the keys of the data object provided. Use the
...@@ -111,7 +111,7 @@ handlebars syntax `{{ value }}` to HTML escape the value. Use the `<%= value %>` ...@@ -111,7 +111,7 @@ handlebars syntax `{{ value }}` to HTML escape the value. Use the `<%= value %>`
syntax to interpolate the value. Use the `<%= value %>` syntax to evaluate the syntax to interpolate the value. Use the `<%= value %>` syntax to evaluate the
value. value.
Passing an array of objects to `DropLab.prototype.addData` will render that data Passing an array of objects to `DropLab.prototype.addData` renders that data
for all `data-dynamic` dropdown lists tracked by that DropLab instance. for all `data-dynamic` dropdown lists tracked by that DropLab instance.
```html ```html
...@@ -227,8 +227,8 @@ provides some potentially useful data. ...@@ -227,8 +227,8 @@ provides some potentially useful data.
Plugins are objects that are registered to be executed when a hook is added (when Plugins are objects that are registered to be executed when a hook is added (when
a DropLab trigger and dropdown are instantiated). a DropLab trigger and dropdown are instantiated).
If no modules API is detected, the library will fall back as it does with If no modules API is detected, the library falls back as it does with
`window.DropLab` and will add `window.DropLab.plugins.PluginName`. `window.DropLab` and adds `window.DropLab.plugins.PluginName`.
### Usage ### Usage
......
...@@ -49,7 +49,7 @@ droplab.addData('trigger', [{ ...@@ -49,7 +49,7 @@ droplab.addData('trigger', [{
In the previous code, the input string is compared against the `test` key of the In the previous code, the input string is compared against the `test` key of the
passed data objects. passed data objects.
Optionally you can set `filterFunction` to a function. This function will be Optionally you can set `filterFunction` to a function. This function is then
used instead of `Filter`'s built-in string search. `filterFunction` is passed used instead of `Filter`'s built-in string search. `filterFunction` is passed
two arguments: the first is one of the data objects, and the second is the two arguments: the first is one of the data objects, and the second is the
current input value. current input value.
...@@ -67,6 +67,6 @@ element's `data-selected-id` to `1`. ...@@ -67,6 +67,6 @@ element's `data-selected-id` to `1`.
Optionally, you can set `inputAttribute` to a string that's the name of an Optionally, you can set `inputAttribute` to a string that's the name of an
attribute on your `input` element that you want to update. If you don't provide attribute on your `input` element that you want to update. If you don't provide
an `inputAttribute`, `InputSetter` will update the `value` of the `input` an `inputAttribute`, `InputSetter` updates the `value` of the `input`
element if it's an `INPUT` element, or the `textContent` of the `input` element element if it's an `INPUT` element, or the `textContent` of the `input` element
if it isn't an `INPUT` element. if it isn't an `INPUT` element.
...@@ -82,13 +82,13 @@ follow up issue and attach it to the component implementation epic found within ...@@ -82,13 +82,13 @@ follow up issue and attach it to the component implementation epic found within
### 4. My submit form button becomes disabled after submitting ### 4. My submit form button becomes disabled after submitting
If you are using a submit button inside a form and you attach an `onSubmit` event listener on the form element, [this piece of code](https://gitlab.com/gitlab-org/gitlab/blob/794c247a910e2759ce9b401356432a38a4535d49/app/assets/javascripts/main.js#L225) will add a `disabled` class selector to the submit button when the form is submitted. If you are using a submit button inside a form and you attach an `onSubmit` event listener on the form element, [this piece of code](https://gitlab.com/gitlab-org/gitlab/blob/794c247a910e2759ce9b401356432a38a4535d49/app/assets/javascripts/main.js#L225) adds a `disabled` class selector to the submit button when the form is submitted.
To avoid this behavior, add the class `js-no-auto-disable` to the button. To avoid this behavior, add the class `js-no-auto-disable` to the button.
### 5. Should I use a full URL (i.e. `gon.gitlab_url`) or a full path (i.e. `gon.relative_url_root`) when referencing backend endpoints? ### 5. Should I use a full URL (i.e. `gon.gitlab_url`) or a full path (i.e. `gon.relative_url_root`) when referencing backend endpoints?
It's preferred to use a **full path** over a **full URL** because the URL will use the hostname configured with It's preferred to use a **full path** over a **full URL** because the URL uses the hostname configured with
GitLab which may not match the request. This will cause [CORS issues like this Web IDE one](https://gitlab.com/gitlab-org/gitlab/-/issues/36810). GitLab which may not match the request. This causes [CORS issues like this Web IDE one](https://gitlab.com/gitlab-org/gitlab/-/issues/36810).
Example: Example:
...@@ -161,8 +161,9 @@ Sometimes it's necessary to test locally what the frontend production build woul ...@@ -161,8 +161,9 @@ Sometimes it's necessary to test locally what the frontend production build woul
1. Open `gitlab.yaml` located in your `gitlab` installation folder, scroll down to the `webpack` section and change `dev_server` to `enabled: false`. 1. Open `gitlab.yaml` located in your `gitlab` installation folder, scroll down to the `webpack` section and change `dev_server` to `enabled: false`.
1. Run `yarn webpack-prod && gdk restart rails-web`. 1. Run `yarn webpack-prod && gdk restart rails-web`.
The production build takes a few minutes to be completed; any code change at this point will be The production build takes a few minutes to be completed; any code changes at this point are
displayed only after executing the item 3 above again. displayed only after executing the item 3 above again.
To return to the normal development mode: To return to the normal development mode:
1. Open `gitlab.yaml` located in your `gitlab` installation folder, scroll down to the `webpack` section and change back `dev_server` to `enabled: true`. 1. Open `gitlab.yaml` located in your `gitlab` installation folder, scroll down to the `webpack` section and change back `dev_server` to `enabled: true`.
......
...@@ -31,7 +31,7 @@ sprite_icon(icon_name, size: nil, css_class: '') ...@@ -31,7 +31,7 @@ sprite_icon(icon_name, size: nil, css_class: '')
- **icon_name**: Use the icon_name for the SVG sprite in the list of - **icon_name**: Use the icon_name for the SVG sprite in the list of
([GitLab SVGs](https://gitlab-org.gitlab.io/gitlab-svgs)). ([GitLab SVGs](https://gitlab-org.gitlab.io/gitlab-svgs)).
- **size (optional)**: Use one of the following sizes : 16, 24, 32, 48, 72 (this - **size (optional)**: Use one of the following sizes : 16, 24, 32, 48, 72 (this
will be translated into a `s16` class) is translated into a `s16` class)
- **css_class (optional)**: If you want to add additional CSS classes. - **css_class (optional)**: If you want to add additional CSS classes.
**Example** **Example**
......
...@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Principles # Principles
These principles will ensure that your frontend contribution starts off in the right direction. These principles ensure that your frontend contribution starts off in the right direction.
## Discuss architecture before implementation ## Discuss architecture before implementation
...@@ -14,7 +14,7 @@ Discuss your architecture design in an issue before writing code. This helps dec ...@@ -14,7 +14,7 @@ Discuss your architecture design in an issue before writing code. This helps dec
## Be consistent ## Be consistent
There are multiple ways of writing code to accomplish the same results. We should be as consistent as possible in how we write code across our codebases. This will make it easier for us to maintain our code across GitLab. There are multiple ways of writing code to accomplish the same results. We should be as consistent as possible in how we write code across our codebases. This makes it easier for us to maintain our code across GitLab.
## Improve code [iteratively](https://about.gitlab.com/handbook/values/#iteration) ## Improve code [iteratively](https://about.gitlab.com/handbook/values/#iteration)
......
...@@ -19,7 +19,7 @@ You can run eslint locally by running `yarn eslint` ...@@ -19,7 +19,7 @@ You can run eslint locally by running `yarn eslint`
## Avoid forEach ## Avoid forEach
Avoid forEach when mutating data. Use `map`, `reduce` or `filter` instead of `forEach` Avoid forEach when mutating data. Use `map`, `reduce` or `filter` instead of `forEach`
when mutating data. This will minimize mutations in functions, when mutating data. This minimizes mutations in functions,
which aligns with [Airbnb's style guide](https://github.com/airbnb/javascript#testing--for-real). which aligns with [Airbnb's style guide](https://github.com/airbnb/javascript#testing--for-real).
```javascript ```javascript
...@@ -237,7 +237,7 @@ document.addEventListener("DOMContentLoaded", function(event) { ...@@ -237,7 +237,7 @@ document.addEventListener("DOMContentLoaded", function(event) {
### Avoid side effects in constructors ### Avoid side effects in constructors
Avoid making asynchronous calls, API requests or DOM manipulations in the `constructor`. Avoid making asynchronous calls, API requests or DOM manipulations in the `constructor`.
Move them into separate functions instead. This will make tests easier to write and Move them into separate functions instead. This makes tests easier to write and
avoids violating the [Single Responsibility Principle](https://en.wikipedia.org/wiki/Single_responsibility_principle). avoids violating the [Single Responsibility Principle](https://en.wikipedia.org/wiki/Single_responsibility_principle).
```javascript ```javascript
......
...@@ -12,7 +12,7 @@ easy to maintain, and performant for the end-user. ...@@ -12,7 +12,7 @@ easy to maintain, and performant for the end-user.
## Rules ## Rules
Our CSS is a mixture of current and legacy approaches. That means sometimes it may be difficult to follow this guide to the letter; it means you will definitely run into exceptions, where following the guide is difficult to impossible without outsized effort. In those cases, you may work with your reviewers and maintainers to identify an approach that does not fit these rules. Please endeavor to limit these cases. Our CSS is a mixture of current and legacy approaches. That means sometimes it may be difficult to follow this guide to the letter; it means you are likely to run into exceptions, where following the guide is difficult to impossible without outsized effort. In those cases, you may work with your reviewers and maintainers to identify an approach that does not fit these rules. Please endeavor to limit these cases.
### Utility Classes ### Utility Classes
...@@ -132,8 +132,8 @@ We use [SCSS Lint](https://github.com/sds/scss-lint) to check for style guide co ...@@ -132,8 +132,8 @@ We use [SCSS Lint](https://github.com/sds/scss-lint) to check for style guide co
ruleset in `.scss-lint.yml`, which is located in the home directory of the ruleset in `.scss-lint.yml`, which is located in the home directory of the
project. project.
To check if any warnings will be produced by your changes, you can run `rake To check if any warnings are produced by your changes, run `rake
scss_lint` in the GitLab directory. SCSS Lint will also run in GitLab CI/CD to scss_lint` in the GitLab directory. SCSS Lint also runs in GitLab CI/CD to
catch any warnings. catch any warnings.
If the Rake task is throwing warnings you don't understand, SCSS Lint's If the Rake task is throwing warnings you don't understand, SCSS Lint's
...@@ -147,4 +147,4 @@ the SCSS style guide, you can use [CSSComb](https://github.com/csscomb/csscomb.j ...@@ -147,4 +147,4 @@ the SCSS style guide, you can use [CSSComb](https://github.com/csscomb/csscomb.j
CSSComb globally (system-wide). Run it in the GitLab directory with CSSComb globally (system-wide). Run it in the GitLab directory with
`csscomb app/assets/stylesheets` to automatically fix issues with CSS/SCSS. `csscomb app/assets/stylesheets` to automatically fix issues with CSS/SCSS.
Note that this won't fix every problem, but it should fix a majority. Note that this doesn't fix every problem, but it should fix a majority.
...@@ -98,7 +98,7 @@ Please check this [rules](https://github.com/vuejs/eslint-plugin-vue#bulb-rules) ...@@ -98,7 +98,7 @@ Please check this [rules](https://github.com/vuejs/eslint-plugin-vue#bulb-rules)
We discourage the use of the spread operator in this specific case in We discourage the use of the spread operator in this specific case in
order to keep our codebase explicit, discoverable, and searchable. order to keep our codebase explicit, discoverable, and searchable.
This applies in any place where we'll benefit from the above, such as This applies in any place where we would benefit from the above, such as
when [initializing Vuex state](../vuex.md#why-not-just-spread-the-initial-state). when [initializing Vuex state](../vuex.md#why-not-just-spread-the-initial-state).
The pattern above also enables us to easily parse non scalar values during The pattern above also enables us to easily parse non scalar values during
instantiation. instantiation.
...@@ -667,7 +667,7 @@ The goal of this accord is to make sure we are all on the same page. ...@@ -667,7 +667,7 @@ The goal of this accord is to make sure we are all on the same page.
1. If you need to grab data from the DOM, you may query the DOM 1 time while bootstrapping your application to grab data attributes using `dataset`. You can do this without jQuery. 1. If you need to grab data from the DOM, you may query the DOM 1 time while bootstrapping your application to grab data attributes using `dataset`. You can do this without jQuery.
1. You may use a jQuery dependency in Vue.js following [this example from the docs](https://vuejs.org/v2/examples/select2.html). 1. You may use a jQuery dependency in Vue.js following [this example from the docs](https://vuejs.org/v2/examples/select2.html).
1. If an outside jQuery Event needs to be listen to inside the Vue application, you may use jQuery event listeners. 1. If an outside jQuery Event needs to be listen to inside the Vue application, you may use jQuery event listeners.
1. We will avoid adding new jQuery events when they are not required. Instead of adding new jQuery events take a look at [different methods to do the same task](https://vuejs.org/v2/api/#vm-emit). 1. We avoid adding new jQuery events when they are not required. Instead of adding new jQuery events take a look at [different methods to do the same task](https://vuejs.org/v2/api/#vm-emit).
1. You may query the `window` object one time, while bootstrapping your application for application specific data (e.g. `scrollTo` is ok to access anytime). Do this access during the bootstrapping of your application. 1. You may query the `window` object one time, while bootstrapping your application for application specific data (e.g. `scrollTo` is ok to access anytime). Do this access during the bootstrapping of your application.
1. You may have a temporary but immediate need to create technical debt by writing code that does not follow our standards, to be refactored later. Maintainers need to be ok with the tech debt in the first place. An issue should be created for that tech debt to evaluate it further and discuss. In the coming months you should fix that tech debt, with its priority to be determined by maintainers. 1. You may have a temporary but immediate need to create technical debt by writing code that does not follow our standards, to be refactored later. Maintainers need to be ok with the tech debt in the first place. An issue should be created for that tech debt to evaluate it further and discuss. In the coming months you should fix that tech debt, with its priority to be determined by maintainers.
1. When creating tech debt you must write the tests for that code before hand and those tests may not be rewritten. e.g. jQuery tests rewritten to Vue tests. 1. When creating tech debt you must write the tests for that code before hand and those tests may not be rewritten. e.g. jQuery tests rewritten to Vue tests.
......
...@@ -14,21 +14,21 @@ We use ESLint to encapsulate and enforce frontend code standards. Our configurat ...@@ -14,21 +14,21 @@ We use ESLint to encapsulate and enforce frontend code standards. Our configurat
This section describes yarn scripts that are available to validate and apply automatic fixes to files using ESLint. This section describes yarn scripts that are available to validate and apply automatic fixes to files using ESLint.
To check all currently staged files (based on `git diff`) with ESLint, run the following script: To check all staged files (based on `git diff`) with ESLint, run the following script:
```shell ```shell
yarn eslint-staged yarn eslint-staged
``` ```
A list of problems found will be logged to the console. A list of problems found are logged to the console.
To apply automatic ESLint fixes to all currently staged files (based on `git diff`), run the following script: To apply automatic ESLint fixes to all staged files (based on `git diff`), run the following script:
```shell ```shell
yarn eslint-staged-fix yarn eslint-staged-fix
``` ```
If manual changes are required, a list of changes will be sent to the console. If manual changes are required, a list of changes are sent to the console.
To check **all** files in the repository with ESLint, run the following script: To check **all** files in the repository with ESLint, run the following script:
...@@ -36,7 +36,7 @@ To check **all** files in the repository with ESLint, run the following script: ...@@ -36,7 +36,7 @@ To check **all** files in the repository with ESLint, run the following script:
yarn eslint yarn eslint
``` ```
A list of problems found will be logged to the console. A list of problems found are logged to the console.
To apply automatic ESLint fixes to **all** files in the repository, run the following script: To apply automatic ESLint fixes to **all** files in the repository, run the following script:
...@@ -44,7 +44,7 @@ To apply automatic ESLint fixes to **all** files in the repository, run the foll ...@@ -44,7 +44,7 @@ To apply automatic ESLint fixes to **all** files in the repository, run the foll
yarn eslint-fix yarn eslint-fix
``` ```
If manual changes are required, a list of changes will be sent to the console. If manual changes are required, a list of changes are sent to the console.
WARNING: WARNING:
Limit use to global rule updates. Otherwise, the changes can lead to huge Merge Requests. Limit use to global rule updates. Otherwise, the changes can lead to huge Merge Requests.
...@@ -156,13 +156,13 @@ The source of these Yarn scripts can be found in `/scripts/frontend/prettier.js` ...@@ -156,13 +156,13 @@ The source of these Yarn scripts can be found in `/scripts/frontend/prettier.js`
node ./scripts/frontend/prettier.js check-all ./vendor/ node ./scripts/frontend/prettier.js check-all ./vendor/
``` ```
This will go over all files in a specific folder check it. This iterates over all files in a specific folder, and checks them.
```shell ```shell
node ./scripts/frontend/prettier.js save-all ./vendor/ node ./scripts/frontend/prettier.js save-all ./vendor/
``` ```
This will go over all files in a specific folder and save it. This iterates over all files in a specific folder and saves them.
### VSCode Settings ### VSCode Settings
......
...@@ -62,11 +62,11 @@ Be sure to read about [page-specific JavaScript](performance.md#page-specific-ja ...@@ -62,11 +62,11 @@ Be sure to read about [page-specific JavaScript](performance.md#page-specific-ja
While mounting a Vue application, you might need to provide data from Rails to JavaScript. While mounting a Vue application, you might need to provide data from Rails to JavaScript.
To do that, you can use the `data` attributes in the HTML element and query them while mounting the application. To do that, you can use the `data` attributes in the HTML element and query them while mounting the application.
You should only do this while initializing the application, because the mounted element will be replaced with Vue-generated DOM. You should only do this while initializing the application, because the mounted element is replaced with a Vue-generated DOM.
The advantage of providing data from the DOM to the Vue instance through `props` in the `render` function The advantage of providing data from the DOM to the Vue instance through `props` in the `render` function
instead of querying the DOM inside the main Vue component is avoiding the need to create a fixture or an HTML element in the unit test, instead of querying the DOM inside the main Vue component is avoiding the need to create a fixture or an HTML element in the unit test,
which will make the tests easier. which makes the tests easier.
See the following example, also, please refer to our [Vue style guide](style/vue.md#basic-rules) for additional See the following example, also, please refer to our [Vue style guide](style/vue.md#basic-rules) for additional
information on why we explicitly declare the data being passed into the Vue app; information on why we explicitly declare the data being passed into the Vue app;
...@@ -98,8 +98,8 @@ return new Vue({ ...@@ -98,8 +98,8 @@ return new Vue({
#### Accessing the `gl` object #### Accessing the `gl` object
When we need to query the `gl` object for data that won't change during the application's life cycle, we should do it in the same place where we query the DOM. When we need to query the `gl` object for data that doesn't change during the application's life cycle, we should do it in the same place where we query the DOM.
By following this practice, we can avoid the need to mock the `gl` object, which will make tests easier. By following this practice, we can avoid the need to mock the `gl` object, which makes tests easier.
It should be done while initializing our Vue instance, and the data should be provided as `props` to the main component: It should be done while initializing our Vue instance, and the data should be provided as `props` to the main component:
```javascript ```javascript
...@@ -162,12 +162,12 @@ This approach has a few benefits: ...@@ -162,12 +162,12 @@ This approach has a few benefits:
### A folder for Components ### A folder for Components
This folder holds all components that are specific of this new feature. This folder holds all components that are specific to this new feature.
If you need to use or create a component that will probably be used somewhere If you need to use or create a component that is likely to be used somewhere
else, please refer to `vue_shared/components`. else, please refer to `vue_shared/components`.
A good rule of thumb to know when you should create a component is to think if A good rule of thumb to know when you should create a component is to think if
it will be reusable elsewhere. it could be reusable elsewhere.
For example, tables are used in a quite amount of places across GitLab, a table For example, tables are used in a quite amount of places across GitLab, a table
would be a good fit for a component. On the other hand, a table cell used only would be a good fit for a component. On the other hand, a table cell used only
...@@ -192,7 +192,7 @@ Check this [page](vuex.md) for more details. ...@@ -192,7 +192,7 @@ Check this [page](vuex.md) for more details.
In the [Vue documentation](https://vuejs.org/v2/api/#Options-Data) the Data function/object is defined as follows: In the [Vue documentation](https://vuejs.org/v2/api/#Options-Data) the Data function/object is defined as follows:
> The data object for the Vue instance. Vue will recursively convert its properties into getter/setters to make it “reactive”. The object must be plain: native objects such as browser API objects and prototype properties are ignored. A rule of thumb is that data should just be data - it is not recommended to observe objects with their own stateful behavior. > The data object for the Vue instance. Vue recursively converts its properties into getter/setters to make it “reactive”. The object must be plain: native objects such as browser API objects and prototype properties are ignored. A rule of thumb is that data should just be data - it is not recommended to observe objects with their own stateful behavior.
Based on the Vue guidance: Based on the Vue guidance:
......
...@@ -82,7 +82,7 @@ const FunctionalComp = (props, slots) => { ...@@ -82,7 +82,7 @@ const FunctionalComp = (props, slots) => {
} }
``` ```
It is not recommended to replace stateful components with functional components unless you absolutely need a performance improvement right now. In Vue 3, performance gains for functional components will be negligible. It is not recommended to replace stateful components with functional components unless you absolutely need a performance improvement right now. In Vue 3, performance gains for functional components are negligible.
## Old slots syntax with `slot` attribute ## Old slots syntax with `slot` attribute
......
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