Skip to content
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
14 changes: 14 additions & 0 deletions src/components/CippComponents/CippAlertSnoozeDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
RadioGroup,
FormControlLabel,
Radio,
TextField,
Typography,
Box,
Stack,
Expand Down Expand Up @@ -35,6 +36,7 @@ export const CippAlertSnoozeDialog = ({
relatedQueryKeys,
}) => {
const [duration, setDuration] = useState('7')
const [reason, setReason] = useState('')
const [submitted, setSubmitted] = useState(false)

const snoozeRequest = ApiPostCall({
Expand All @@ -50,6 +52,7 @@ export const CippAlertSnoozeDialog = ({
TenantFilter: tenantFilter,
AlertItem: alertItem,
Duration: parseInt(duration, 10),
Reason: reason,
},
})
}
Expand All @@ -58,6 +61,7 @@ export const CippAlertSnoozeDialog = ({
setSubmitted(false)
snoozeRequest.reset()
setDuration('7')
setReason('')
onClose()
}

Expand Down Expand Up @@ -125,6 +129,16 @@ export const CippAlertSnoozeDialog = ({
/>
))}
</RadioGroup>
<TextField
label="Reason (optional)"
value={reason}
onChange={(e) => setReason(e.target.value)}
fullWidth
multiline
minRows={2}
sx={{ mt: 2 }}
placeholder="Why is this alert being snoozed?"
/>
</Box>
) : (
<CippApiResults apiObject={snoozeRequest} />
Expand Down
56 changes: 56 additions & 0 deletions src/components/CippComponents/CippIntuneDeviceActions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
AutoMode,
Recycling,
ManageAccounts,
GroupAdd,
} from '@mui/icons-material'

// Shared between the MEM devices list page and the View Device detail page.
Expand Down Expand Up @@ -73,6 +74,61 @@ export const getIntuneDeviceActions = ({ tenantFilter } = {}) => [
],
confirmText: 'Select the User to set as the primary user for [deviceName]',
},
{
label: 'Add to Group',
type: 'POST',
icon: <GroupAdd />,
url: '/api/EditGroup',
customDataformatter: (row, action, formData) => {
// Build the device list from selected devices - the backend resolves the Entra
// directory object id from azureADDeviceId
const rows = Array.isArray(row) ? row : [row]
const addDevice = rows.map((r) => ({
label: r.deviceName,
value: r.azureADDeviceId,
addedFields: {
azureADDeviceId: r.azureADDeviceId,
deviceName: r.deviceName,
},
}))

// Handle multiple groups - return an array of requests (one per group)
const selectedGroups = Array.isArray(formData.groupId) ? formData.groupId : [formData.groupId]

return selectedGroups.map((group) => ({
AddDevice: addDevice,
tenantFilter: tenantFilter,
groupId: group,
}))
},
fields: [
{
type: 'autoComplete',
name: 'groupId',
label: 'Select groups to add the device to',
multiple: true,
creatable: false,
validators: { required: 'Please select at least one group' },
api: {
url: '/api/ListGroups',
labelField: (option) =>
option?.calculatedGroupType
? `${option.displayName} (${option.calculatedGroupType})`
: (option?.displayName ?? ''),
valueField: 'id',
addedField: {
groupType: 'groupType',
groupName: 'displayName',
},
queryKey: `groups-${tenantFilter}`,
showRefresh: true,
},
},
],
confirmText: 'Are you sure you want to add [deviceName] to the selected groups?',
multiPost: false,
allowResubmit: true,
},
{
label: 'Rename Device',
type: 'POST',
Expand Down
8 changes: 7 additions & 1 deletion src/components/CippComponents/CippReportToolbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ export const CippReportToolbar = () => {
const [deleteDialog, setDeleteDialog] = useState({ open: false })
const [refreshDialog, setRefreshDialog] = useState({ open: false })

const defaultReportId =
settings.UserSpecificSettings?.defaultTestSuite?.value ||
settings.defaultTestSuite?.value ||
'ztna'
const selectedReport =
router.isReady && !router.query.reportId ? 'ztna' : router.query.reportId || 'ztna'
router.isReady && !router.query.reportId
? defaultReportId
: router.query.reportId || defaultReportId

const formControl = useForm({ mode: 'onChange' })
const reportIdValue = useWatch({ control: formControl.control })
Expand Down
23 changes: 23 additions & 0 deletions src/pages/cipp/preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ const Page = () => {
queryKey: "authmecipp",
});

// Test suites for the default Home page suite selector (shared cache with the dashboard)
const reportsApi = ApiGetCall({
url: "/api/ListTestReports",
queryKey: "ListTestReports",
});

const cleanedSettings = { ...settings };

if (cleanedSettings.offboardingDefaults?.keepCopy) {
Expand Down Expand Up @@ -287,6 +293,23 @@ const Page = () => {
/>
),
},
{
label: "Default test suite on the Home page",
value: (
<CippFormComponent
type="autoComplete"
creatable={false}
name="defaultTestSuite"
formControl={formcontrol}
multiple={false}
options={(reportsApi.data || []).map((report) => ({
value: report.id,
label: report.name,
}))}
isFetching={reportsApi.isFetching}
/>
),
},
{
label: "Added Attributes when creating a new user",
value: (
Expand Down
5 changes: 3 additions & 2 deletions src/pages/cipp/snooze-alert.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const durationLabel = (d) => {

const Page = () => {
const router = useRouter()
const { cmdlet, tenant, data, duration } = router.query
const { cmdlet, tenant, data, duration, reason } = router.query
const [submitted, setSubmitted] = useState(false)
const [parseError, setParseError] = useState(null)

Expand Down Expand Up @@ -54,9 +54,10 @@ const Page = () => {
TenantFilter: tenant,
AlertItem: alertItem,
Duration: durationNum,
Reason: reason || '',
},
})
}, [router.isReady, cmdlet, tenant, data, duration])
}, [router.isReady, cmdlet, tenant, data, duration, reason])

