Added support for updating custom fields.

This commit is contained in:
Colin Williams
2023-03-19 18:01:57 -07:00
committed by GitHub
parent a627aaa423
commit e552ff377e
7 changed files with 159 additions and 44 deletions
+20
View File
@@ -0,0 +1,20 @@
export enum CustomFieldType {
Number = 'number',
Text = 'text',
Date = 'date',
}
export interface CustomField {
id: number;
type: CustomFieldType;
label: string;
value_string: string | null;
value: string | null;
bundle: unknown | null;
member_edit_own: boolean;
}
export interface CustomFieldUpdate {
id: number;
value: string | null;
}
+66 -5
View File
@@ -1,5 +1,7 @@
import HttpUtils from './httpUtils'
import { CustomFieldUpdate } from './customField'
import { Entity, EntityType } from './entity'
import type { Group } from './group'
import HttpUtils from './httpUtils'
import type { Member, MemberUpdate } from './member'
const D4H_FETCH_LIMIT = 250
@@ -31,7 +33,7 @@ export default class D4H {
/**************** MEMBERS *******************/
/********************************************/
getMemberAsync(id: number, options?: GetMemberOptions): Promise<Member> {
async getMemberAsync(id: number, options?: GetMemberOptions): Promise<Member> {
const url = new URL(`${D4H_BASE_URL}/team/members/${id}`)
if (options !== undefined) {
@@ -42,10 +44,13 @@ export default class D4H {
}
}
return this._httpUtils.getAsync<Member>(url)
const member = await this._httpUtils.getAsync<Member>(url)
member.type = EntityType.Member
return member
}
getMembersAsync(options?: GetMembersOptions): Promise<Member[]> {
async getMembersAsync(options?: GetMembersOptions): Promise<Member[]> {
const url = new URL(`${D4H_BASE_URL}/team/members`)
if (options !== undefined) {
@@ -64,7 +69,10 @@ export default class D4H {
}
}
return this._httpUtils.getManyAsync(url)
const members = await this._httpUtils.getManyAsync<Member>(url)
members.forEach(m => m.type = EntityType.Member)
return members
}
updateMemberAsync(id: number, updates: MemberUpdate): Promise<Member> {
@@ -98,4 +106,57 @@ export default class D4H {
return this._httpUtils.getManyAsync(url)
}
/********************************************/
/************** CUSTOM FIELDS ***************/
/********************************************/
updateCustomFields(entity: Entity, updates: CustomFieldUpdate[], onlyMemberEditOwn: boolean): Promise<void> {
const url = new URL(`${D4H_BASE_URL}/team/custom-fields/${entity.type}/${entity.id}`)
// From the documentation:
// https://api.d4h.org/v2/documentation#operation/putTeamCustomfieldsEntity_typeEntity_id
// The PUT action for fields is distinguished by Bundle. If you include one field's value
// from a bundle (or an unbundled field's value) you must include values for all fields
// of that bundle (or all unbundled fields)
// ----------------------------------------------------------------------------------------
// To ensure a mistake doesn't occur, let's ensure that *all* custom fields from the original
// entity are in the list of updates.
// At this time all entities we're working with have custom fields. As a result, throw an
// error if none are found. This most likely indicates the original request was made without
// including custom fields.
const originalCustomFields = entity.custom_fields
if (!originalCustomFields) {
throw new Error('Cannot update custom fields for an entity with no custom fields. Ensure your original request included custom fields.')
}
// For any fields not being changed, back fill from the original entity to ensure
// they retain the same value.
for (const field of originalCustomFields) {
if (field.bundle !== null) {
throw new Error('One or more custom fields on the entity are part of a bundle. Bundles are not supported.')
}
const update = updates.find((u) => u.id == field.id)
if (update && onlyMemberEditOwn && !field.member_edit_own) {
throw new Error('onlyMemberEditOwn specified, but attempting to update non-memberEditOwn field.')
} else if (!update) {
let include = true
if (onlyMemberEditOwn && !field.member_edit_own) {
include = false
}
if (include) {
updates.push({
id: field.id,
value: field.value
})
}
}
}
return this._httpUtils.putAsync(url, { fields: updates })
}
}
+16
View File
@@ -0,0 +1,16 @@
import { CustomField } from './customField'
export interface Entity {
custom_fields?: CustomField[];
id: number;
type: EntityType;
}
// EntityType must be one of:
// event, exercise, gear, healthsafety_report, incident,
// incident.weather, member, person_involved, unit, activity
//
// Only the ones actively in use are implemented.
export enum EntityType {
Member = 'member',
}
+1 -1
View File
@@ -33,7 +33,7 @@ export default class HttpUtils {
'Content-Type': 'application/json'
}
console.log(url)
console.log(`${method}: ${url.toString()}\n${JSON.stringify(body)}`)
const options: RequestInit = {
method,
+2 -16
View File
@@ -1,16 +1,4 @@
export enum CustomFieldType {
Number = 'number',
Text = 'text',
Date = 'date',
}
export interface CustomField {
id: number;
type: CustomFieldType;
label: string;
value_string: string | null;
value: string | null;
}
import { Entity } from './entity'
export interface EmergencyContact {
name: string | null;
@@ -31,14 +19,12 @@ export interface MemberStatusLabel {
value: string;
}
export interface Member {
export interface Member extends Entity {
address: string;
custom_fields?: CustomField[];
email: string | null;
emergency_contacts: EmergencyContact[];
group_ids: number[] | null;
homephone: string;
id: number;
mobilephone: string;
name: string;
notes: string | null;