Skip to content

Commit

Permalink
Merge pull request #17513 from opf/refactor/decorated-select
Browse files Browse the repository at this point in the history
Remove decorated select field in favor of opce-autocomplete
  • Loading branch information
oliverguenther authored Jan 7, 2025
2 parents 5d832b8 + d17d253 commit 4d9254a
Show file tree
Hide file tree
Showing 23 changed files with 160 additions and 350 deletions.
6 changes: 6 additions & 0 deletions app/models/custom_actions/actions/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ def allowed_values
raise NotImplementedError
end

def value_objects
values.map do |value|
allowed_values.find { |v| v[:value] == value }
end
end

def type
raise NotImplementedError
end
Expand Down
6 changes: 6 additions & 0 deletions app/models/custom_actions/conditions/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ def allowed_values
.map { |value, label| { value:, label: } }
end

def value_objects
values.map do |value|
allowed_values.find { |v| v[:value] == value }
end
end

def human_name
WorkPackage.human_attribute_name(self.class.key)
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/custom_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ def possible_user_values_options(obj)
end

scope
.select(*(User::USER_FORMATS_STRUCTURE[Setting.user_format].map(&:to_s) << "id"))
.select(*User::USER_FORMATS_STRUCTURE[Setting.user_format].map(&:to_s), "id", "type")
end
end

Expand Down
14 changes: 0 additions & 14 deletions app/views/augmented/_autocomplete_select_decoration.html.erb

This file was deleted.

75 changes: 55 additions & 20 deletions app/views/custom_actions/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<% initialize_hide_sections_with @custom_action.all_actions.map { |a| { key: a.key, label: a.human_name } },
@custom_action.actions.map { |a| { key: a.key, label: a.human_name } } %>
@custom_action.actions.map { |a| { key: a.key, label: a.human_name } } %>

<div class="form--field -required">
<%= f.text_field :name, required: true, container_class: '-middle' %>
Expand All @@ -17,18 +17,36 @@
<div class="form--field">
<%= styled_label_tag("custom_action_conditions_#{condition.key}", condition.human_name, class: '-top') %>
<% input_name = "custom_action[conditions][#{condition.key}]" %>
<% selected_values = condition.values
select_options = condition.allowed_values.map { |v| { label: v[:label], value: v[:value], selected: selected_values.include?(v[:value]) } } %>

<div class="form--field-container">
<div class="form--select-container -middle">
<%= render partial: 'augmented/autocomplete_select_decoration',
locals: { input_name: input_name,
input_id: "custom_action_conditions_#{condition.key}",
select_options: select_options,
multiple: true,
key: condition.key.to_s
} %>
<% if condition.key == :project %>
<%= angular_component_tag 'opce-project-autocompleter',
inputs: {
multiple: true,
filters: [{ name: 'active', operator: '=', values: ['t'] }],
resource: "projects",
inputName: input_name,
appendTo: "body",
labelForId: "custom_action_actions_#{condition.key}",
inputValue: condition.values
}
%>
<% else %>
<%= angular_component_tag 'opce-autocompleter',
inputs: {
multiple: true,
defaultData: false,
items: condition.allowed_values.map { |v| { id: v[:value], name: v[:label] } },
model: condition.value_objects.map { |v| { id: v[:value], name: v[:label] } },
inputName: input_name,
bindLabel: "name",
bindValue: "id",
labelForId: "custom_action_conditions_#{condition.key}",
appendTo: "body",
}
%>
<% end %>
</div>
</div>
</div>
Expand All @@ -49,18 +67,35 @@

<% input_name = "custom_action[actions][#{action.key}]" %>
<% if %i(associated_property boolean).include?(action.type) %>
<% selected_values = action.values
select_options = action.allowed_values.map { |v| { label: v[:label], value: v[:value], selected: selected_values.include?(v[:value]) } } %>

