-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into jf/uaa-login
- Loading branch information
Showing
32 changed files
with
2,410 additions
and
24 deletions.
There are no files selected for viewing
128 changes: 128 additions & 0 deletions
128
training-front-end/src/components/AdminAgencySelect.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
<script setup> | ||
import { ref, computed} from "vue" | ||
const emit = defineEmits(['checkItem']) | ||
const props = defineProps({ | ||
'items': { | ||
type: Array, | ||
required: false, | ||
default: undefined | ||
}, | ||
'values': { | ||
type: Array, | ||
required: true | ||
}, | ||
'parent': { | ||
type: Object, | ||
required: true | ||
} | ||
}) | ||
const filtertext = ref('') | ||
function isChecked(id) { | ||
return props.values.some(item => item.id == id) | ||
} | ||
function selectAllBureaus(){ | ||
for (const item of filtereditems.value) { | ||
// don't add items twice | ||
if (!props.values.some(p => p.id ==item.id)){ | ||
emit('checkItem', item, true) | ||
} | ||
} | ||
} | ||
const hasSubAgencies = computed(() => props.items && props.items.length > 0) | ||
const filtereditems = computed(() => props.items && props.items.filter( | ||
item => item | ||
.name | ||
.toLowerCase() | ||
.split(/\W+/) | ||
.some(word => word | ||
.toLowerCase() | ||
.startsWith(filtertext.value.toLowerCase())) | ||
)) | ||
</script> | ||
|
||
<template> | ||
<div | ||
id="item-container" | ||
class="usa-prose" | ||
> | ||
<fieldset | ||
id="agencies" | ||
class="usa-fieldset" | ||
> | ||
<label | ||
v-if="hasSubAgencies" | ||
class="usa-label margin-top-0" | ||
for="agency-search" | ||
> | ||
Filter by sub-agency name | ||
</label> | ||
<input | ||
v-if="hasSubAgencies" | ||
id="agency-search" | ||
v-model="filtertext" | ||
class="agency-filter usa-input margin-bottom-2" | ||
name="agency-search" | ||
type="text" | ||
> | ||
<button | ||
v-if="hasSubAgencies" | ||
id="select-all" | ||
class="usa-button usa-button--unstyled margin-bottom-2" | ||
@click="selectAllBureaus" | ||
> | ||
Select all | ||
</button> | ||
<div | ||
id="selected-agencies" | ||
class="list maxh-card-lg overflow-y-scroll padding-bottom-1" | ||
> | ||
<div | ||
v-if="!hasSubAgencies" | ||
class="usa-checkbox" | ||
> | ||
<input | ||
:id="parent.id" | ||
class="usa-checkbox__input" | ||
type="checkbox" | ||
name="agencies[]" | ||
:value="parent.id" | ||
:checked="isChecked(parent.id)" | ||
@change="$emit('checkItem', parent, $event.target.checked)" | ||
> | ||
<label | ||
class="usa-checkbox__label agency-name" | ||
:for="parent.id" | ||
> | ||
{{ parent.name }} | ||
</label> | ||
</div> | ||
<div | ||
v-for="item in filtereditems" | ||
:key="item.id" | ||
class="usa-checkbox border-top-1px border-base-lighter padding-bottom-2" | ||
> | ||
<input | ||
:id="item.id" | ||
class="usa-checkbox__input" | ||
type="checkbox" | ||
name="agencies[]" | ||
:value="item.id" | ||
:checked="isChecked(item.id)" | ||
@change="$emit('checkItem', item, $event.target.checked)" | ||
> | ||
<label | ||
class="usa-checkbox__label agency-name" | ||
:for="item.id" | ||
> | ||
{{ item.name }} | ||
</label> | ||
</div> | ||
</div> | ||
</fieldset> | ||
</div> | ||
</template> |
215 changes: 215 additions & 0 deletions
215
training-front-end/src/components/AdminEditReporting.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
<script setup> | ||
import { reactive, watch, ref, computed } from "vue" | ||
import AdminAgencySelect from "./AdminAgencySelect.vue"; | ||
import DeleteIcon from "./icons/DeleteIcon.vue"; | ||
import USWDSComboBox from "./USWDSComboBox.vue"; | ||
import { bureauList, agencyList, setSelectedAgencyId, selectedAgencyId} from '../stores/agencies' | ||
import { useStore } from '@nanostores/vue' | ||
const props = defineProps({ | ||
user: { | ||
type: Object, | ||
required: true, | ||
} | ||
}) | ||
// Copy to avoid modifying parent prop and allow cancelling edits | ||
const agencies = ref([...props.user.report_agencies]) | ||
defineEmits(['cancel', 'save']) | ||
const agency_options = useStore(agencyList) | ||
const bureaus = useStore(bureauList) | ||
const agencyId = useStore(selectedAgencyId) | ||
const user_input = reactive({ | ||
agency_id: undefined, | ||
}) | ||
const selectedAgency = computed(() => agency_options.value.find(agency => agency.id == agencyId.value)) | ||
function editUserAgencies(e, checked) { | ||
if (checked) { | ||
agencies.value.push({ | ||
id: e.id, | ||
name: selectedAgency.value.name, | ||
bureau: agencyId.value == e.id ? undefined : e.name | ||
}) | ||
} else { | ||
agencies.value = agencies.value.filter(agency => agency.id != e.id) | ||
} | ||
} | ||
watch(() => user_input.agency_id, async() => { | ||
setSelectedAgencyId(user_input.agency_id) | ||
}) | ||
</script> | ||
|
||
<template> | ||
<div class="usa-prose"> | ||
<h3> | ||
Edit User | ||
</h3> | ||
</div> | ||
<div class="grid-row grid-gap"> | ||
<div class="tablet:grid-col"> | ||
<label | ||
for="input-full-name" | ||
class="usa-label" | ||
> | ||
Full Name | ||
</label> | ||
<input | ||
id="input-full-name" | ||
class="usa-input bg-base-lightest" | ||
name="input-full-name" | ||
:value="user.name" | ||
disabled | ||
> | ||
</div> | ||
<div class="tablet:grid-col"> | ||
<label | ||
for="input-email" | ||
class="usa-label" | ||
> | ||
Full Name | ||
</label> | ||
<input | ||
id="input-email" | ||
class="usa-input bg-base-lightest" | ||
name="input-email" | ||
:value="user.email" | ||
disabled | ||
> | ||
</div> | ||
</div> | ||
<div class="grid-row grid-gap"> | ||
<div class="tablet:grid-col"> | ||
<label | ||
for="input-agency" | ||
class="usa-label" | ||
> | ||
Agency / Organization | ||
</label> | ||
<input | ||
id="input-agency" | ||
class="usa-input bg-base-lightest" | ||
name="input-agency" | ||
:value="user.agency.name" | ||
disabled | ||
> | ||
</div> | ||
<div class="tablet:grid-col"> | ||
<label | ||
class="usa-label" | ||
for="input-bureau" | ||
> | ||
Sub-Agency, Organization, or Bureau | ||
</label> | ||
<input | ||
id="input-bureau" | ||
class="usa-input bg-base-lightest" | ||
name="input-bureau" | ||
:value="user.agency.bureau" | ||
disabled | ||
> | ||
</div> | ||
</div> | ||
|
||
<section class="margin-top-5"> | ||
<div class="usa-prose"> | ||
<h4> | ||
Add Agency/Organization Reporting Access | ||
</h4> | ||
</div> | ||
<div class="grid-row grid-gap"> | ||
<div class="tablet:grid-col"> | ||
<USWDSComboBox | ||
v-model="user_input.agency_id" | ||
:items="agency_options" | ||
name="agency" | ||
label="Which agency or organization should this person receive reports for?" | ||
/> | ||
|
||
<div | ||
v-if="user_input.agency_id" | ||
class="border-1px padding-2 margin-top-2" | ||
> | ||
<AdminAgencySelect | ||
:items="bureaus" | ||
:values="agencies" | ||
:parent="selectedAgency" | ||
@check-item="editUserAgencies" | ||
/> | ||
</div> | ||
<div class="margin-top-3"> | ||
<button | ||
id="update-user" | ||
class="usa-button" | ||
@click="$emit('save', user.id, agencies)" | ||
> | ||
Update | ||
</button> | ||
</div> | ||
<button | ||
id="cancel" | ||
type="button" | ||
class="usa-button usa-button--unstyled margin-y-2" | ||
@click="$emit('cancel')" | ||
> | ||
Cancel and return to search results | ||
</button> | ||
</div> | ||
<div class="tablet:grid-col"> | ||
<table class="usa-table usa-table--borderless width-full"> | ||
<thead> | ||
<tr> | ||
<th | ||
scope="col" | ||
class="text-no-wrap" | ||
> | ||
Agency/Organization | ||
</th> | ||
<th | ||
scope="col" | ||
class="text-no-wrap" | ||
> | ||
Sub-Agency, Org, or Bureau | ||
</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr v-if="agencies.length == 0"> | ||
<td colspan="4"> | ||
None | ||
</td> | ||
</tr> | ||
<tr | ||
v-for="agency in agencies" | ||
:key="agency.id" | ||
> | ||
<td> | ||
{{ agency.name }} | ||
</td> | ||
<td> | ||
<div class="display-flex flex-justify"> | ||
<div> | ||
{{ agency.bureau }} | ||
</div> | ||
<div class="flex-align-self-center"> | ||
<button | ||
class="usa-button usa-button--unstyled font-serif-lg" | ||
@click="editUserAgencies(agency, false)" | ||
> | ||
<DeleteIcon /> | ||
</button> | ||
</div> | ||
</div> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
</section> | ||
</template> |
Oops, something went wrong.