Skip to content

Commit

Permalink
Add DatePicker component and dsl for single_date_picker and range_dat…
Browse files Browse the repository at this point in the history
…e_picker form fields
  • Loading branch information
dombesz committed Dec 17, 2024
1 parent 002fdf3 commit 56445a9
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[attr.data-value]="value"
[id]="id"
[name]="name"
[attr.name]="name"
[required]="required"
[disabled]="disabled"
[ngModel]="stringValue"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ export class OpBasicRangeDatePickerComponent implements OnInit, ControlValueAcce

@Input() inputClassNames = '';

@Input() inDialog = false;

@ViewChild('input') input:ElementRef;

stringValue = '';
Expand Down Expand Up @@ -199,6 +201,7 @@ export class OpBasicRangeDatePickerComponent implements OnInit, ControlValueAcce
!!this.minimalDate && dayElem.dateObj <= this.minimalDate,
);
},
static: this.inDialog,
},
this.input.nativeElement as HTMLInputElement,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import { DayElement } from 'flatpickr/dist/types/instance';
import { populateInputsFromDataset } from '../../dataset-inputs';
import { DeviceService } from 'core-app/core/browser/device.service';


@Component({
selector: 'op-basic-single-date-picker',
templateUrl: './basic-single-date-picker.component.html',
Expand Down Expand Up @@ -96,6 +95,8 @@ export class OpBasicSingleDatePickerComponent implements ControlValueAccessor, O

@Input() remoteFieldKey = null;

@Input() inDialog = false;

@ViewChild('input') input:ElementRef;

mobile = false;
Expand Down Expand Up @@ -179,6 +180,7 @@ export class OpBasicSingleDatePickerComponent implements ControlValueAccessor, O
!!this.minimalDate && dayElem.dateObj <= this.minimalDate,
);
},
static: this.inDialog,
},
this.input.nativeElement as HTMLInputElement,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
@import '../../app/spot/styles/sass/variables'
@import '../../global_styles/openproject/variables'

.op-datepicker-modal
display: flex
flex-direction: column
Expand Down Expand Up @@ -88,3 +87,8 @@
&--date-form
&:only-child
grid-column: 1 / 3

.flatpickr-wrapper
// Make flatpickr behave correctly when it is instantiated
// inside a dialog using the static: true option.
width: 100%
23 changes: 23 additions & 0 deletions lib/primer/open_project/forms/date_picker.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<%= render(FormControl.new(input: @input, tag: :"primer-datepicker-field")) do %>
<%= content_tag(:div, **@field_wrap_arguments) do %>
<%# leading spinner implies a leading visual %>
<% if @input.leading_visual || @input.leading_spinner? %>
<span class="FormControl-input-leadingVisualWrap">
<%= render(Primer::Beta::Octicon.new(**@input.leading_visual, data: { target: "primer-text-field.leadingVisual" })) %>
<% if @input.leading_spinner? %>
<%= render(Primer::Beta::Spinner.new(size: :small, hidden: true, data: { target: "primer-text-field.leadingSpinner" })) %>
<% end %>
</span>
<% end %>
<%= render Primer::ConditionalWrapper.new(condition: @input.auto_check_src, tag: "auto-check", csrf: auto_check_authenticity_token, src: @input.auto_check_src) do %>
<%= angular_component_tag @datepicker_options.fetch(:component),
inputs: @datepicker_options.merge(
id: @datepicker_options.fetch(:id) { builder.field_id(@input.name) },
name: @datepicker_options.fetch(:name) { builder.field_name(@input.name) },
value: @datepicker_options.fetch(:value) { @input.input_arguments[:value] },
inputClassNames: @datepicker_options.fetch(:class) { @input.input_arguments[:class] }
)
%>
<% end %>
<% end %>
<% end %>
17 changes: 17 additions & 0 deletions lib/primer/open_project/forms/date_picker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module Primer
module OpenProject
module Forms
# :nodoc:
class DatePicker < Primer::Forms::TextField
include AngularHelper

def initialize(input:, datepicker_options:)
super(input:)
@datepicker_options = datepicker_options
end
end
end
end
end
30 changes: 19 additions & 11 deletions lib/primer/open_project/forms/dsl/input_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,39 @@ module Forms
module Dsl
module InputMethods
def autocompleter(**, &)
add_input AutocompleterInput.new(builder: @builder, form: @form, **, &)
add_input AutocompleterInput.new(builder:, form:, **, &)
end

def work_package_autocompleter(**, &)
add_input WorkPackageAutocompleterInput.new(builder: @builder, form: @form, **, &)
def color_select_list(**, &)
add_input ColorSelectInput.new(builder:, form:, **, &)
end

def html_content(**, &)
add_input HtmlContentInput.new(builder:, form:, **, &)
end

def project_autocompleter(**, &)
add_input ProjectAutocompleterInput.new(builder: @builder, form: @form, **, &)
add_input ProjectAutocompleterInput.new(builder:, form:, **, &)
end

def range_date_picker(**)
add_input RangeDatePickerInput.new(builder:, form:, **)
end

def rich_text_area(**)
add_input RichTextAreaInput.new(builder: @builder, form: @form, **)
add_input RichTextAreaInput.new(builder:, form:, **)
end

def storage_manual_project_folder_selection(**)
add_input StorageManualProjectFolderSelectionInput.new(builder: @builder, form: @form, **)
def single_date_picker(**)
add_input SingleDatePickerInput.new(builder:, form:, **)
end

def color_select_list(**, &)
add_input ColorSelectInput.new(builder:, form:, **, &)
def storage_manual_project_folder_selection(**)
add_input StorageManualProjectFolderSelectionInput.new(builder:, form:, **)
end

