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

release v0.1.4 #28

Merged
merged 7 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 35 additions & 3 deletions dashboard/APIController/API.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import axios, { AxiosResponse, AxiosError } from 'axios'
import { TypeSigninBody, TypeSignupBody, APIResponse } from './types'

const RootURL = "http://localhost:8080"
const RootURL = "https://api.ufosc.org"

export const GetClient = (id : string) => {
return new Promise((resolve: Function, reject: Function) => {
Expand All @@ -17,6 +17,22 @@ export const GetClient = (id : string) => {
})
}

export const DeleteClient = (id : string, token : string) => {
return new Promise((resolve: Function, reject: Function) => {
axios.delete(`${RootURL}/client/${id}`, { headers: {
'Authorization': `Bearer ${token}`}}).then((res : AxiosResponse) => {
resolve(res.data)
})
.catch((err: AxiosError) => {
if (err.response && IsAPIFailure(err.response.data)) {
resolve(err.response.data)
return
}
reject(err)
})
})
}

export const GetClients = (page : number, token : string) => {
return new Promise((resolve: Function, reject: Function) => {
axios.get(`${RootURL}/clients?page=${page}`, {
Expand Down Expand Up @@ -98,10 +114,10 @@ export const GetUsers = (page : number, token : string) => {
}

export const UpdateUser = (firstName : string, lastName : string,
jwt : string) => {
token : string) => {
return new Promise((resolve: Function, reject: Function) => {
axios.put(`${RootURL}/user`, { first_name: firstName, last_name: lastName },
{ headers: { 'Authorization': `Bearer ${jwt}` }})
{ headers: { 'Authorization': `Bearer ${token}` }})
.then((res : AxiosResponse) => {
resolve(res.data)
})
Expand All @@ -115,6 +131,22 @@ export const UpdateUser = (firstName : string, lastName : string,
})
}

export const DeleteUser = (id : string, token : string) => {
return new Promise((resolve: Function, reject: Function) => {
axios.delete(`${RootURL}/user/${id}`, { headers: {
'Authorization': `Bearer ${token}`}}).then((res : AxiosResponse) => {
resolve(res.data)
})
.catch((err : AxiosError) => {
if (err.response && IsAPIFailure(err.response.data)) {
resolve(err.response.data)
return
}
reject(err)
})
})
}

export function IsAPISuccess(obj : any): obj is APIResponse {
return typeof (obj as APIResponse).message !== 'undefined'
}
Expand Down
2 changes: 1 addition & 1 deletion dashboard/app/authorize/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import Permissions from './permissions'
import './style.scss'

export default function Page() {
const cookies = useCookies()
const router = useRouter()
const cookies = useCookies()
const token = cookies.get('ows-access-token')
const [view, setView] = useState<"signin" | "signup">("signin")

Expand Down
41 changes: 22 additions & 19 deletions dashboard/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { useState } from 'react'
import { useState, useEffect } from 'react'
import { useCookies } from 'next-client-cookies'
import MyAccount from '@/components/MyAccount'
import { GetUser, IsAPISuccess } from '@/APIController/API'
Expand All @@ -15,27 +15,30 @@ type User = {
}

export default function Page() {
const router = useRouter()
const cookies = useCookies()
const token = cookies.get('ows-access-token')
const router = useRouter()
if (typeof token === "undefined") {
router.push("/authorize")
}

const [user, setUser] = useState<User | null>(null)
if (user === null) {
GetUser(token as string).then((res) => {
if (!IsAPISuccess(res)) {

useEffect(() => {
if (typeof token === "undefined") {
router.push("/authorize")
}

if (user === null) {
GetUser(token as string).then((res) => {
if (!IsAPISuccess(res)) {
cookies.remove('ows-access-token')
router.push("/authorize")
return
}
setUser(res as User)
}).catch((err) => {
cookies.remove('ows-access-token')
router.push("/authorize")
return
}
setUser(res as User)
}).catch((err) => {
cookies.remove('ows-access-token')
router.push("/authorize")
})
}
})
}
}, [])

if (user === null) {
return (<Loading withOverlay={true} />)
Expand All @@ -52,8 +55,8 @@ export default function Page() {
</TabList>
<TabPanels>
<TabPanel><MyAccount user={user} /></TabPanel>
<TabPanel><Clients /></TabPanel>
<TabPanel><Users /></TabPanel>
<TabPanel>{(user.realms?.includes("clients.read")) ? (<Clients />) : null }</TabPanel>
<TabPanel>{ (user.realms?.includes("users.read")) ? (<Users />) : null }</TabPanel>
</TabPanels>
</Tabs>
</div>
Expand Down
62 changes: 53 additions & 9 deletions dashboard/components/Clients.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import TableView from './TableView'
import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { GetClients, IsAPISuccess } from '@/APIController/API'
import { DeleteClient, GetClients, IsAPIFailure, IsAPISuccess } from '@/APIController/API'
import { useCookies } from 'next-client-cookies'
import { Loading } from '@carbon/react'
import { Loading, InlineNotification } from '@carbon/react'
import PaginationNav from '@carbon/react/lib/components/PaginationNav/PaginationNav'

// Data table headers.
Expand Down Expand Up @@ -39,23 +39,28 @@ const headers = [
type ClientResponse = {
clients: any[],
total_count: number,
count: number,
}

export default function Clients() {
const router = useRouter()
const cookies = useCookies()
const token = cookies.get('ows-access-token')
if (typeof token === "undefined") {
router.push("/authorize")
return
}
useEffect(() => {
if (typeof token === "undefined") {
router.push("/authorize")
}
}, [])

const [page, setPage] = useState<number>(0)
const [numPages, setNumPages] = useState<number>(1)
const [rows, setRows] = useState<any>([])
const [isLoading, setIsLoading] = useState<boolean>(true)
const [hasNotif, setHasNotif] = useState<boolean>(false)
const [notifData, setNotifData] = useState<{title: string,
subtitle: string }>({title: "", subtitle: ""})

useEffect(() => {
const fetchTable = () => {
GetClients(page, token as string).then((res) => {
if (!IsAPISuccess(res)) {
cookies.remove('ows-access-tokens')
Expand All @@ -76,7 +81,6 @@ export default function Clients() {
}))

setIsLoading(false)

const pageCount = Math.ceil((res as ClientResponse).total_count / 20)
if (pageCount !== numPages && pageCount > 0) {
setNumPages(pageCount)
Expand All @@ -86,7 +90,9 @@ export default function Clients() {
cookies.remove('ows-access-tokens')
router.push('/authorize')
})
}, [page])
}

useEffect(fetchTable, [page])

const pageChange = (newPage : number) => {
if (newPage === page) {
Expand All @@ -96,8 +102,45 @@ export default function Clients() {
setPage(newPage)
}

const onDelete = async (selectedRows : { id: string }[]) => {
setIsLoading(true)
let hasError = false
for (let i = 0; i < selectedRows.length; ++i) {
await DeleteClient(selectedRows[i].id, token as string).then((res) => {
if (IsAPIFailure(res)) {
hasError = true
}
}).catch(err => { hasError = true })
}

if (hasError) {
setNotifData({
title: "Error Deleting Clients",
subtitle: "You are not authorized to delete clients"
})
setHasNotif(true)
setTimeout(() => { setHasNotif(false) }, 5000)
}

fetchTable()
setIsLoading(false)
}

return (
<>
{
(hasNotif) ? (
<InlineNotification
kind="error"
onClose={() => setHasNotif(false) }
onCloseButtonClick={() => setHasNotif(false)}
statusIconDescription="notification"
subtitle={notifData.subtitle}
title={notifData.title}
style={{ position: "fixed", bottom: 5, left: 5}}
/>
) : null
}
{
(isLoading) ?
(<Loading id='decoration--landing' withOverlay={true} />)
Expand All @@ -112,6 +155,7 @@ export default function Clients() {
users for permission and, if granted, may securely access
their private data."
hasAddButton={true}
onDelete={onDelete}
/>
<PaginationNav itemsShown={5} totalItems={numPages} onChange={pageChange} />
</>
Expand Down
13 changes: 7 additions & 6 deletions dashboard/components/MyAccount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { UpdateUser, IsAPISuccess, IsAPIFailure } from '@/APIController/API'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
import { useState, useEffect } from 'react'
import { useCookies } from 'next-client-cookies'
import { Loading } from '@carbon/react'
import { Edit, EditOff } from '@carbon/icons-react'
Expand All @@ -27,13 +27,14 @@ const editButton = (isEditing : boolean, setIsEditing : Function) => {
}

export default function MyAccount({ user } : any) {
const cookies = useCookies()
const router = useRouter()
const cookies = useCookies()
const token = cookies.get('ows-access-token')
if (typeof token === "undefined") {
router.push("/authorize")
return
}
useEffect(() => {
if (typeof token === "undefined") {
router.push("/authorize")
}
}, [])

const headingColor = () => {
const { theme } = useTheme()
Expand Down
4 changes: 2 additions & 2 deletions dashboard/components/NavHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { Header, HeaderContainer, HeaderName, HeaderGlobalBar,
HeaderGlobalAction, SkipToContent, useTheme } from '@carbon/react'

const NavHeader = (props : { setTheme: Function }) => {
const cookies = useCookies()
const router = useRouter()
const cookies = useCookies()
const token = cookies.get('ows-access-token')

const themeSelector = () => {
Expand Down Expand Up @@ -38,7 +38,7 @@ const NavHeader = (props : { setTheme: Function }) => {
<Header aria-label="OpenWebServices">
<SkipToContent />
<HeaderName href="/" prefix="UF">OpenWebServices</HeaderName>
<p>v0.1.0-alpha</p>
<p>v0.1.4-alpha</p>
<HeaderGlobalBar>
{ themeSelector() }
{
Expand Down
2 changes: 1 addition & 1 deletion dashboard/components/Permissions/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { useCookies } from 'next-client-cookies'
import { useRouter } from 'next/navigation'

const PermissionsForm = (props: { client: any, state: string }) => {
const cookies = useCookies()
const router = useRouter()
const cookies = useCookies()

const headingColor = () => {
const { theme } = useTheme()
Expand Down
2 changes: 1 addition & 1 deletion dashboard/components/SigninForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { useCookies } from 'next-client-cookies'
import { useRouter } from 'next/navigation'

const SigninForm = (props: { setView: Function }) => {
const cookies = useCookies()
const router = useRouter()
const cookies = useCookies()
const headingColor = () => {
const { theme } = useTheme()
return (theme == "white") ? "black" : "white"
Expand Down
10 changes: 8 additions & 2 deletions dashboard/components/TableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
export default function TableView(props: {
rows: any, headers: any, title: string,
description: string, hasAddButton: boolean,
onDelete: Function,
}) {

const addButton = () => {
Expand All @@ -37,7 +38,8 @@ export default function TableView(props: {
getBatchActionProps,
selectRow,
getToolbarProps,
getSelectionProps
getSelectionProps,
selectedRows,
}) => {

const batchActionProps = {
Expand All @@ -59,7 +61,11 @@ export default function TableView(props: {
<TableBatchActions {...batchActionProps}>
<TableBatchAction
tabIndex={batchActionProps.shouldShowBatchActions ? 0 : -1}
renderIcon={TrashCan}>
renderIcon={TrashCan}
onClick={() => {
props.onDelete(selectedRows)
getBatchActionProps().onCancel()
}}>
Delete
</TableBatchAction>
</TableBatchActions>
Expand Down
Loading
Loading