mirror of
https://github.com/plausible/analytics.git
synced 2024-12-23 17:44:43 +03:00
wip
This commit is contained in:
parent
b2a546ea92
commit
c7a6124c3f
@ -1,4 +1,5 @@
|
||||
[
|
||||
plugins: [Phoenix.LiveView.HTMLFormatter],
|
||||
import_deps: [:ecto, :ecto_sql, :phoenix],
|
||||
subdirectories: ["priv/*/migrations"],
|
||||
inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"]
|
||||
|
@ -29,7 +29,7 @@ window.addEventListener(`phx:update-value`, (e) => {
|
||||
|
||||
window.addEventListener(`phx:hide`, (e) => {
|
||||
let el = document.getElementById(e.detail.id)
|
||||
el.style.display = 'none'
|
||||
el.classList.add('hidden')
|
||||
})
|
||||
|
||||
window.addEventListener(`phx:scroll-to`, (e) => {
|
||||
|
@ -20,20 +20,34 @@ defmodule PlausibleWeb.Live.FunnelSettings do
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<%= if @add_funnel? do %>
|
||||
<.live_component module={PlausibleWeb.Live.FunnelSettings.Form} id="funnelForm" site={@site} form={to_form(Plausible.Funnel.changeset())} goals={@goals} />
|
||||
<.live_component
|
||||
module={PlausibleWeb.Live.FunnelSettings.Form}
|
||||
id="funnelForm"
|
||||
site={@site}
|
||||
form={to_form(Plausible.Funnel.changeset())}
|
||||
goals={@goals}
|
||||
/>
|
||||
<% else %>
|
||||
<div :if={Enum.count(@goals) >= 2}>
|
||||
<.live_component module={PlausibleWeb.Live.FunnelSettings.List} id="funnelsList" funnels={@funnels} site={@site} />
|
||||
<.live_component
|
||||
module={PlausibleWeb.Live.FunnelSettings.List}
|
||||
id="funnelsList"
|
||||
funnels={@funnels}
|
||||
site={@site}
|
||||
/>
|
||||
<button type="button" class="button mt-6" phx-click="add_funnel">+ Add funnel</button>
|
||||
</div>
|
||||
<div :if={Enum.count(@goals) < 2}>
|
||||
|
||||
<div class="rounded-md bg-yellow-100 p-4 mt-8">
|
||||
<p class="text-sm leading-5 text-gray-900 dark:text-gray-100">
|
||||
You need to define at least two goals to create a funnel. Go ahead and <%= link "add goals", to: PlausibleWeb.Router.Helpers.site_path(@socket, :new_goal, @site.domain), class: "text-indigo-500 w-full text-center" %> to proceed.
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-md bg-yellow-100 p-4 mt-8">
|
||||
<p class="text-sm leading-5 text-gray-900 dark:text-gray-100">
|
||||
You need to define at least two goals to create a funnel. Go ahead and <%= link(
|
||||
"add goals",
|
||||
to: PlausibleWeb.Router.Helpers.site_path(@socket, :new_goal, @site.domain),
|
||||
class: "text-indigo-500 w-full text-center"
|
||||
) %> to proceed.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
"""
|
||||
end
|
||||
|
@ -16,11 +16,21 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
|
||||
~H"""
|
||||
<div class="grid grid-cols-4 gap-6 mt-6">
|
||||
<div class="col-span-4 sm:col-span-2">
|
||||
<.form :let={f} for={@form} phx-change="validate" phx-submit="save" onkeydown="return event.key != 'Enter';">
|
||||
<%= label f, "Funnel name", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
|
||||
<.input field={@form[:name]} />
|
||||
<.form
|
||||
:let={f}
|
||||
for={@form}
|
||||
phx-change="validate"
|
||||
phx-submit="save"
|
||||
onkeydown="return event.key != 'Enter';"
|
||||
>
|
||||
<%= label(f, "Funnel name",
|
||||
class: "block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
) %>
|
||||
<.input field={@form[:name]} />
|
||||
|
||||
<%= label f, "Funnel Steps", class: "mt-6 block text-sm font-medium text-gray-700 dark:text-gray-300" %>
|
||||
<%= label(f, "Funnel Steps",
|
||||
class: "mt-6 block text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
) %>
|
||||
|
||||
<.live_component
|
||||
:for={step_number <- 1..@step_count}
|
||||
@ -29,13 +39,26 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
|
||||
options={Enum.map(@goals, fn goal -> {goal.id, Plausible.Goal.display_name(goal)} end)}
|
||||
/>
|
||||
|
||||
<a :if={@step_count < 5} class="underline text-indigo-600 text-sm cursor-pointer mt-6" phx-click="add-step" phx-target={@myself}>+ Add another step</a>
|
||||
<a
|
||||
:if={@step_count < 5}
|
||||
class="underline text-indigo-600 text-sm cursor-pointer mt-6"
|
||||
phx-click="add-step"
|
||||
phx-target={@myself}
|
||||
>
|
||||
+ Add another step
|
||||
</a>
|
||||
|
||||
<div class="mt-6">
|
||||
<button type="submit" class="button mt-6">Save</button>
|
||||
<button type="button" class="inline-block mt-4 ml-2 px-4 py-2 border border-gray-300 dark:border-gray-500 text-sm leading-5 font-medium rounded-md text-red-700 bg-white dark:bg-gray-800 hover:text-red-500 dark:hover:text-red-400 focus:outline-none focus:border-blue-300 focus:ring active:text-red-800 active:bg-gray-50 transition ease-in-out duration-150 " phx-click="cancel_add_funnel">Cancel</button>
|
||||
<button
|
||||
type="button"
|
||||
class="inline-block mt-4 ml-2 px-4 py-2 border border-gray-300 dark:border-gray-500 text-sm leading-5 font-medium rounded-md text-red-700 bg-white dark:bg-gray-800 hover:text-red-500 dark:hover:text-red-400 focus:outline-none focus:border-blue-300 focus:ring active:text-red-800 active:bg-gray-50 transition ease-in-out duration-150 "
|
||||
phx-click="cancel_add_funnel"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</.form>
|
||||
</.form>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
@ -45,7 +68,15 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
|
||||
|
||||
def input(assigns) do
|
||||
~H"""
|
||||
<input autofocus type="text" id={@field.id} name={@field.name} value={@field.value} phx-debounce="300" class="focus:ring-indigo-500 focus:border-indigo-500 dark:bg-gray-900 dark:text-gray-300 block w-full rounded-md sm:text-sm border-gray-300 dark:border-gray-500" />
|
||||
<input
|
||||
autofocus
|
||||
type="text"
|
||||
id={@field.id}
|
||||
name={@field.name}
|
||||
value={@field.value}
|
||||
phx-debounce="300"
|
||||
class="focus:ring-indigo-500 focus:border-indigo-500 dark:bg-gray-900 dark:text-gray-300 block w-full rounded-md sm:text-sm border-gray-300 dark:border-gray-500"
|
||||
/>
|
||||
"""
|
||||
end
|
||||
|
||||
|
@ -18,113 +18,154 @@ defmodule PlausibleWeb.Live.FunnelSettings.InputPicker do
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
attr :placeholder, :string, default: "Select option or search by typing"
|
||||
attr :id, :any, default: nil
|
||||
attr :options, :list, required: true
|
||||
attr(:placeholder, :string, default: "Select option or search by typing")
|
||||
attr(:id, :any, default: nil)
|
||||
attr(:options, :list, required: true)
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="mb-3">
|
||||
<div class="relative w-full">
|
||||
<div
|
||||
phx-click-away={close_dropdown(@id)}
|
||||
class="pl-2 pr-8 py-1 w-full dark:bg-gray-900 dark:text-gray-300 rounded-md shadow-sm border border-gray-300 dark:border-gray-700 focus-within:border-indigo-500 focus-within:ring-1 focus-within:ring-indigo-500">
|
||||
<div class="relative w-full">
|
||||
<div
|
||||
phx-click-away={close_dropdown(@id)}
|
||||
class="pl-2 pr-8 py-1 w-full dark:bg-gray-900 dark:text-gray-300 rounded-md shadow-sm border border-gray-300 dark:border-gray-700 focus-within:border-indigo-500 focus-within:ring-1 focus-within:ring-indigo-500"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
id={@id}
|
||||
placeholder={@placeholder}
|
||||
phx-keyup="keypress"
|
||||
phx-focus={open_dropdown(@id)}
|
||||
phx-target={@myself}
|
||||
name={"display-#{@id}"}
|
||||
value={@display_value}
|
||||
class="border-none py-1 px-1 p-0 w-full inline-block rounded-md focus:outline-none focus:ring-0 text-sm"
|
||||
style="background-color: inherit;"
|
||||
/>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
id={@id}
|
||||
placeholder={@placeholder}
|
||||
phx-keyup="keypress"
|
||||
phx-focus={open_dropdown(@id)}
|
||||
phx-target={@myself}
|
||||
name={"display-#{@id}"}
|
||||
value={@display_value}
|
||||
class="border-none py-1 px-1 p-0 w-full inline-block rounded-md focus:outline-none focus:ring-0 text-sm" style="background-color: inherit;" />
|
||||
<.dropdown_anchor id={@id} />
|
||||
|
||||
<.dropdown_anchor id={@id}/>
|
||||
|
||||
<input type="hidden" name={@id} value={@submit_value} />
|
||||
<input type="hidden" name={@id} value={@submit_value} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<.dropdown ref={@id} options={@options} choices={@choices} target={@myself} candidate={@candidate} />
|
||||
<.dropdown
|
||||
ref={@id}
|
||||
options={@options}
|
||||
choices={@choices}
|
||||
target={@myself}
|
||||
candidate={@candidate}
|
||||
/>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
attr :id, :any, required: true
|
||||
attr(:id, :any, required: true)
|
||||
|
||||
def dropdown_anchor(assigns) do
|
||||
~H"""
|
||||
<div phx-click={open_dropdown(@id)} class="cursor-pointer absolute inset-y-0 right-0 flex items-center pr-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="h-4 w-4 text-gray-500">
|
||||
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clip-rule="evenodd"></path>
|
||||
<div
|
||||
phx-click={open_dropdown(@id)}
|
||||
class="cursor-pointer absolute inset-y-0 right-0 flex items-center pr-2"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
class="h-4 w-4 text-gray-500"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z"
|
||||
clip-rule="evenodd"
|
||||
>
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def open_dropdown(js \\ %JS{}, id) do
|
||||
js |> close_all_dropdowns() |> JS.show(to: "#dropdown-#{id}")
|
||||
js
|
||||
|> close_all_dropdowns()
|
||||
|> JS.remove_class("hidden", to: "#dropdown-#{id}")
|
||||
end
|
||||
|
||||
def close_dropdown(js \\ %JS{}, id) do
|
||||
JS.hide(js, to: "#dropdown-#{id}")
|
||||
JS.add_class(js, "hidden", to: "#dropdown-#{id}")
|
||||
end
|
||||
|
||||
def close_all_dropdowns(js \\ %JS{}) do
|
||||
JS.hide(js, to: ".dropdown")
|
||||
JS.add_class(js, "hidden", to: ".dropdown")
|
||||
end
|
||||
|
||||
attr :ref, :string, required: true
|
||||
attr :options, :list, default: []
|
||||
attr :choices, :list, default: []
|
||||
attr :candidate, :integer, required: true
|
||||
attr :target, :any
|
||||
attr(:ref, :string, required: true)
|
||||
attr(:options, :list, default: [])
|
||||
attr(:choices, :list, default: [])
|
||||
attr(:candidate, :integer, required: true)
|
||||
attr(:target, :any)
|
||||
|
||||
def dropdown(assigns) do
|
||||
~H"""
|
||||
<ul
|
||||
tabindex="-1"
|
||||
id={"dropdown-#{@ref}"}
|
||||
phx-target={@target}
|
||||
class="dropdown hidden z-50 absolute mt-1 max-h-60 overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm dark:bg-gray-900">
|
||||
<.option :if={@choices != []} :for={{{submit_value, display_value}, idx} <- Enum.with_index(@choices)}
|
||||
class="dropdown hidden z-50 absolute mt-1 max-h-60 overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm dark:bg-gray-900"
|
||||
>
|
||||
<.option
|
||||
:for={{{submit_value, display_value}, idx} <- Enum.with_index(@choices)}
|
||||
:if={@choices != []}
|
||||
idx={idx}
|
||||
submit_value={submit_value}
|
||||
display_value={display_value}
|
||||
target={@target}
|
||||
ref={@ref}
|
||||
candidate={@candidate} />
|
||||
candidate={@candidate}
|
||||
/>
|
||||
|
||||
<div :if={@choices == []} class="relative cursor-default select-none py-2 px-4 text-gray-700 dark:text-gray-300">
|
||||
No matches found. Try searching for something different.
|
||||
</div>
|
||||
<div
|
||||
:if={@choices == []}
|
||||
class="relative cursor-default select-none py-2 px-4 text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
No matches found. Try searching for something different.
|
||||
</div>
|
||||
</ul>
|
||||
"""
|
||||
end
|
||||
|
||||
attr :display_value, :string, required: true
|
||||
attr :submit_value, :integer, required: true
|
||||
attr :ref, :string, required: true
|
||||
attr :target, :any
|
||||
attr :idx, :integer, required: true
|
||||
attr :candidate, :integer, required: true
|
||||
attr(:display_value, :string, required: true)
|
||||
attr(:submit_value, :integer, required: true)
|
||||
attr(:ref, :string, required: true)
|
||||
attr(:target, :any)
|
||||
attr(:idx, :integer, required: true)
|
||||
attr(:candidate, :integer, required: true)
|
||||
|
||||
def option(assigns) do
|
||||
assigns = assign(assigns, :max_options_displayed, @max_options_displayed)
|
||||
|
||||
~H"""
|
||||
<li class={["relative select-none py-2 px-3 cursor-pointer dark:text-gray-300", @idx == @candidate && "text-white bg-indigo-500"]}
|
||||
id={"dropdown-#{@ref}-option-#{@idx}"}>
|
||||
|
||||
<a phx-click={select_option(@ref, @submit_value, @display_value)} phx-value-display-value={@display_value} phx-target={@target}>
|
||||
<li
|
||||
class={[
|
||||
"relative select-none py-2 px-3 cursor-pointer dark:text-gray-300",
|
||||
@idx == @candidate && "text-white bg-indigo-500"
|
||||
]}
|
||||
id={"dropdown-#{@ref}-option-#{@idx}"}
|
||||
>
|
||||
<a
|
||||
phx-click={select_option(@ref, @submit_value, @display_value)}
|
||||
phx-value-display-value={@display_value}
|
||||
phx-target={@target}
|
||||
>
|
||||
<span class="block truncate">
|
||||
<%= @display_value %>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li :if={@idx == @max_options_displayed - 1} class="text-xs text-gray-500 relative py-2 px-3">Max results reached. Refine your search by typing in goal name.</li>
|
||||
<li :if={@idx == @max_options_displayed - 1} class="text-xs text-gray-500 relative py-2 px-3">
|
||||
Max results reached. Refine your search by typing in goal name.
|
||||
</li>
|
||||
"""
|
||||
end
|
||||
|
||||
|
@ -5,20 +5,37 @@ defmodule PlausibleWeb.Live.FunnelSettings.List do
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div>
|
||||
<%= if Enum.count(@funnels) > 0 do %>
|
||||
<div class="mt-4">
|
||||
<%= for funnel <- @funnels do %>
|
||||
<div class="border-b border-gray-300 dark:border-gray-500 py-3 flex justify-between">
|
||||
<span class="text-sm font-medium text-gray-900 dark:text-gray-100"><%= funnel.name %></span>
|
||||
<%= button(to: "", method: :delete, class: "text-sm text-red-600", data: [confirm: "Are you sure you want to remove funnel '#{funnel.name}'? This will just affect the UI, all of your analytics data will stay intact."]) do %>
|
||||
<svg class="feather feather-sm" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="mt-4 dark:text-gray-100">No funnels configured for this site yet</div>
|
||||
<% end %>
|
||||
<%= if Enum.count(@funnels) > 0 do %>
|
||||
<div class="mt-4">
|
||||
<%= for funnel <- @funnels do %>
|
||||
<div class="border-b border-gray-300 dark:border-gray-500 py-3 flex justify-between">
|
||||
<span class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||
<%= funnel.name %>
|
||||
</span>
|
||||
<%= button(to: "", method: :delete, class: "text-sm text-red-600", data: [confirm: "Are you sure you want to remove funnel '#{funnel.name}'? This will just affect the UI, all of your analytics data will stay intact."]) do %>
|
||||
<svg
|
||||
class="feather feather-sm"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<polyline points="3 6 5 6 21 6"></polyline>
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2">
|
||||
</path>
|
||||
<line x1="10" y1="11" x2="10" y2="17"></line>
|
||||
<line x1="14" y1="11" x2="14" y2="17"></line>
|
||||
</svg>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="mt-4 dark:text-gray-100">No funnels configured for this site yet</div>
|
||||
<% end %>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
@ -57,18 +57,50 @@ defmodule PlausibleWeb.SiteView do
|
||||
|
||||
def google_logo(assigns \\ %{}) do
|
||||
~H"""
|
||||
<svg width="46px" height="46px" viewBox="0 0 46 46" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(-1.000000, -1.000000)">
|
||||
<g transform="translate(15.000000, 15.000000)">
|
||||
<path d="M17.64,9.20454545 C17.64,8.56636364 17.5827273,7.95272727 17.4763636,7.36363636 L9,7.36363636 L9,10.845 L13.8436364,10.845 C13.635,11.97 13.0009091,12.9231818 12.0477273,13.5613636 L12.0477273,15.8195455 L14.9563636,15.8195455 C16.6581818,14.2527273 17.64,11.9454545 17.64,9.20454545 L17.64,9.20454545 Z" id="Shape" fill="#4285F4" sketch:type="MSShapeGroup"></path>
|
||||
<path d="M9,18 C11.43,18 13.4672727,17.1940909 14.9563636,15.8195455 L12.0477273,13.5613636 C11.2418182,14.1013636 10.2109091,14.4204545 9,14.4204545 C6.65590909,14.4204545 4.67181818,12.8372727 3.96409091,10.71 L0.957272727,10.71 L0.957272727,13.0418182 C2.43818182,15.9831818 5.48181818,18 9,18 L9,18 Z" id="Shape" fill="#34A853" sketch:type="MSShapeGroup"></path>
|
||||
<path d="M3.96409091,10.71 C3.78409091,10.17 3.68181818,9.59318182 3.68181818,9 C3.68181818,8.40681818 3.78409091,7.83 3.96409091,7.29 L3.96409091,4.95818182 L0.957272727,4.95818182 C0.347727273,6.17318182 0,7.54772727 0,9 C0,10.4522727 0.347727273,11.8268182 0.957272727,13.0418182 L3.96409091,10.71 L3.96409091,10.71 Z" id="Shape" fill="#FBBC05" sketch:type="MSShapeGroup"></path>
|
||||
<path d="M9,3.57954545 C10.3213636,3.57954545 11.5077273,4.03363636 12.4404545,4.92545455 L15.0218182,2.34409091 C13.4631818,0.891818182 11.4259091,0 9,0 C5.48181818,0 2.43818182,2.01681818 0.957272727,4.95818182 L3.96409091,7.29 C4.67181818,5.16272727 6.65590909,3.57954545 9,3.57954545 L9,3.57954545 Z" id="Shape" fill="#EA4335" sketch:type="MSShapeGroup"></path>
|
||||
<path d="M0,0 L18,0 L18,18 L0,18 L0,0 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
||||
<svg
|
||||
width="46px"
|
||||
height="46px"
|
||||
viewBox="0 0 46 46"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
||||
>
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(-1.000000, -1.000000)">
|
||||
<g transform="translate(15.000000, 15.000000)">
|
||||
<path
|
||||
d="M17.64,9.20454545 C17.64,8.56636364 17.5827273,7.95272727 17.4763636,7.36363636 L9,7.36363636 L9,10.845 L13.8436364,10.845 C13.635,11.97 13.0009091,12.9231818 12.0477273,13.5613636 L12.0477273,15.8195455 L14.9563636,15.8195455 C16.6581818,14.2527273 17.64,11.9454545 17.64,9.20454545 L17.64,9.20454545 Z"
|
||||
id="Shape"
|
||||
fill="#4285F4"
|
||||
sketch:type="MSShapeGroup"
|
||||
>
|
||||
</path>
|
||||
<path
|
||||
d="M9,18 C11.43,18 13.4672727,17.1940909 14.9563636,15.8195455 L12.0477273,13.5613636 C11.2418182,14.1013636 10.2109091,14.4204545 9,14.4204545 C6.65590909,14.4204545 4.67181818,12.8372727 3.96409091,10.71 L0.957272727,10.71 L0.957272727,13.0418182 C2.43818182,15.9831818 5.48181818,18 9,18 L9,18 Z"
|
||||
id="Shape"
|
||||
fill="#34A853"
|
||||
sketch:type="MSShapeGroup"
|
||||
>
|
||||
</path>
|
||||
<path
|
||||
d="M3.96409091,10.71 C3.78409091,10.17 3.68181818,9.59318182 3.68181818,9 C3.68181818,8.40681818 3.78409091,7.83 3.96409091,7.29 L3.96409091,4.95818182 L0.957272727,4.95818182 C0.347727273,6.17318182 0,7.54772727 0,9 C0,10.4522727 0.347727273,11.8268182 0.957272727,13.0418182 L3.96409091,10.71 L3.96409091,10.71 Z"
|
||||
id="Shape"
|
||||
fill="#FBBC05"
|
||||
sketch:type="MSShapeGroup"
|
||||
>
|
||||
</path>
|
||||
<path
|
||||
d="M9,3.57954545 C10.3213636,3.57954545 11.5077273,4.03363636 12.4404545,4.92545455 L15.0218182,2.34409091 C13.4631818,0.891818182 11.4259091,0 9,0 C5.48181818,0 2.43818182,2.01681818 0.957272727,4.95818182 L3.96409091,7.29 C4.67181818,5.16272727 6.65590909,3.57954545 9,3.57954545 L9,3.57954545 Z"
|
||||
id="Shape"
|
||||
fill="#EA4335"
|
||||
sketch:type="MSShapeGroup"
|
||||
>
|
||||
</path>
|
||||
<path d="M0,0 L18,0 L18,18 L0,18 L0,0 Z" id="Shape" sketch:type="MSShapeGroup"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
"""
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user