const preview = (() => {
if (!data) return null
Expand Down
8 changes: 7 additions & 1 deletion src/pages/dashboardv2/custom/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@ const Page = () => {
const settings = useSettings()
const { currentTenant } = settings
const router = useRouter()
const defaultReportId =
settings.UserSpecificSettings?.defaultTestSuite?.value ||
settings.defaultTestSuite?.value ||
'ztna'
const selectedReport =
router.isReady && !router.query.reportId ? 'ztna' : router.query.reportId || 'ztna'
router.isReady && !router.query.reportId
? defaultReportId
: router.query.reportId || defaultReportId

const testsApi = ApiGetCall({
url: '/api/ListTests',
Expand Down
8 changes: 7 additions & 1 deletion src/pages/dashboardv2/devices/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ const Page = () => {
const { currentTenant } = settings
const router = useRouter()
// Only use default if router is ready and reportId is still not present
const defaultReportId =
settings.UserSpecificSettings?.defaultTestSuite?.value ||
settings.defaultTestSuite?.value ||
'ztna'
const selectedReport =
router.isReady && !router.query.reportId ? 'ztna' : router.query.reportId || 'ztna'
router.isReady && !router.query.reportId
? defaultReportId
: router.query.reportId || defaultReportId

const testsApi = ApiGetCall({
url: '/api/ListTests',
Expand Down
8 changes: 7 additions & 1 deletion src/pages/dashboardv2/identity/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@ const Page = () => {
const { currentTenant } = settings
const router = useRouter()
// Only use default if router is ready and reportId is still not present
const defaultReportId =
settings.UserSpecificSettings?.defaultTestSuite?.value ||
settings.defaultTestSuite?.value ||
'ztna'
const selectedReport =
router.isReady && !router.query.reportId ? 'ztna' : router.query.reportId || 'ztna'
router.isReady && !router.query.reportId
? defaultReportId
: router.query.reportId || defaultReportId

const testsApi = ApiGetCall({
url: '/api/ListTests',
Expand Down
10 changes: 8 additions & 2 deletions src/pages/dashboardv2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,16 @@ const Page = () => {
const [portalMenuItems, setPortalMenuItems] = useState([])
const isWide = useMediaQuery('(min-width:1513px)')
const [reportsMenuAnchor, setReportsMenuAnchor] = useState(null)
// Get reportId from query params or default to "ztna"
// Get reportId from query params or default to the user's preferred suite (Preferences page)
// Only use default if router is ready and reportId is still not present
const defaultReportId =
settings.UserSpecificSettings?.defaultTestSuite?.value ||
settings.defaultTestSuite?.value ||
'ztna'
const selectedReport =
router.isReady && !router.query.reportId ? 'ztna' : router.query.reportId || 'ztna'
router.isReady && !router.query.reportId
? defaultReportId
: router.query.reportId || defaultReportId

// Fetch available reports (shared cache with CippReportToolbar)
const reportsApi = ApiGetCall({
Expand Down
43 changes: 43 additions & 0 deletions src/pages/identity/administration/groups/edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const EditGroup = () => {
RemoveOwner: [],
AddContact: [],
RemoveContact: [],
AddDevice: [],
AddLicenses: [],
RemoveLicenses: [],
visibility: 'Public',
Expand Down Expand Up @@ -113,6 +114,7 @@ const EditGroup = () => {
RemoveOwner: [],
AddContact: [],
RemoveContact: [],
AddDevice: [],
AddLicenses: [],
RemoveLicenses: [],
}
Expand Down Expand Up @@ -310,6 +312,47 @@ const EditGroup = () => {
/>
</Grid>

{groupType !== 'Distribution List' && groupType !== 'Mail-Enabled Security' && (
<Grid size={{ xs: 12 }}>
<CippFormComponent
type="autoComplete"
name="AddDevice"
label="Add Devices"
formControl={formControl}
multiple={true}
creatable={false}
isFetching={groupInfo.isFetching}
disabled={groupInfo.isFetching}
api={{
url: '/api/ListGraphRequest',
dataKey: 'Results',
data: {
Endpoint: 'devices',
manualPagination: true,
$select: 'id,displayName,operatingSystem',
$count: true,
$orderby: 'displayName',
$top: 999,
},
labelField: (option) =>
option?.operatingSystem
? `${option.displayName} (${option.operatingSystem})`
: (option?.displayName ?? ''),
valueField: 'id',
addedField: {
displayName: 'displayName',
},
queryKey: `ListDevices-${tenantFilter}`,
dataFilter: (options) =>
options.filter(
(option) => !groupInfo.data?.members?.some((m) => m.id === option.value)
),
showRefresh: true,
}}
/>
</Grid>
)}

<Grid size={{ xs: 12 }}>
<Divider sx={{ my: 2 }} />
<Typography variant="h6">Remove Members</Typography>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const Page = () => {
'CmdletName',
'Tenant',
'ContentPreview',
'SnoozeReason',
'SnoozedBy',
'Status',
'RemainingDays',
Expand Down