Skip to content

Commit

Permalink
Merge pull request #84 from KelvinTegelaar/dev
Browse files Browse the repository at this point in the history
[pull] dev from KelvinTegelaar:dev
  • Loading branch information
BNWEIN authored Mar 18, 2024
2 parents 254d3c8 + ff0eacb commit 8b9e13e
Show file tree
Hide file tree
Showing 24 changed files with 1,089 additions and 7,284 deletions.
7,820 changes: 737 additions & 7,083 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cipp",
"version": "5.2.1",
"version": "5.3.1",
"description": "The CyberDrain Improved Partner Portal is a portal to help manage administration for Microsoft Partners.",
"homepage": "https://cipp.app/",
"bugs": {
Expand Down
2 changes: 1 addition & 1 deletion public/version_latest.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.2.1
5.3.1
3 changes: 2 additions & 1 deletion src/components/forms/RFFComponents.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,11 @@ export const RFFCFormInput = ({
disabled = false,
spellCheck = true,
autoFocus = false,
hiddenValue,
onChange,
}) => {
return (
<Field name={name} validate={validate}>
<Field initialValue={hiddenValue} name={name} validate={validate}>
{({ input, meta }) => {
const handleChange = onChange
? (e) => {
Expand Down
10 changes: 6 additions & 4 deletions src/components/header/AppHeaderSearch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback } from 'react'
import { faSearch } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { toggleSwitcher } from 'src/store/features/switcher'
import { CButton } from '@coreui/react'
import { CButton, CTooltip } from '@coreui/react'
import { useDispatch } from 'react-redux'

const AppHeaderSearch = () => {
Expand All @@ -12,9 +12,11 @@ const AppHeaderSearch = () => {
}, [dispatch])
return (
<>
<CButton variant="ghost" onClick={handleFastSwitcher}>
<FontAwesomeIcon icon={faSearch} size="lg" />
</CButton>
<CTooltip content="Search" placement="bottom">
<CButton variant="ghost" onClick={handleFastSwitcher}>
<FontAwesomeIcon icon={faSearch} size="lg" />
</CButton>
</CTooltip>
</>
)
}
Expand Down
96 changes: 87 additions & 9 deletions src/components/layout/AppHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,25 @@ import { useSelector, useDispatch } from 'react-redux'
import {
CAlert,
CAlertLink,
CContainer,
CCollapse,
CHeader,
CHeaderNav,
CNavItem,
CHeaderToggler,
CImage,
CSidebarBrand,
CButton,
CFormSwitch,
CTooltip,
} from '@coreui/react'
import { AppHeaderSearch } from 'src/components/header'
import { TenantSelector } from '../utilities'
import { CippActionsOffcanvas, TenantSelector } from '../utilities'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faBars } from '@fortawesome/free-solid-svg-icons'
import { setCurrentTheme, setUserSettings, toggleSidebarShow } from 'src/store/features/app'
import { useMediaPredicate } from 'react-media-hook'
import { useGenericGetRequestQuery, useLoadAlertsDashQuery } from 'src/store/api/app'
import {
useGenericGetRequestQuery,
useLazyGenericGetRequestQuery,
useLoadAlertsDashQuery,
} from 'src/store/api/app'
import { useLocation } from 'react-router-dom'

const AppHeader = () => {
Expand All @@ -31,6 +32,11 @@ const AppHeader = () => {
const sidebarShow = useSelector((state) => state.app.sidebarShow)
const currentTheme = useSelector((state) => state.app.currentTheme)
const preferredTheme = useMediaPredicate('(prefers-color-scheme: dark)') ? 'impact' : 'cyberdrain'
const [cippQueueExtendedInfo, setCippQueueExtendedInfo] = useState([])
const [cippQueueVisible, setCippQueueVisible] = useState(false)
const [cippQueueRefresh, setCippQueueRefresh] = useState(
(Math.random() + 1).toString(36).substring(7),
)
const { data: dashboard } = useLoadAlertsDashQuery()
const {
data: userSettings,
Expand All @@ -54,6 +60,49 @@ const AppHeader = () => {
userSettings,
])

const [getCippQueueList, cippQueueList] = useLazyGenericGetRequestQuery()

function loadCippQueue() {
setCippQueueVisible(true)
getCippQueueList({ path: 'api/ListCippQueue', params: { refresh: cippQueueRefresh } })
}

function refreshCippQueue() {
setCippQueueRefresh((Math.random() + 1).toString(36).substring(7))
loadCippQueue()
}

useEffect(() => {
if (cippQueueList.isFetching || cippQueueList.isLoading) {
setCippQueueExtendedInfo([
{
label: 'Fetching recent jobs',
value: 'Please wait',
timestamp: Date(),
link: '#',
},
])
}
if (
cippQueueList.isSuccess &&
Array.isArray(cippQueueList.data) &&
cippQueueList.data.length > 0
) {
setCippQueueExtendedInfo(
cippQueueList.data?.map((job) => ({
label: `${job.Name}`,
value: job.Status,
link: job.Link,
timestamp: job.Timestamp,
})),
)
} else {
setCippQueueExtendedInfo([
{ label: 'No jobs to display', value: '', timpestamp: Date(), link: '#' },
])
}
}, [cippQueueList])

const SwitchTheme = () => {
let targetTheme = preferredTheme
if (isDark) {
Expand Down Expand Up @@ -89,14 +138,23 @@ const AppHeader = () => {
target="_blank"
href={`https://docs.cipp.app/user-documentation${location.pathname}`}
>
<CButton variant="ghost">
<FontAwesomeIcon icon={'question'} size="lg" />
</CButton>
<CTooltip content="Documentation" placement="bottom">
<CButton variant="ghost">
<FontAwesomeIcon icon={'question'} size="lg" />
</CButton>
</CTooltip>
</a>
</CNavItem>
<CNavItem>
<AppHeaderSearch />
</CNavItem>
<CNavItem>
<CTooltip content="Recent Jobs" placement="bottom">
<CButton variant="ghost" onClick={() => loadCippQueue()} className="me-1">
<FontAwesomeIcon icon={'history'} size="lg" />
</CButton>
</CTooltip>
</CNavItem>
<CNavItem>
<div className="custom-switch-wrapper primary">
<CFormSwitch
Expand Down Expand Up @@ -134,6 +192,26 @@ const AppHeader = () => {
</div>
))}
</div>
<CippActionsOffcanvas
title="Recent Jobs"
extendedInfo={[]}
cards={cippQueueExtendedInfo}
refreshFunction={refreshCippQueue}
actions={[
{
label: 'Clear History',
color: 'info',
modal: true,
modalUrl: `/api/RemoveCippQueue`,
modalMessage: 'Are you sure you want clear the history?',
icon: <FontAwesomeIcon icon="trash" className="me-2" />,
},
]}
placement="end"
visible={cippQueueVisible}
id="cipp-queue"
hideFunction={() => setCippQueueVisible(false)}
/>
</>
)
}
Expand Down
11 changes: 5 additions & 6 deletions src/components/tables/CellTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function cellTable(
propertyName,
checkWhenZero = false,
crossWhenZero = false,
dangerButton = false, // Added 4th parameter for btn-danger class
dangerButton = false,
) {
var columnProp = ''
if (propertyName) {
Expand All @@ -21,10 +21,10 @@ export default function cellTable(
}

if (!Array.isArray(columnProp) && typeof columnProp === 'object') {
columnProp = Object.entries(columnProp).map((row) => {
return { Name: row[0], Value: row[1] }
})
} else if (Array.isArray(columnProp) && typeof Object.entries(columnProp)[0][1] !== 'object') {
columnProp = [columnProp]
}

if (Array.isArray(columnProp) && typeof columnProp[0] !== 'object') {
columnProp = columnProp.map((row) => {
return {
Value: row,
Expand Down Expand Up @@ -77,7 +77,6 @@ export default function cellTable(
return <FontAwesomeIcon icon={faCheckCircle} className="text-success" />
}

// Use dangerButton to determine button class
const buttonClassName = dangerButton ? 'btn-danger' : ''
return (
<CButton
Expand Down
24 changes: 24 additions & 0 deletions src/components/tables/CippDatatable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,36 @@ export default function CippDatatable({ path, params, ...rest }) {
refetch,
} = useListDatatableQuery({ path, params: { $filter: graphFilter, ...params } })

let anonimized = false // Assuming default value is false
const regex = new RegExp('^[A-Z0-9]+$')
const principalNameOrUPN =
data[0]?.userPrincipalName ??
data[0]?.UPN ??
data.Results?.[0]?.upn ??
data.Results?.[0]?.userPrincipalName

if (principalNameOrUPN && regex.test(principalNameOrUPN)) {
anonimized = true
}

var defaultFilterText = ''
if (params?.Parameters?.$filter) {
defaultFilterText = 'Graph: ' + params?.Parameters?.$filter
}
return (
<>
{anonimized && (
<CCallout color="info">
This table might contain anonymized data. Please check this
<a
className="m-1"
href="https://docs.cipp.app/troubleshooting/frequently-asked-questions#my-usernames-or-sites-are-guids-or-blank"
>
documentation link
</a>
to resolve this.
</CCallout>
)}
{data?.Metadata?.Queued && <CCallout color="info">{data?.Metadata?.QueueMessage}</CCallout>}
<CippTable
{...rest}
Expand Down
20 changes: 12 additions & 8 deletions src/components/tables/CippTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export default function CippTable({
const [filterviaURL, setFilterviaURL] = React.useState(false)
const [originalColumns, setOrginalColumns] = React.useState(columns)
const [updatedColumns, setUpdatedColumns] = React.useState(columns)
if (defaultColumns && defaultColumnsSet === false) {
if (defaultColumns && defaultColumnsSet === false && endpointName) {
const defaultColumnsArray = defaultColumns.split(',').filter((item) => item)

const actionsColumn = columns.length > 0 ? columns[columns.length - 1] : null
Expand All @@ -180,11 +180,13 @@ export default function CippTable({
let newColumns = tempColumns.filter(
(column) => defaultColumnsArray.includes(column.exportSelector) || column === actionsColumn,
)

setUpdatedColumns(newColumns)
setDefaultColumnsSet(true)
}

if (!endpointName && defaultColumnsSet === false) {
setUpdatedColumns(columns)
setDefaultColumnsSet(true)
}
const [selectedRows, setSelectedRows] = React.useState(false)
const [genericGetRequest, getResults] = useLazyGenericGetRequestQuery()
const [genericPostRequest, postResults] = useLazyGenericPostRequestQuery()
Expand Down Expand Up @@ -342,10 +344,12 @@ export default function CippTable({
useEffect(() => {
if (columns.length !== updatedColumns.length) {
setUpdatedColumns(updatedColumns)
setColumnDefaultLayout(
endpointName,
updatedColumns.map((column) => column.exportSelector).join(','),
)
if (endpointName) {
setColumnDefaultLayout(
endpointName,
updatedColumns.map((column) => column.exportSelector).join(','),
)
}
}
}, [
columns,
Expand Down Expand Up @@ -971,7 +975,7 @@ export default function CippTable({
responsive={responsive}
dense={dense}
striped={striped}
columns={updatedColumns}
columns={dynamicColumns ? updatedColumns : columns}
data={filteredItems}
expandableRows={expandableRows}
expandableRowsComponent={expandableRowsComponent}
Expand Down
23 changes: 13 additions & 10 deletions src/components/utilities/CippActionsOffcanvas.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,10 @@ export default function CippActionsOffcanvas(props) {
cardContent = props.cards.map((action, index) => (
<>
<CCard key={index} className="border-top-dark border-top-3 mb-3">
<CCardBody>
<CCardHeader className="d-flex justify-content-between align-items-center">
<CCardTitle>Report Name: {action.label}</CCardTitle>
</CCardHeader>
<CCardBody>
<CCardText>
{action.value && <Link to={action.link}>Status: {action.value}</Link>}
</CCardText>
Expand Down Expand Up @@ -325,15 +327,16 @@ export default function CippActionsOffcanvas(props) {
{getResults.isError && (
<CCallout color="danger">Could not connect to API: {getResults.error.message}</CCallout>
)}

<CCard className="content-card">
<CCardHeader className="d-flex justify-content-between align-items-center">
<CCardTitle>
<FontAwesomeIcon icon={faGlobe} className="mx-2" /> Extended Information
</CCardTitle>
</CCardHeader>
<CCardBody>{extendedInfoContent}</CCardBody>
</CCard>
{!cardContent && (
<CCard className="content-card">
<CCardHeader className="d-flex justify-content-between align-items-center">
<CCardTitle>
<FontAwesomeIcon icon={faGlobe} className="mx-2" /> Extended Information
</CCardTitle>
</CCardHeader>
<CCardBody>{extendedInfoContent}</CCardBody>
</CCard>
)}
{cardContent && cardContent}
{<COffcanvasTitle>Actions</COffcanvasTitle>}
<CListGroup>
Expand Down
40 changes: 40 additions & 0 deletions src/components/utilities/CippTableOffcanvas.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import { CippOffcanvas } from 'src/components/utilities'
import PropTypes from 'prop-types'
import { CippDatatable } from '../tables'

function CippTableOffcanvas({
state: visible,
hideFunction,
title = 'Table',
path,
params,
columns,
tableProps,
}) {
return (
<>
<CippOffcanvas
title={title}
addedClass="offcanvas-large"
placement="end"
visible={visible}
hideFunction={hideFunction}
>
<CippDatatable path={path} params={params} columns={columns} tableProps={tableProps} />
</CippOffcanvas>
</>
)
}

CippTableOffcanvas.propTypes = {
state: PropTypes.bool,
hideFunction: PropTypes.func,
title: PropTypes.string,
path: PropTypes.string,
params: PropTypes.object,
columns: PropTypes.object,
tableProps: PropTypes.object,
}

export default CippTableOffcanvas
Loading

0 comments on commit 8b9e13e

Please sign in to comment.