Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: add vue component/master #71

Merged
merged 17 commits into from
May 30, 2018

Conversation

jackiecookie
Copy link
Contributor

first, I want to thanks the casl team for providing the awesome package.
I'm now using casl to my Vue project for permissions. and I've implemented a Can component with Vue provide/inject which #64 mentioned.if you guys have good advice. please feel free to tell me.

@stalniy
Copy link
Owner

stalniy commented May 29, 2018

First of all, thank you for all that work! it's really hard to review because there are a lot of files :)

P.S.: remove yarn.lock please

import { abilitiesPlugin } from '../src';

chai.use(spies);
const should = chai.should();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use expect because all packages in repo uses expect not should

@@ -46,6 +46,8 @@
"@casl/ability": "^2.0.0",
"@vue/test-utils": "^1.0.0-beta.12",
"vue": "^2.5.13",
"vue-template-compiler": "^2.5.13"
"vue-template-compiler": "^2.5.13",
"chai": "^4.1.0",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be removed. chai and chai-spies are installed on the top level. So, you can run tests with 2 commands:

  • npm test -- --scope @casl/vue
  • or from package root: PATH=$PATH:../../node_modules/.bin npm test

@@ -1,86 +1,91 @@
import { createLocalVue } from '@vue/test-utils'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove all semicolons from tests. I prefer to keep tests clean and I'm not using semicolons in tests )) Probably need to add eslint rules for this

methods: {
$can(...args) {
watcher.rules = watcher.rules; // create dependency
return this.$ability.can(...args);
},
$defineAbility(fn) {
const watcherForComponent = new Vue({
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need a separate watcher. Also I'd like to not add this function into Vue components. People can use regular AbilityBuilder.define instead.

You can use parent.$can() from component, instead of adding additional watcher

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return parent.$can(action, subject, field) ? children : null

methods: {
$can(...args) {
watcher.rules = watcher.rules; // create dependency
return this.$ability.can(...args);
},
$defineAbility(fn) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove this function

}
}
});
Vue.component('Can', Can);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be removed and I'd like people (i.e., clients of CASL) to do it manually in case if they want to use Can component. In case if not, component can be shaked out from the build by webpack or rollup.

So, @casl/vue should just export Can component and later in the app if you want to use it you will do this:

import { Can, abilitiesPlugin } from '@casl/vue'
import Vue from 'vue'

Vue.use(abilitiesPlugin)
Vue.component('Can', Can)

new Vue(...)

props, children, parent, injections
}) {
validateProps(props);
if (injections.ability) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this. I'd prefer to implement inject/provide in a separate PR after dicussion


export default {
name: 'Can',
inject: ['ability'],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this, explanations below

props: {
I: String,
do: String,
a: [String, Object],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be only string or Function (i.e., class)

on: [String, Object]
},
render(createElement, {
props, children, parent, injections
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to use slots. What is the difference between slots and children?

@stalniy
Copy link
Owner

stalniy commented May 29, 2018

there is #63 task with subtasks for this. You can look for details there

@jackiecookie jackiecookie force-pushed the feature-add-vue-component/master branch from 1c2a1ad to 38b6a82 Compare May 30, 2018 00:41
@codecov-io
Copy link

codecov-io commented May 30, 2018

Codecov Report

Merging #71 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #71      +/-   ##
==========================================
+ Coverage   99.62%   99.63%   +<.01%     
==========================================
  Files          15       16       +1     
  Lines         267      274       +7     
==========================================
+ Hits          266      273       +7     
  Misses          1        1
Impacted Files Coverage Δ
packages/casl-vue/src/component/can.js 100% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b12eb80...40d2e19. Read the comment docs.

@jackiecookie jackiecookie force-pushed the feature-add-vue-component/master branch from 38b6a82 to 07f17a6 Compare May 30, 2018 00:44
@jackiecookie
Copy link
Contributor Author

jackiecookie commented May 30, 2018

the slot between children on functional component reference: https://vuejs.org/v2/guide/render-function.html#slots-vs-children on this Can component children equals slot.default.

AFAIK the ability.update will reassign rules which hard maintain if I have a lot of authority to manage.so, in this case, every Can component can use the separate ability provide by its own vm instance or parent instance maybe is better(like casl-react abilityProvider).

@stalniy
Copy link
Owner

stalniy commented May 30, 2018

Awesome! Thanks for explanation.

Frankly speaking, I don’t think that it make sense to have more than 1 instance of Ability in application.

However your point is valid. In some edge cases it may be required (I don’t know such). But for simplicity I’d like to proceed with smaller steps (I wrote article about CR).

Let’s add support for provide/inject in a separate PR.

Copy link
Owner

@stalniy stalniy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it's better. I will change tests a bit and merge it. Thanks!

@@ -149,4 +149,4 @@ describe('`Can` component', () => {
function validateProps(Component, props, propName) {
assertPropTypes(Component.propTypes, props, 'prop', Component.name)
}
})
})
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert this change please as it doesn’t relates to the purpose of this commit :)

@stalniy stalniy merged commit 42ee540 into stalniy:master May 30, 2018
@stalniy
Copy link
Owner

stalniy commented May 30, 2018

created #72 for provide/inject functionality

@jackiecookie
Copy link
Contributor Author

jackiecookie commented May 30, 2018

just have one instance of ability also has another issue at this time.let's say, I have one App have 3 components. like: https://jsfiddle.net/saL0ocLj/ , when getAnotherAbility called, the Post component cause rerendered, its performance waste. if Post component and Blog component can provide Ability by own components,like: https://jsfiddle.net/bfdvr5k8/. hope that's can make sense. Thanks!

@stalniy
Copy link
Owner

stalniy commented May 30, 2018

Ok. I’ll take a look at that tomorrow. Thanks!

@stalniy
Copy link
Owner

stalniy commented May 30, 2018

I see your point. You want to not rerender component if ability.can didn’t change its value. To do this can needs to be converted to stateful component. Functional ones are rerendered on each tick

The main idea of CASL is to keep all permissions in one place. So I don’t think it make sense to create separate abilities (I.e. instances of Ability)

Another point is that user permissions are not changed very often. Thus performance shouldn’t be a big issue here

@jackiecookie jackiecookie deleted the feature-add-vue-component/master branch May 31, 2018 00:34
@jackiecookie
Copy link
Contributor Author

Thanks for the explanation, It's helpful!

@stalniy
Copy link
Owner

stalniy commented May 31, 2018

An interesting reading about functional components: vuejs/vue#4037 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants