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

Options API to Composition API #403

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

lambert-alex
Copy link
Contributor

@lambert-alex lambert-alex commented Oct 6, 2022

Issue #: /bcgov/entity#13675

Description of changes:
The work done here isn't complete or completely correct it still needs to be tested.

  • example of a composables instead of mixins
  • simple and more complex example of script setup
  • some incomplete changes to router, store and auth,

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the business-filings-ui license (Apache 2.0).

@sonarcloud
Copy link

sonarcloud bot commented Oct 6, 2022

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 14 Code Smells

No Coverage information No Coverage information
6.0% 6.0% Duplication

@@ -41,11 +41,12 @@
"v-mask": "^2.3.0",
"vue": "^2.7.10",
"vue-affix": "^0.5.2",
"vue-router": "^3.6.5",
"vue-router": "^4.1.5",
"vue-template-compiler": "^2.7.10",
Copy link
Collaborator

@severinbeauvais severinbeauvais Oct 7, 2022

Choose a reason for hiding this comment

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

vue-template-compiler is a dev dependency.

}
const { formatYyyyMmDd } = DateComposable()
const { isBComp } = AllowableActionsComposable() // probably can pull from state getters
const { getCurrentDate } = FilingComposable()
Copy link
Collaborator

@severinbeauvais severinbeauvais Oct 7, 2022

Choose a reason for hiding this comment

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

getCurrentDate come from Vuex getters.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it does, I only used the getCurrentDate from FilingComposable because I hadn't implemented the getCurrentDate in the Vuex getters and I wanted a complete component

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok.

It might be good to be concise moving forward.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes I agree


@Component({})
export default class ArDate extends Mixins(DateMixin) {
@State nextARDate!: string
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where does this come from?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't implement this. I am not sure of the best way to implement state it seems like one of the advantages of the composition api is the ability to share states between different components. So I am not really sure what the best way is to handle @state

Copy link
Collaborator

Choose a reason for hiding this comment

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

Accessing state directly was a cheat, left over from the initial implementation of this UI. It's much better to use getters.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh okay! This could possibly be a good refactor to do before changing API's I am making some tickets for that. I can add this.

import { Component } from 'vue-property-decorator'

@Component({})
export default class ContactInfo extends Vue {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

How does this component get named?

Copy link
Contributor Author

@lambert-alex lambert-alex Oct 7, 2022

Choose a reason for hiding this comment

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

The component is named as a variable when it is imported.

i.e. import ContactInfo from './ContactInfo.vue <ContactInfo /> works for this component and

import SomeRandomName from './ContactInfo.vue' <SomeRandomName /> works exactly the same

Copy link
Collaborator

Choose a reason for hiding this comment

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

So then we can't do import * from <whatever> ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you do would do import * as All from ./components <All.Foo /> <All.Bar /> There may be a more elegant solution but I haven't found one yet

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok

const isFirm = computed(() => store.getters['isFirm'] as boolean)
const isCoop = computed(() => store.getters['isCoop'] as boolean)
const hasBlockerExceptStaffApproval = computed(() => store.getters['hasBlockerExceptStaffApproval'] as boolean)
const isGoodStanding = computed(() => store.getters[''] as boolean)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is really repetitive. Is there a way to combine these and just import/declare a single thing?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or we could write a helper?
Or is there a decorator for this somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes this is way to repetitive. This is what I mean when I think we would need to do a major refactor. As code used anywhere can be reactive this could be replaced with

const { getEntityType, hasBlcker, ect.... } = getters where all the computed methods are stored

* @param keys the nested object keys which to omit properties from
* @param prop the properties to be removed
*/
const omitProps = (baseObj: any, keys: Array<string>, prop: Array<string>): any => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please set type of baseObj to object.

* Ref: https://www.npmjs.com/package/serverdate
* @returns a promise to return a Date object
*/
const getServerDate = async (): Promise<Date> => {
Copy link
Collaborator

@severinbeauvais severinbeauvais Oct 7, 2022

Choose a reason for hiding this comment

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

Do we have to use this function format or can we do this?

async function getServerDate (): Promise<Date> {
 ...
}

I think this ^^^ is easier to read. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The function format is better. I agree.

return {
fieldSorter
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you think this is better as a composable or would it be better as a standalone util function like these?

https://github.com/bcgov/business-edit-ui/tree/main/src/utils

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure. It very well might be. Right now what I have converted over is the composition api with a structure of an options api app. Which I don't think uses the composition api to its full potential

routes,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
scrollBehavior (to, from, savedPosition) {
// see https://router.vuejs.org/guide/advanced/scroll-behavior.html
return { x: 0, y: 0 }
return { left: 0, top: 0 }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wow, you've done a ton of R&D to figure all this out. Nice work! 👍

Copy link
Collaborator

@severinbeauvais severinbeauvais left a comment

Choose a reason for hiding this comment

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

Nice work!

I'm looking forward to what the next steps should be in our eventual move to Vue3 -- keeping in mind what we must do versus what we could do.

import { Debounce } from 'vue-debounce-decorator'
<script setup lang="ts">
import _ from 'lodash'
import { computed, ref, watch, defineEmits } from 'vue'
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does defineProps need to be imported here as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No and defineEmits doesn't need to be there either. Both are part of script setup

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

Successfully merging this pull request may close these issues.

2 participants