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

replace with new tn-models-fp #204

Merged
merged 39 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
483d038
replace with new tn-models-fp
paribaker Jul 16, 2023
70fc1e6
updated to remove comments
paribaker Jul 16, 2023
ea88024
updated axios
paribaker Jul 16, 2023
8622f56
fix missing deps
paribaker Jul 16, 2023
93c7a1e
remvoed users
paribaker Jul 16, 2023
d363f64
checking implicit exports
paribaker Jul 16, 2023
90f1703
updated user api
paribaker Jul 16, 2023
16845aa
import axios instance
paribaker Jul 16, 2023
9c73166
updated user resgistration
paribaker Jul 16, 2023
ca47ae0
updated fn
paribaker Jul 16, 2023
1d8c8eb
make base shape readonly
paribaker Jul 16, 2023
1223953
updated baseModelShape
paribaker Jul 16, 2023
d521408
updated typo
paribaker Jul 16, 2023
666a654
updated to include token as opt
paribaker Jul 16, 2023
401d469
fix readonly import
paribaker Jul 16, 2023
c443347
change to confirm password
paribaker Jul 16, 2023
5afc5eb
updated reset flow
paribaker Jul 16, 2023
5f50bd5
Merge branch 'main' into feature/vue-to-models-fp
paribaker Jul 17, 2023
30a5c6d
small fixes
paribaker Aug 3, 2023
d7234d3
updated code with new libs
paribaker Aug 10, 2023
33f44c6
merge main
paribaker Aug 10, 2023
c42d41c
remove lock file
paribaker Aug 10, 2023
3bb0c6c
updated package.json
paribaker Aug 10, 2023
d7b64fe
Merge branch 'main' into feature/vue-to-models-fp
paribaker Aug 10, 2023
9f4cc27
Merge branch 'main' into feature/vue-to-models-fp
paribaker Aug 11, 2023
1274573
remove read only
paribaker Aug 11, 2023
0084f37
upadted readonly
paribaker Aug 11, 2023
935effc
changed to tailwind 3.2.2 for async error
paribaker Aug 11, 2023
bc631b2
trying tailwind 3.2.2
paribaker Aug 12, 2023
aa3dd24
pin tailwind version
paribaker Aug 12, 2023
26a7eee
resolve comments
paribaker Aug 18, 2023
778a22b
updated with merge conflicts
paribaker Aug 18, 2023
6bf9082
added api to axios and removed from libs
paribaker Aug 18, 2023
676c68a
fix for sign up, temp use react for test
paribaker Aug 20, 2023
4d5d804
trigger react
paribaker Aug 20, 2023
bb7adb5
fix skip lock issue
paribaker Aug 20, 2023
9320df5
updated to force react
paribaker Aug 20, 2023
64d9ca5
updated to remove react force
paribaker Aug 20, 2023
65d7348
form fix for react sign up
paribaker Aug 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions {{cookiecutter.project_slug}}/clients/web/vue3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@
"@thinknimble/tn-forms": "^2.0.9",
"@thinknimble/tn-models": "1.2.1",
"@thinknimble/tn-utils": "1.6.0",
"@thinknimble/tn-models-fp": "^2.12.1",
"autoprefixer": "^10.0.2",
"axios": "^0.22.0",
"axios": "^1.4.0",
"core-js": "^3.6.5",
"js-cookie": "^3.0.1",
"postcss": "^8.1.0",
"tailwindcss": "3.0.11",
"vue": "^3.0.0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0",
"vuex-persistedstate": "^4.1.0"
"vuex-persistedstate": "^4.1.0",
"zod": "3.21.4"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ApiService {
static session
static init
constructor() {
let baseURL = `${window.location.protocol}//${window.location.host}/api`
let baseURL = `${window.location.protocol}//${window.location.host}/`

paribaker marked this conversation as resolved.
Show resolved Hide resolved
console.debug(`API Service for ${baseURL}`)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { z } from 'zod'
import {readonly} from '@thinknimble/tn-models-fp'

paribaker marked this conversation as resolved.
Show resolved Hide resolved
export const baseModelShape = {
id: readonly(z.string().uuid().optiona()),
datetimeCreated: readonly(z.string().datetime().optional()),
lastEdited: readonly(z.string().datetime().optional()),
}
Original file line number Diff line number Diff line change
@@ -1,81 +1,47 @@
import { ModelAPI, objectToCamelCase } from '@thinknimble/tn-models'

import AxiosClient from '../AxiosClient'
import { apiErrorHandler } from '../api'

// NOTE: The AxiosClient is congfigured to include '/api' in the baseUrl
const LOGIN_ENDPOINT = '/login/'
const PASSWORD_RESET_EMAIL_ENDPOINT = '/password/reset/'
const PASSWORD_RESET_ENDPOINT = '/password/reset/confirm/'
const REGISTRATION_ENDPOINT = '/users/'
const USERS_ENDPOINT = '/users/'

export default class UserAPI extends ModelAPI {
/**
* ModelAPI contains methods for list and create (overridden here) and the FILTERS_MAP
* You may override any of these methods by statically defining them here
* e.g static FILTERS_MAP={...UserAPI.FILTERS_MAP, <FITERS>}
* list({ filters = {}, pagination = {} }){
*
* }
*/

get client() {
return AxiosClient
}

static ENDPOINT = USERS_ENDPOINT

login(d) {
const data = { email: d.email.toLowerCase(), password: d.password }
return this.client
.post(LOGIN_ENDPOINT, data)
.then((response) => this.cls.fromAPI(response.data))
.catch(
apiErrorHandler({
apiName: 'UserAPI.login',
enable400Alert: false,
enable500Alert: false
}),
)
}

registerUser(d) {
const data = {
firstName: d.firstName,
lastName: d.lastName,
email: d.email.toLowerCase(),
password: d.password,
}
return this.client
.post(REGISTRATION_ENDPOINT, this.cls.toAPI(data))
.then((response) => this.cls.fromAPI(response.data))
.catch(
apiErrorHandler({
apiName: 'UserAPI.registerUser',
enable400Alert: false,
enable500Alert: false,
}),
)
}

requestPasswordReset(email) {
const data = { email: email }
return this.client
.post(PASSWORD_RESET_EMAIL_ENDPOINT, data)
.catch(
apiErrorHandler({
apiName: 'UserAPI.requestPasswordReset',
}),
)
}

resetPassword({ uid, token, password }) {
const url = `${PASSWORD_RESET_ENDPOINT}${uid}/${token}/`
const data = { password }
return this.client
.post(url, data)
.then((response) => this.cls.fromAPI(response.data))
.catch(apiErrorHandler({ apiName: 'UserAPI.resetPassword' }))
}
}
import { createApi, createCustomServiceCall } from '@thinknimble/tn-models-fp'
import { z } from 'zod'
import axiosInstance from '../AxiosClient'
paribaker marked this conversation as resolved.
Show resolved Hide resolved
import { userShape, forgotPasswordShape, userCreateShape, loginShape } from './models'

const login = createCustomServiceCall(
{
inputShape: loginShape,
outputShape: userShape,
},
async ({ client, input, utils }) => {
const res = await client.post('api/login/', utils.toApi(input))
paribaker marked this conversation as resolved.
Show resolved Hide resolved
return utils.fromApi(res.data)
},
)

const requestPasswordReset = createCustomServiceCall(
{
inputShape: forgotPasswordShape,
},
async ({ client, input }) => {
await client.get(`api/password/reset/${input.email}/`)
},
)
const resetPassword = createCustomServiceCall(
{
inputShape: { uid: z.string().email(), token: z.string(), password: z.string() },
outputShape: userShape,
},
async ({ client, input, utils }) => {
const { email, ...rest } = utils.toApi(input)
const res = await client.post(`api/password/reset/code/confirm/${input.email}/`, rest)
return utils.fromApi(res.data)
},
)

export const userApi = createApi(
{
client: axiosInstance,
baseUri: 'api/users/',
models: {
create: userCreateShape,
entity: userShape,
},
},
{ login, requestPasswordReset, resetPassword },
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import User from './models'
import UserAPI from './api'
import { LoginForm, SignupForm, RequestPasswordResetForm, PasswordResetForm } from './forms'

export default User
export { LoginForm, SignupForm, RequestPasswordResetForm, PasswordResetForm, UserAPI }
export * from './forms'
export * from './api'
export * from './models'
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import Model, { fields } from '@thinknimble/tn-models'
import { z } from 'zod'
import { baseModelShape } from '../base-model'

import UserAPI from './api'
export const userShape = {
...baseModelShape,
paribaker marked this conversation as resolved.
Show resolved Hide resolved
email: z.string().email(),
firstName: z.string(),
lastName: z.string(),
token: z.string().nullable(),
}

export const userCreateShape = {
...userShape,
password: z.string(),
confirmPassword: z.string(),
}

export const forgotPasswordShape = {
email: z.string().email(),
}

export default class User extends Model {
static api = UserAPI.create(User)

static id = new fields.CharField({ readOnly: true })
static firstName = new fields.CharField()
static lastName = new fields.CharField()
static email = new fields.CharField()
static fullName = new fields.CharField({ readOnly: true })
static token = new fields.CharField()
export const loginShape = {
email: z.string().email(),
password: z.string(),
}

Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import { ref } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
import User, { LoginForm } from '@/services/users/'
import { LoginForm, userApi } from '@/services/users/'
import InputField from '@/components/inputs/InputField'

export default {
Expand Down Expand Up @@ -74,8 +74,7 @@ export default {
const unwrappedForm = form.value
unwrappedForm.validate()
if (!unwrappedForm.isValid) return

User.api
userApi.csc
.login({ email: unwrappedForm.email.value, password: unwrappedForm.password.value })
.then(handleLoginSuccess)
.catch(handleLoginFailure)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

<script>
import { ref } from 'vue'
import User, { RequestPasswordResetForm } from '@/services/users/'
import { userApi, RequestPasswordResetForm } from '@/services/users/'
import InputField from '@/components/inputs/InputField'

export default {
Expand All @@ -67,8 +67,7 @@ export default {
unwrappedForm.validate()
if (!unwrappedForm.isValid) return

User.api
.requestPasswordReset(unwrappedForm.email.value)
userApi.csc.requestPasswordReset(unwrappedForm.email.value)
.then(handleResetRequestSuccess)
.catch(handleResetRequestFailure)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import { ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useStore } from 'vuex'
import User, { PasswordResetForm } from '@/services/users/'
import { userApi, PasswordResetForm } from '@/services/users/'
import InputField from '@/components/inputs/InputField'

export default {
Expand Down Expand Up @@ -58,7 +58,7 @@ export default {

const { uid, token } = route.params

User.api
userApi.csc
paribaker marked this conversation as resolved.
Show resolved Hide resolved
.resetPassword({
uid,
token,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@
import { ref } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
import User, { SignupForm } from '@/services/users/'
import { userApi, SignupForm } from '@/services/users/'
import InputField from '@/components/inputs/InputField'


export default {
name: 'Signup',
components: {
Expand Down Expand Up @@ -92,8 +93,7 @@ export default {
unwrappedForm.validate()
if (!unwrappedForm.isValid) return

User.api
.registerUser({
userApi.create({
paribaker marked this conversation as resolved.
Show resolved Hide resolved
firstName: unwrappedForm.firstName.value,
lastName: unwrappedForm.lastName.value,
email: unwrappedForm.email.value,
Expand Down