diff --git a/app/Actions/Projects/BuildProjectTicketMetadataSettingsPayload.php b/app/Actions/Projects/BuildProjectTicketMetadataSettingsPayload.php index 3ab6fcf..b20bde4 100644 --- a/app/Actions/Projects/BuildProjectTicketMetadataSettingsPayload.php +++ b/app/Actions/Projects/BuildProjectTicketMetadataSettingsPayload.php @@ -34,8 +34,8 @@ class BuildProjectTicketMetadataSettingsPayload DuplicateProjectConfiguration::COPY_TICKET_FIELDS, DuplicateProjectConfiguration::COPY_TICKET_LINK_TYPES, ]), - 'ticketFieldDefinitions' => TicketFieldDefinitionResource::collection($project->ticketFieldDefinitions()->get())->resolve(), - 'ticketLinkTypes' => TicketLinkTypeResource::collection($project->ticketLinkTypes()->get())->resolve(), + 'ticketFieldDefinitions' => TicketFieldDefinitionResource::collection($project->ticketFieldDefinitions()->withCount('ticketFieldValues')->get())->resolve(), + 'ticketLinkTypes' => TicketLinkTypeResource::collection($project->ticketLinkTypes()->withCount('ticketLinks')->get())->resolve(), 'ticketPriorities' => TicketPriorityResource::collection($project->ticketPriorities()->get())->resolve(), 'ticketTypes' => TicketTypeResource::collection($project->ticketTypes()->withCount('tickets')->get())->resolve(), ]; diff --git a/app/Http/Resources/TicketFieldDefinitionResource.php b/app/Http/Resources/TicketFieldDefinitionResource.php index ed8596f..0e225e1 100644 --- a/app/Http/Resources/TicketFieldDefinitionResource.php +++ b/app/Http/Resources/TicketFieldDefinitionResource.php @@ -20,6 +20,7 @@ class TicketFieldDefinitionResource extends JsonResource 'label' => $this->label, 'position' => $this->position, 'project_id' => $this->project_id, + 'ticket_field_values_count' => $this->when(isset($this->ticket_field_values_count), (int) $this->ticket_field_values_count), 'created_at' => $this->created_at?->toISOString(), 'updated_at' => $this->updated_at?->toISOString(), ]; diff --git a/app/Http/Resources/TicketLinkTypeResource.php b/app/Http/Resources/TicketLinkTypeResource.php index 55bca63..9af1bd6 100644 --- a/app/Http/Resources/TicketLinkTypeResource.php +++ b/app/Http/Resources/TicketLinkTypeResource.php @@ -20,6 +20,7 @@ class TicketLinkTypeResource extends JsonResource 'counterpart_label' => $this->counterpart_label ?: $this->label, 'position' => $this->position, 'project_id' => $this->project_id, + 'ticket_links_count' => $this->when(isset($this->ticket_links_count), (int) $this->ticket_links_count), 'created_at' => $this->created_at?->toISOString(), 'updated_at' => $this->updated_at?->toISOString(), ]; diff --git a/resources/js/components/projects/TicketFieldDefinitionEditorDialog.vue b/resources/js/components/projects/TicketFieldDefinitionEditorDialog.vue new file mode 100644 index 0000000..48630f2 --- /dev/null +++ b/resources/js/components/projects/TicketFieldDefinitionEditorDialog.vue @@ -0,0 +1,267 @@ + + + diff --git a/resources/js/components/projects/TicketFieldDefinitionSettings.vue b/resources/js/components/projects/TicketFieldDefinitionSettings.vue new file mode 100644 index 0000000..75c606a --- /dev/null +++ b/resources/js/components/projects/TicketFieldDefinitionSettings.vue @@ -0,0 +1,142 @@ + + + diff --git a/resources/js/components/projects/TicketLinkTypeEditorDialog.vue b/resources/js/components/projects/TicketLinkTypeEditorDialog.vue new file mode 100644 index 0000000..74970cd --- /dev/null +++ b/resources/js/components/projects/TicketLinkTypeEditorDialog.vue @@ -0,0 +1,269 @@ + + + diff --git a/resources/js/components/projects/TicketLinkTypeSettings.vue b/resources/js/components/projects/TicketLinkTypeSettings.vue new file mode 100644 index 0000000..1a075bb --- /dev/null +++ b/resources/js/components/projects/TicketLinkTypeSettings.vue @@ -0,0 +1,135 @@ + + + diff --git a/resources/js/locales/en.ts b/resources/js/locales/en.ts index f0bcc11..fd2438c 100644 --- a/resources/js/locales/en.ts +++ b/resources/js/locales/en.ts @@ -960,4 +960,47 @@ export const en = { 'metadata.chooseType': 'Choose a type', 'metadata.parentReplacement': 'If any affected ticket has child tickets, choose a parent type. The server checks this before deleting.', + 'metadata.customFields': 'Custom fields', + 'metadata.customFieldsDescription': + 'Define the project-specific user and number fields shown on tickets.', + 'metadata.addField': 'Add field', + 'metadata.noCustomFields': 'No custom fields', + 'metadata.noCustomFieldsDescription': + 'Add a field when this project needs structured information beyond the standard ticket details.', + 'metadata.storedValues': 'Stored values: {count}', + 'metadata.editField': 'Edit {name}', + 'metadata.deleteField': 'Delete {name}', + 'metadata.fieldEditorHelp': + 'Choose a label and one of the supported field types. Existing ticket values remain attached when this definition is edited.', + 'metadata.deleteFieldHelp': + 'Delete this custom field? This action cannot be undone.', + 'metadata.fieldDeletionImpact': + 'Deleting this field also permanently removes {count} stored ticket values.', + 'metadata.fieldLabel': 'Field label', + 'metadata.fieldType': 'Field type', + 'metadata.fieldTypeHelp': + 'Only the field types already supported by this project are available.', + 'metadata.linkTypes': 'Link types', + 'metadata.linkTypesDescription': + 'Define the labels shown from each side of a ticket relationship.', + 'metadata.addLinkType': 'Add link type', + 'metadata.noLinkTypes': 'No link types', + 'metadata.noLinkTypesDescription': + 'Add a link type before tickets can be connected with a project-specific relationship.', + 'metadata.ticketRelationships': 'Ticket relationships: {count}', + 'metadata.linkDirection': '{source} points to {counterpart}', + 'metadata.editLinkType': 'Edit {name}', + 'metadata.deleteLinkType': 'Delete {name}', + 'metadata.linkTypeEditorHelp': + 'The source label is shown on the originating ticket; the counterpart label is shown on the linked ticket.', + 'metadata.deleteLinkTypeHelp': + 'Delete this link type? This action cannot be undone.', + 'metadata.linkTypeDeletionImpact': + 'Deleting this link type also permanently removes {count} ticket relationships.', + 'metadata.sourceLabel': 'Source label', + 'metadata.sourceLabelHelp': + 'Shown when viewing the ticket where the relationship starts.', + 'metadata.counterpartLabel': 'Counterpart label', + 'metadata.counterpartLabelHelp': + 'Shown when viewing the ticket at the other end of the relationship.', } as const; diff --git a/resources/js/pages/projects/settings/Metadata.vue b/resources/js/pages/projects/settings/Metadata.vue index 51cfdcf..41dd9f8 100644 --- a/resources/js/pages/projects/settings/Metadata.vue +++ b/resources/js/pages/projects/settings/Metadata.vue @@ -1,23 +1,13 @@