allow one-to-one user relationship
This commit is contained in:
parent
5693657b54
commit
85af8a5859
@ -149,6 +149,14 @@
|
||||
editingFieldIdentifier.value = toIdentifier(editingFieldName.value)
|
||||
}
|
||||
|
||||
function updateNewFieldType (entityId: number) {
|
||||
newFields[entityId].relationshipType = newFields[entityId].type === 'USER' ? 'ONE_TO_MANY' : 'ONE_TO_ONE'
|
||||
}
|
||||
|
||||
function updateEditingFieldType () {
|
||||
editingRelationshipType.value = editingFieldType.value === 'USER' ? 'ONE_TO_MANY' : 'ONE_TO_ONE'
|
||||
}
|
||||
|
||||
async function addEntity () {
|
||||
const name = newEntityName.value.trim()
|
||||
const identifier = newEntityIdentifier.value.trim()
|
||||
@ -208,6 +216,8 @@
|
||||
if (!draft.targetEntityId) return
|
||||
values.targetEntityId = String(draft.targetEntityId)
|
||||
values.relationshipType = draft.relationshipType
|
||||
} else if (draft.type === 'USER') {
|
||||
values.relationshipType = draft.relationshipType
|
||||
}
|
||||
const response = await request(`/api/entity-definitions/${entity.id}/fields`, 'POST', values)
|
||||
if (!response.ok) throw new Error('Field create failed')
|
||||
@ -227,7 +237,7 @@
|
||||
editingFieldIdentifier.value = field.identifier
|
||||
editingFieldType.value = field.type
|
||||
editingTargetEntityId.value = field.targetEntityId
|
||||
editingRelationshipType.value = field.relationshipType ?? 'ONE_TO_ONE'
|
||||
editingRelationshipType.value = field.relationshipType ?? (field.type === 'USER' ? 'ONE_TO_MANY' : 'ONE_TO_ONE')
|
||||
}
|
||||
|
||||
async function saveField (entity: EntityDefinition, field: EntityField) {
|
||||
@ -244,6 +254,8 @@
|
||||
if (!editingTargetEntityId.value) return
|
||||
values.targetEntityId = String(editingTargetEntityId.value)
|
||||
values.relationshipType = editingRelationshipType.value
|
||||
} else if (editingFieldType.value === 'USER') {
|
||||
values.relationshipType = editingRelationshipType.value
|
||||
}
|
||||
const response = await request(`/api/entity-definitions/${entity.id}/fields/${field.id}`, 'PATCH', values)
|
||||
if (!response.ok) throw new Error('Field update failed')
|
||||
@ -346,6 +358,10 @@
|
||||
return type === 'ONE_TO_MANY' ? 'One to many' : 'One to one'
|
||||
}
|
||||
|
||||
function userRelationshipLabel (type?: RelationshipType) {
|
||||
return type === 'ONE_TO_ONE' ? 'One to one' : 'Many to one'
|
||||
}
|
||||
|
||||
function targetName (field: EntityField) {
|
||||
return field.targetEntityName
|
||||
?? entities.value.find(entity => entity.id === field.targetEntityId)?.name
|
||||
@ -488,7 +504,7 @@
|
||||
<input :id="`edit-field-identifier-${field.id}`" v-model="editingFieldIdentifier" required>
|
||||
<label class="sr-only" :for="`edit-type-${field.id}`">Field type</label>
|
||||
|
||||
<select :id="`edit-type-${field.id}`" v-model="editingFieldType">
|
||||
<select :id="`edit-type-${field.id}`" v-model="editingFieldType" @change="updateEditingFieldType">
|
||||
<option v-for="type in fieldTypes" :key="type" :value="type">{{ typeLabel(type) }}</option>
|
||||
</select>
|
||||
|
||||
@ -508,6 +524,15 @@
|
||||
</select>
|
||||
</template>
|
||||
|
||||
<template v-else-if="editingFieldType === 'USER'">
|
||||
<label class="sr-only" :for="`edit-user-relationship-${field.id}`">User relationship type</label>
|
||||
|
||||
<select :id="`edit-user-relationship-${field.id}`" v-model="editingRelationshipType">
|
||||
<option value="ONE_TO_MANY">Many to one</option>
|
||||
<option value="ONE_TO_ONE">One to one</option>
|
||||
</select>
|
||||
</template>
|
||||
|
||||
<button class="text-button" type="submit">Save field</button>
|
||||
<button class="text-button muted" type="button" @click="editingFieldId = undefined">Cancel</button>
|
||||
</form>
|
||||
@ -522,7 +547,9 @@
|
||||
{{ targetName(field) }} · {{ relationshipLabel(field.relationshipType) }}
|
||||
</span>
|
||||
|
||||
<span v-else-if="field.type === 'USER'" class="reference-detail">Built-in User entity</span>
|
||||
<span v-else-if="field.type === 'USER'" class="reference-detail">
|
||||
Built-in User entity · {{ userRelationshipLabel(field.relationshipType) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
@ -549,7 +576,7 @@
|
||||
<input :id="`new-field-identifier-${entity.id}`" v-model="newFields[entity.id].identifier" placeholder="Identifier" required>
|
||||
<label class="sr-only" :for="`new-type-${entity.id}`">Field type</label>
|
||||
|
||||
<select :id="`new-type-${entity.id}`" v-model="newFields[entity.id].type">
|
||||
<select :id="`new-type-${entity.id}`" v-model="newFields[entity.id].type" @change="updateNewFieldType(entity.id)">
|
||||
<option v-for="type in fieldTypes" :key="type" :value="type">{{ typeLabel(type) }}</option>
|
||||
</select>
|
||||
|
||||
@ -569,6 +596,15 @@
|
||||
</select>
|
||||
</template>
|
||||
|
||||
<template v-else-if="newFields[entity.id].type === 'USER'">
|
||||
<label class="sr-only" :for="`new-user-relationship-${entity.id}`">User relationship type</label>
|
||||
|
||||
<select :id="`new-user-relationship-${entity.id}`" v-model="newFields[entity.id].relationshipType">
|
||||
<option value="ONE_TO_MANY">Many to one</option>
|
||||
<option value="ONE_TO_ONE">One to one</option>
|
||||
</select>
|
||||
</template>
|
||||
|
||||
<button class="secondary-button" :disabled="saving" type="submit">Add field</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -184,9 +184,10 @@ test('admin can add, edit, and remove an entity and its fields', async ({ page }
|
||||
|
||||
await organizationFieldForm.getByLabel('New field').fill('Account owner')
|
||||
await organizationFieldForm.getByLabel('Field type').selectOption('USER')
|
||||
await organizationFieldForm.getByLabel('User relationship type').selectOption('ONE_TO_ONE')
|
||||
await organizationFieldForm.getByRole('button', { name: 'Add field' }).click()
|
||||
await expect(organization.locator('.type-badge').filter({ hasText: 'User reference' })).toBeVisible()
|
||||
await expect(organization.getByText('Built-in User entity')).toBeVisible()
|
||||
await expect(organization.getByText('Built-in User entity · One to one')).toBeVisible()
|
||||
|
||||
await organization.getByRole('button', { name: 'Remove entity' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Organization' })).not.toBeVisible()
|
||||
|
||||
@ -140,6 +140,11 @@ class EntityDefinitionController(
|
||||
}
|
||||
|
||||
private fun Context.relationshipDetails(fieldType: FieldType?): RelationshipDetails? {
|
||||
if (fieldType == FieldType.USER) {
|
||||
val relationshipType = formParam("relationshipType")?.let(RelationshipType::from)
|
||||
?: RelationshipType.ONE_TO_MANY
|
||||
return RelationshipDetails(null, relationshipType)
|
||||
}
|
||||
if (fieldType != FieldType.RELATIONSHIP) return RelationshipDetails(null, null)
|
||||
|
||||
val targetEntityId = formParam("targetEntityId")?.toLongOrNull()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user