updated npm dependencies and implemented basic import

This commit is contained in:
Adam Piontek 2021-03-25 15:28:39 -04:00
parent 686bb489ba
commit 1d017a3cd1
6 changed files with 925 additions and 618 deletions

View file

@ -57,6 +57,8 @@ import "../node_modules/bootstrap-icons/icons/asterisk.svg";
import "../node_modules/bootstrap-icons/icons/card-list.svg";
import "../node_modules/bootstrap-icons/icons/file-earmark-spreadsheet.svg";
import "../node_modules/bootstrap-icons/icons/box-arrow-in-left.svg";
import "../node_modules/bootstrap-icons/icons/link.svg";
import "../node_modules/bootstrap-icons/icons/link-45deg.svg";
// webpack automatically bundles all modules in your
// entry points. Those entry points can be configured

1385
assets/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
"@fontsource/lato": "^4.2.1",
"@mdi/svg": "^5.9.55",
"@popperjs/core": "^2.8.4",
"bootstrap": "^5.0.0-beta2",
"bootstrap": "^5.0.0-beta3",
"bootstrap-icons": "^1.4.0",
"hamburgers": "^1.1.3",
"heroicons": "^0.4.2",

View file

@ -1,55 +1,94 @@
defmodule Shift73kWeb.ShiftImportLive.Index do
use Shift73kWeb, :live_view
alias Shift73k.Repo
alias Shift73k.Shifts
@url_regex_str "[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)"
@url_regex Regex.compile!(@url_regex_str)
@impl true
def mount(_params, session, socket) do
HTTPoison.start()
socket
|> assign_defaults(session)
|> assign(:url_valid, :false)
|> assign(:url_validated, :false)
|> assign(:tz_valid, :true)
|> live_okreply()
end
@impl true
def handle_event("save", %{"ics_import" => %{"ics_url" => ics_url}}, socket) do
ics_url
|> IO.inspect(label: "given ical url :")
|> HTTPoison.get!()
|> handle_http_ics_response(socket)
def handle_event("validate", %{"ics_import" => %{"ics_url" => url, "time_zone" => tz}}, socket) do
socket
|> assign(:url_valid, Regex.match?(@url_regex, url) |> IO.inspect(label: "url valid?"))
|> assign(:url_validated, true)
|> assign(:tz_valid, Enum.member?(Tzdata.zone_list(), tz))
|> live_noreply()
end
defp handle_http_ics_response(%HTTPoison.Response{status_code: 200} = resp, socket) do
@impl true
def handle_event("save", %{"ics_import" => %{"ics_url" => url, "time_zone" => tz}}, socket) do
url
|> HTTPoison.get!()
|> handle_http_ics_response(socket, tz)
end
defp handle_http_ics_response(%HTTPoison.Response{status_code: 200} = resp, socket, tz) do
case content_type_calendar?(resp.headers) do
false ->
handle_http_ics_response(false, socket)
handle_http_ics_response(false, socket, tz)
true ->
resp.body
|> ICalendar.from_ics()
|> handle_parsed_ics_data(socket)
|> handle_parsed_ics_data(socket, tz)
end
end
defp handle_http_ics_response(_, socket) do
defp handle_http_ics_response(_, socket, _tz) do
socket
|> put_flash(:error, "Bad data, bad URL, or some other error")
|> put_flash(:error, "Bad data, bad URL, or some other error. Page the dev!")
|> live_noreply()
end
defp handle_parsed_ics_data([], socket), do: handle_http_ics_response(false, socket)
defp handle_parsed_ics_data([], socket, tz), do: handle_http_ics_response(false, socket, tz)
defp handle_parsed_ics_data(events, socket) do
defp handle_parsed_ics_data(events, socket, tz) do
IO.inspect(events, label: "We got some ical events! :")
IO.inspect(tz, label: "time zone was :")
socket
|> put_flash(:success, "We got some ical events")
|> live_noreply()
to_insert =
events
|> Stream.map(&shift_from_event(&1, tz, socket.assigns.current_user.id))
|> Enum.map(&Repo.timestamp/1)
|> Shifts.create_multiple()
|> handle_create_multiple_result(length(events), socket)
|> live_noreply()
end
def ical_request(ics_url) do
# ics_url = "https://calendar.google.com/calendar/ical/l44mcggj2rsoqq7prlakvitqfo%40group.calendar.google.com/private-66f4cf8b340bdd6e9de8c60b2ae36528/basic.ics"
defp handle_create_multiple_result(result, event_count, socket) do
{status, msg} =
case result do
{:error, errmsg} ->
{:error, "Ope, problem error inserting shifts, page the dev! Message: #{errmsg}"}
{n, _} ->
s = (n > 1 && "s") || ""
if n == event_count do
{:success, "Successfully imported #{n} event#{s}"}
else
{:warning, "Some error, only #{n} event#{s} imported but seemed like iCal contained #{event_count}?"}
end
end
put_flash(socket, status, msg)
end
defp content_type_calendar?(headers) do
headers
|> List.keyfind("Content-Type", 0)
@ -57,7 +96,34 @@ defmodule Shift73kWeb.ShiftImportLive.Index do
|> String.contains?("text/calendar")
end
def shift_from_event(%ICalendar.Event{} = event) do
%{}
defp shift_from_event(%ICalendar.Event{} = e, tz, user_id) do
dtzstart = DateTime.shift_zone!(e.dtstart, tz)
dtzend = DateTime.add(dtzstart, DateTime.diff(e.dtend, e.dtstart))
%{
subject: e.summary,
location: e.location,
description: fix_description(e.description),
date: DateTime.to_date(dtzstart),
time_zone: tz,
time_start: DateTime.to_time(dtzstart),
time_end: DateTime.to_time(dtzend),
user_id: user_id
}
end
defp fix_description(description) do
description
|> String.replace("<br>", "\r\n")
|> String.replace("<br\\>", "\r\n")
|> String.replace("<br \\>", "\r\n")
|> String.replace("<b>", "**")
|> String.replace("</b>", "**")
|> String.replace("<strong>", "**")
|> String.replace("</strong>", "**")
|> String.replace("<i>", "*")
|> String.replace("</i>", "*")
|> String.replace("<em>", "*")
|> String.replace("</em>", "*")
end
end