def html_content(**, &)
add_input HtmlContentInput.new(builder: @builder, form: @form, **, &)
def work_package_autocompleter(**, &)
add_input WorkPackageAutocompleterInput.new(builder:, form:, **, &)
end
end
end
Expand Down
21 changes: 21 additions & 0 deletions lib/primer/open_project/forms/dsl/range_date_picker_input.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module Primer
module OpenProject
module Forms
module Dsl
class RangeDatePickerInput < SingleDatePickerInput
def derive_datepicker_options(options)
options.reverse_merge(
component: "opce-range-date-picker"
)
end

def type
:range_date_picker
end
end
end
end
end
end
33 changes: 33 additions & 0 deletions lib/primer/open_project/forms/dsl/single_date_picker_input.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

module Primer
module OpenProject
module Forms
module Dsl
class SingleDatePickerInput < Primer::Forms::Dsl::TextFieldInput
attr_reader :datepicker_options

def initialize(name:, label:, datepicker_options:, **system_arguments)
@datepicker_options = derive_datepicker_options(datepicker_options)

super(name:, label:, **system_arguments)
end

def derive_datepicker_options(options)
options.reverse_merge(
component: "opce-single-date-picker"
)
end

def to_component
DatePicker.new(input: self, datepicker_options:)
end

def type
:single_date_picker
end
end
end
end
end
end
12 changes: 8 additions & 4 deletions lookbook/previews/open_project/common/datepicker_preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ class DatepickerPreview < Lookbook::Preview
# before using or contributing to date pickers.
#
# @param value date
def single(value: Time.zone.today.iso8601)
render_with_template(locals: { value: })
# @param in_dialog toggle
# @param icon [Symbol] octicon
def single(value: Time.zone.today, in_dialog: false, icon: :calendar)
render_with_template(locals: { value:, in_dialog:, icon: })
end

##
Expand All @@ -48,8 +50,10 @@ def single(value: Time.zone.today.iso8601)
# before using or contributing to date pickers.
#
# @param value text
def range(value: "#{Time.zone.today.iso8601} - #{Time.zone.today.iso8601}")
render_with_template(locals: { value: })
# @param in_dialog toggle
# @param icon [Symbol] octicon
def range(value: "#{Time.zone.today.iso8601} - #{Time.zone.today.iso8601}", in_dialog: false, icon: :calendar)
render_with_template(locals: { value:, in_dialog:, icon: })
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,58 @@
<%= tag :'opce-range-date-picker', value: %>
<%
the_form = Class.new(ApplicationForm) do
form do |query_form|
query_form.range_date_picker(
name: :date,
label: 'Date',
leading_visual: { icon: },
value: value,
datepicker_options: { inDialog: in_dialog }
)

query_form.range_date_picker(
name: :date,
label: 'Date',
leading_visual: { icon: },
value: value,
datepicker_options: { inDialog: in_dialog }
)

query_form.range_date_picker(
name: :date,
label: 'Date',
leading_visual: { icon: },
value: value,
datepicker_options: { inDialog: in_dialog }
)
end
end
%>

<% if in_dialog %>
<%= render(Primer::Alpha::Dialog.new(title: "Dialog Title",
size: :large,
open: true,
id: "my-dialog")) do |d| %>
<% d.with_show_button { "Show dialog" } %>
<% d.with_header(variant: :medium) %>

<%= render(Primer::Alpha::Dialog::Body.new) do
primer_form_with(
url: '/abc',
id: "my-form") do |f|
render(the_form.new(f))
end
end %>

<%= d.with_footer do %>
<%= render(Primer::Beta::Button.new(data: { "close-dialog-id": "my-dialog" })) { I18n.t(:button_cancel) } %>
<%= render(Primer::Beta::Button.new(scheme: :primary, type: :submit, form: "my-form")) { I18n.t(:button_apply) } %>
<% end %>
<% end %>
<% else %>
<%= primer_form_with(
url: '/abc',
id: "my-form") do |f|
render(the_form.new(f))
end %>
<% end %>
Original file line number Diff line number Diff line change
@@ -1 +1,58 @@
<%= tag :'opce-single-date-picker', value: %>
<%
the_form = Class.new(ApplicationForm) do
form do |query_form|
query_form.single_date_picker(
name: :date,
label: 'Date',
leading_visual: { icon: },
value: value.iso8601,
datepicker_options: { inDialog: in_dialog }
)

query_form.single_date_picker(
name: :date,
label: 'Date',
leading_visual: { icon: },
value: value.iso8601,
datepicker_options: { inDialog: in_dialog }
)

query_form.single_date_picker(
name: :date,
label: 'Date',
leading_visual: { icon: },
value: value.iso8601,
datepicker_options: { inDialog: in_dialog }
)
end
end
%>

<% if in_dialog %>
<%= render(Primer::Alpha::Dialog.new(title: "Dialog Title",
size: :large,
open: true,
id: "my-dialog")) do |d| %>
<% d.with_show_button { "Show dialog" } %>
<% d.with_header(variant: :medium) %>

<%= render(Primer::Alpha::Dialog::Body.new) do
primer_form_with(
url: '/abc',
id: "my-form") do |f|
render(the_form.new(f))
end
end %>

<%= d.with_footer do %>
<%= render(Primer::Beta::Button.new(data: { "close-dialog-id": "my-dialog" })) { I18n.t(:button_cancel) } %>
<%= render(Primer::Beta::Button.new(scheme: :primary, type: :submit, form: "my-form")) { I18n.t(:button_apply) } %>
<% end %>
<% end %>
<% else %>
<%= primer_form_with(
url: '/abc',
id: "my-form") do |f|
render(the_form.new(f))
end %>
<% end %>

0 comments on commit 56445a9

Please sign in to comment.