<div class="form--field-container">
<div class="form--select-container -middle">
<%= render partial: 'augmented/autocomplete_select_decoration',
locals: { input_name: input_name,
input_id: "custom_action_actions_#{action.key}",
select_options: select_options,
multiple: action.multi_value?,
key: action.key.to_s
} %>
<% if action.key == :project %>
<%= angular_component_tag 'opce-project-autocompleter',
inputs: {
multiple: false,
filters: [{ name: 'active', operator: '=', values: ['t'] }],
resource: "projects",
inputName: input_name,
appendTo: "body",
labelForId: "custom_action_actions_#{action.key}",
inputValue: action.values.first
}
%>
<% else %>
<%= angular_component_tag 'opce-autocompleter',
inputs: {
multiple: action.multi_value?,
defaultData: false,
items: action.allowed_values.map { |v| { id: v[:value], name: v[:label] } },
model: action.value_objects.map { |v| { id: v[:value], name: v[:label] } },
inputName: input_name,
bindLabel: "name",
bindValue: "id",
labelForId: "custom_action_actions_#{action.key}",
appendTo: "body",
}
%>
<% end %>
</div>
</div>
<% elsif %i(date_property).include?(action.type) %>
Expand Down
4 changes: 0 additions & 4 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@ import {
import {
ProjectAutocompleterComponent,
} from 'core-app/shared/components/autocompleter/project-autocompleter/project-autocompleter.component';
import {
AutocompleteSelectDecorationComponent,
} from 'core-app/shared/components/autocompleter/autocomplete-select-decoration/autocomplete-select-decoration.component';
import {
MembersAutocompleterComponent,
} from 'core-app/shared/components/autocompleter/members-autocompleter/members-autocompleter.component';
Expand Down Expand Up @@ -426,7 +423,6 @@ export class OpenProjectModule implements DoBootstrap {
registerCustomElement('opce-global-search', GlobalSearchInputComponent, { injector });
registerCustomElement('opce-autocompleter', OpAutocompleterComponent, { injector });
registerCustomElement('opce-project-autocompleter', ProjectAutocompleterComponent, { injector });
registerCustomElement('opce-select-decoration', AutocompleteSelectDecorationComponent, { injector });
registerCustomElement('opce-members-autocompleter', MembersAutocompleterComponent, { injector });
registerCustomElement('opce-user-autocompleter', UserAutocompleterComponent, { injector });
registerCustomElement('opce-macro-attribute-value', AttributeValueMacroComponent, { injector });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ import {
OnInit,
Output,
} from '@angular/core';
import {
AbstractControl,
UntypedFormControl,
UntypedFormGroup,
Validators,
} from '@angular/forms';
import { AbstractControl, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { BannersService } from 'core-app/core/enterprise/banners.service';
import { CurrentUserService } from 'core-app/core/current-user/current-user.service';
Expand All @@ -23,11 +18,14 @@ import { ProjectResource } from 'core-app/features/hal/resources/project-resourc
import { PrincipalType } from '../invite-user.component';
import { ProjectAllowedValidator } from './project-allowed.validator';
import { map } from 'rxjs/operators';
import { IProjectAutocompleteItem } from 'core-app/shared/components/autocompleter/project-autocompleter/project-autocomplete-item';
import {
IProjectAutocompleteItem,
} from 'core-app/shared/components/autocompleter/project-autocompleter/project-autocomplete-item';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import idFromLink from 'core-app/features/hal/helpers/id-from-link';
import { ICapability } from 'core-app/core/state/capabilities/capability.model';
import { firstValueFrom } from 'rxjs';
import { IAPIFilter } from 'core-app/shared/components/autocompleter/op-autocompleter/typings';

@Component({
selector: 'op-ium-project-selection',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Input,
Output,
} from '@angular/core';
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { UntypedFormArray } from '@angular/forms';
import { ApiV3ListFilter } from 'core-app/core/apiv3/paths/apiv3-list-resource.interface';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { HalSourceLink } from 'core-app/features/hal/resources/hal-resource';
import { IProjectAutocompleteItem } from 'core-app/shared/components/autocompleter/project-autocompleter/project-autocomplete-item';
import {
IProjectAutocompleteItem,
} from 'core-app/shared/components/autocompleter/project-autocompleter/project-autocomplete-item';
import { IAPIFilter } from 'core-app/shared/components/autocompleter/op-autocompleter/typings';

export interface NotificationSettingProjectOption {
name:string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
import { firstValueFrom } from 'rxjs';
import { IAPIFilter } from 'core-app/shared/components/autocompleter/op-autocompleter/typings';

@Component({
selector: 'op-filter-project',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,31 @@
// See COPYRIGHT and LICENSE files for more details.
//++

import {
Component,
Inject,
} from '@angular/core';
import { Component, Inject } from '@angular/core';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { WorkPackageInlineCreateService } from 'core-app/features/work-packages/components/wp-inline-create/wp-inline-create.service';
import { WorkPackageInlineCreateComponent } from 'core-app/features/work-packages/components/wp-inline-create/wp-inline-create.component';
import { WorkPackageRelationsService } from 'core-app/features/work-packages/components/wp-relations/wp-relations.service';
import { WpRelationInlineCreateServiceInterface } from 'core-app/features/work-packages/components/wp-relations/embedded/wp-relation-inline-create.service.interface';
import {
WorkPackageInlineCreateService,
} from 'core-app/features/work-packages/components/wp-inline-create/wp-inline-create.service';
import {
WorkPackageInlineCreateComponent,
} from 'core-app/features/work-packages/components/wp-inline-create/wp-inline-create.component';
import {
WorkPackageRelationsService,
} from 'core-app/features/work-packages/components/wp-relations/wp-relations.service';
import {
WpRelationInlineCreateServiceInterface,
} from 'core-app/features/work-packages/components/wp-relations/embedded/wp-relation-inline-create.service.interface';
import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource';
import { UrlParamsHelperService } from 'core-app/features/work-packages/components/wp-query/url-params-helper';
import { RelationResource } from 'core-app/features/hal/resources/relation-resource';
import { HalEventsService } from 'core-app/features/hal/services/hal-events.service';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import { WorkPackageNotificationService } from 'core-app/features/work-packages/services/notifications/work-package-notification.service';
import {
WorkPackageNotificationService,
} from 'core-app/features/work-packages/services/notifications/work-package-notification.service';
import { IsolatedQuerySpace } from 'core-app/features/work-packages/directives/query-space/isolated-query-space';
import { IAPIFilter } from 'core-app/shared/components/autocompleter/op-autocompleter/typings';
import { FilterOperator } from 'core-app/shared/helpers/api-v3/api-v3-filter-builder';

@Component({
templateUrl: './wp-relation-inline-add-existing.component.html',
Expand Down Expand Up @@ -140,8 +149,8 @@ export class WpRelationInlineAddExistingComponent {
filters.forEach((filter) => {
iApiFilters.push({
name: filter.id,
operator: filter.operator.id,
values: filter.values.map((f) => (typeof f === 'string' ? f : f.id)),
operator: filter.operator.id as FilterOperator,
values: filter.values.map((f) => (typeof f === 'string' ? f : f.id as string)),
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
WorkPackageNotificationService,
} from 'core-app/features/work-packages/services/notifications/work-package-notification.service';
import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decorator';
import { TOpAutocompleterResource } from 'core-app/shared/components/autocompleter/op-autocompleter/typings';

export interface IWorkPackageAutocompleteItem extends WorkPackageResource {
id:string,
Expand Down
Loading

0 comments on commit 4d9254a

Please sign in to comment.