diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-20 12:26:25 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-20 12:26:25 +0000 |
commit | a09983ae35713f5a2bbb100981116d31ce99826e (patch) | |
tree | 2ee2af7bd104d57086db360a7e6d8c9d5d43667a /doc/development/ee_features.md | |
parent | 18c5ab32b738c0b6ecb4d0df3994000482f34bd8 (diff) | |
download | gitlab-ce-a09983ae35713f5a2bbb100981116d31ce99826e.tar.gz |
Add latest changes from gitlab-org/gitlab@13-2-stable-ee
Diffstat (limited to 'doc/development/ee_features.md')
-rw-r--r-- | doc/development/ee_features.md | 88 |
1 files changed, 70 insertions, 18 deletions
diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md index e22e96b6f06..ac544113cbd 100644 --- a/doc/development/ee_features.md +++ b/doc/development/ee_features.md @@ -512,12 +512,12 @@ do that, so we'll follow regular object-oriented practices that we define the interface first here. For example, suppose we have a few more optional parameters for EE. We can move the -parameters out of the `Grape::API` class to a helper module, so we can inject it +parameters out of the `Grape::API::Instance` class to a helper module, so we can inject it before it would be used in the class. ```ruby module API - class Projects < Grape::API + class Projects < Grape::API::Instance helpers Helpers::ProjectsHelpers end end @@ -578,7 +578,7 @@ class definition to make it easy and clear: ```ruby module API - class JobArtifacts < Grape::API + class JobArtifacts < Grape::API::Instance # EE::API::JobArtifacts would override the following helpers helpers do def authorize_download_artifacts! @@ -622,7 +622,7 @@ route. Something like this: ```ruby module API - class MergeRequests < Grape::API + class MergeRequests < Grape::API::Instance helpers do # EE::API::MergeRequests would override the following helpers def update_merge_request_ee(merge_request) @@ -691,7 +691,7 @@ least argument. We would approach this as follows: ```ruby # api/merge_requests/parameters.rb module API - class MergeRequests < Grape::API + class MergeRequests < Grape::API::Instance module Parameters def self.update_params_at_least_one_of %i[ @@ -707,7 +707,7 @@ API::MergeRequests::Parameters.prepend_if_ee('EE::API::MergeRequests::Parameters # api/merge_requests.rb module API - class MergeRequests < Grape::API + class MergeRequests < Grape::API::Instance params do at_least_one_of(*Parameters.update_params_at_least_one_of) end @@ -900,27 +900,79 @@ export default { </template> ``` -#### For JS code that is EE only, like props, computed properties, methods, etc, we will keep the current approach +#### For JS code that is EE only, like props, computed properties, methods, etc -- Since we [can't async load a mixin](https://github.com/vuejs/vue-loader/issues/418#issuecomment-254032223) we will use the [`ee_else_ce`](../development/ee_features.md#javascript-code-in-assetsjavascripts) alias we already have for webpack. - - This means all the EE specific props, computed properties, methods, etc that are EE only should be in a mixin in the `ee/` folder and we need to create a CE counterpart of the mixin +- Please do not use mixins unless ABSOLUTELY NECESSARY. Please try to find an alternative pattern. -##### Example +##### Reccomended alternative approach (named/scoped slots) -```javascript -import mixin from 'ee_else_ce/path/mixin'; +- We can use slots and/or scoped slots to achieve the same thing as we did with mixins. If you only need an EE component there is no need to create the CE component. + +1. First, we have a CE component that can render a slot incase we need EE template and functionality to be decorated on top of the CE base. + +```vue +// ./ce/my_component.vue + +<script> +export default { + props: { + tooltipDefaultText: { + type: String, + }, + }, + computed: { + tooltipText() { + return this.tooltipDefaultText || "5 issues please"; + } + }, +} +</script> + +<template> + <span v-gl-tooltip :title="tooltipText" class="ce-text">Community Edition Only Text</span> + <slot name="ee-specific-component"> +</template> +``` + +1. Next, we render the EE component, and inside of the EE component we render the CE component and add additional content in the slot. -{ - mixins: [mixin] +```vue +// ./ee/my_component.vue + +<script> +export default { + computed: { + tooltipText() { + if (this.weight) { + return "5 issues with weight 10"; + } + } + }, + methods: { + submit() { + // do something. + } + }, } +</script> + +<template> + <my-component :tooltipDefaultText="tooltipText"> + <template #ee-specific-component> + <span class="some-ee-specific">EE Specific Value</span> + <button @click="submit">Click Me</button> + </template> + </my-component> +</template> ``` -- Computed Properties/methods and getters only used in the child import still need a counterpart in CE +1. Finally, wherever the component is needed we can require it like so + +`import MyComponent from 'ee_else_ce/path/my_component'.vue` -- For store modules, we will need a CE counterpart too. -- You can see an MR with an example [here](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9762) +- this way the correct component will be included for either the ce or ee implementation -#### `template` tag +**For EE components that need different results for the same computed values, we can pass in props to the CE wrapper as seen in the example.** - **EE Child components** - Since we are using the async loading to check which component to load, we'd still use the component's name, check [this example](#child-component-only-used-in-ee). |