View file

@ -11,18 +11,53 @@
<div class="row justify-content-center">
<div class="col-12 col-sm-11 col-md-10 col-lg-9 col-xxl-8">
<%= form_for :ics_import, "#", [phx_submit: "save"], fn iimf -> %>
<%= form_for :ics_import, "#", [phx_change: "validate", phx_submit: "save"], fn iimf -> %>
<div class="row">
<div class="col mb-3">
<%= label iimf, :ics_url, "iCal/ics URL", class: "form-label" %>
<%= url_input iimf, :ics_url, class: "form-control" %>
<% show_url_error = @url_validated && !@url_valid || false %>
<% valid_class = @url_validated && "is-valid" || "" %>
<%= label iimf, :ics_url, "iCal/ics URL", class: "form-label" %>
<div class="inner-addon left-addon mb-3">
<%= icon_div @socket, "bi-link", [class: "icon is-left text-muted fs-5"] %>
<%= url_input iimf, :ics_url,
class: show_url_error && "form-control is-invalid" || "form-control #{valid_class}",
phx_debounce: 500,
aria_describedby: "ics-import-url-error"
%>
<%= if show_url_error do %>
<div class="invalid-feedback d-block" id="ics-import-url-error">
Must be a valid URL
</div>
</div>
<% end %>
</div>
<%= label iimf, :time_zone, class: "form-label" %>
<div class="inner-addon left-addon mb-3">
<%= icon_div @socket, "bi-map", [class: "icon is-left text-muted fs-5"] %>
<%= text_input iimf, :time_zone,
value: Shift73k.Util.Dt.app_time_zone(),
class: @tz_valid && "form-control" || "form-control is-invalid",
phx_debounce: 250,
aria_describedby: "ics-import-tz-error",
list: "tz_list"
%>
<datalist id="tz_list">
<%= for tz_name <- Tzdata.zone_list() do %>
<option value="<%= tz_name %>"></option>
<% end %>
</datalist>
<div class="valid-feedback d-block text-primary">Type to search & select from list of known <%= link "IANA tz database", to: "https://en.wikipedia.org/wiki/List_of_tz_database_time_zones", target: "_blank" %> time zones</div>
<%= if !@tz_valid do %>
<div class="invalid-feedback d-block" id="ics-import-tz-error">
Invalid time zone
</div>
<% end %>
</div>
<div class="row">
<div class="col mb-3 text-end">
<%= submit "Submit", class: "btn btn-primary" %>
<%= submit "Submit", class: "btn btn-primary", disabled: !@tz_valid || !@url_valid %>
</div>
</div>

View file

@ -93,7 +93,6 @@
<%= for tz_name <- Tzdata.zone_list() do %>
<option value="<%= tz_name %>"></option>
<% end %>
end
</datalist>
<div class="valid-feedback d-block text-primary">Type to search & select from list of known <%= link "IANA tz database", to: "https://en.wikipedia.org/wiki/List_of_tz_database_time_zones", target: "_blank" %> time zones</div>
<%= error_tag f, :time_zone %>