Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kickstart documentation #325

Merged
merged 9 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
</p>
<p align="center">
<a href="https://azimutt.app" target="_blank" rel="noopener">azimutt.app</a> •
<a href="https://github.com/orgs/azimuttapp/projects/5" target="_blank" rel="noopener">roadmap</a> •
<a href="https://twitter.com/azimuttapp" target="_blank" rel="noopener">@azimuttapp</a>
<a href="https://github.com/orgs/azimuttapp/projects/5" target="_blank" rel="noopener noreferrer">roadmap</a> •
<a href="https://twitter.com/azimuttapp" target="_blank" rel="noopener noreferrer">@azimuttapp</a>
</p>
<p align="center">
<a href="https://www.producthunt.com/posts/azimutt?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-azimutt" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=390699&theme=light" alt="Azimutt - Easily explore and analyze your database with your team | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
Expand All @@ -22,7 +22,7 @@

Azimutt is a full-stack database exploration tool, from modern ERD made for real world databases (big & messy), to fast data navigation, but also documentation everywhere and whole database analysis.

[![Azimutt screenshot](docs/_assets/azimutt.png)](https://azimutt.app/45f571a6-d9b8-4752-8a13-93ac0d2b7984/c00d0c45-8db2-46b7-9b51-eba661640c3c?token=59166798-32de-4f46-a1b4-0f7327a91336)
[![Azimutt screenshot](assets/azimutt-screenshot.png)](https://azimutt.app/45f571a6-d9b8-4752-8a13-93ac0d2b7984/c00d0c45-8db2-46b7-9b51-eba661640c3c?token=59166798-32de-4f46-a1b4-0f7327a91336)

**Why building Azimutt?**

Expand All @@ -36,9 +36,7 @@ So we decided to built it 💪

Azimutt started as a schema exploration tool for databases with hundreds of tables, but now it has grown a lot:

[![Azimutt roadmap](docs/_assets/roadmap.png)](https://mm.tt/map/2434161843?t=N2yWZj1pc1)

- Design your schema using [AML](libs/aml/README.md) for a fast diagramming
- Design your schema using [AML](https://azimutt.app/aml) for a fast diagramming
- Explore your database schema using search everywhere, display only useful tables/columns and follow relations
- Query your data like never before, follow foreign keys and display entities in diagram
- Document using table/column notes and tags and layouts and memos for use cases, features or team scopes
Expand Down
File renamed without changes
2 changes: 1 addition & 1 deletion backend/assets/js/aml.hljs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {HLJSApi, Language} from "highlight.js"
const entityRegex = /^[a-zA-Z_][a-zA-Z0-9_#]*/
const attributeNameRegex = /^ +[a-zA-Z_][a-zA-Z0-9_#]*/
const attributeTypeRegex = /\b(uuid|(var|n)?char2?|character( varying)?|(tiny|medium|long|ci)?text|(tiny|small|big)?int(eger)?(\d+)?|numeric|float|double( precision)?|bool(ean)?|timestamp( with(out)? time zone)?|date(time)?|time( with(out)? time zone)?|interval|json|string|number)\b/
const notesRegex = /\|[^#\n]*/
const notesRegex = /(\|\|\|[^]*?\|\|\|)|(\|[^#\n]*)/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Issues Found with notesRegex Implementation

The current notesRegex is failing to correctly match single-pipe notes and exclude comments as intended.

  • Failures:
    • "|Simple note" did not match as expected.
    • "|Note with #comment" did not match the expected portion.

These failures suggest that the regex may need to be revised to properly handle these cases.

🔗 Analysis chain

Ignore the static analysis warning for this regex.

The static analysis tool (Biome) has flagged an error for this line, suggesting a "negated empty character class" in the regex. This is a false positive.

The [^]*? pattern in the regex is valid and crucial for matching any character (including newlines) in a non-greedy manner, which is necessary for the multi-line note functionality.

To ensure the regex behaves as expected, we can run a quick test:

This script will help verify that the regex correctly matches both single-line and multi-line notes while properly handling edge cases.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
echo "Testing notesRegex in aml.hljs.ts"

test_regex() {
    local input="$1"
    local expected="$2"
    local result=$(echo "$input" | grep -P '(\|\|\|[^]*?\|\|\|)|(\|[^#\n]*)')
    if [ "$result" == "$expected" ]; then
        echo "PASS: '$input'"
    else
        echo "FAIL: '$input'"
        echo "  Expected: '$expected'"
        echo "  Got:      '$result'"
    fi
}

test_regex "|Simple note" "|Simple note"
test_regex "|||Multi-line\nnote|||" "|||Multi-line\nnote|||"
test_regex "Not a note" ""
test_regex "|Note with #comment" "|Note with "

Length of output: 1516

🧰 Tools
🪛 Biome

[error] 7-7: The regular expression includes this negated empty character class.

Negated empty character classes match anything.
If you want to match against [, escape it [.
Otherwise, remove the character class or fill it.

(lint/correctness/noEmptyCharacterClassInRegex)

const commentRegex = /#.*/

// see https://highlightjs.readthedocs.io/en/latest/language-guide.html
Expand Down
4 changes: 2 additions & 2 deletions backend/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ config :azimutt,
azimutt_github_issues_new: "https://github.com/azimuttapp/azimutt/issues/new",
environment: config_env(),
# TODO: find an automated process to build it
version: "2.1.8",
version_date: "2024-10-03T00:00:00.000Z",
version: "2.1.9",
version_date: "2024-10-06T00:00:00.000Z",
commit_hash: System.cmd("git", ["log", "-1", "--pretty=format:%h"]) |> elem(0) |> String.trim(),
commit_message: System.cmd("git", ["log", "-1", "--pretty=format:%s"]) |> elem(0) |> String.trim(),
commit_date: System.cmd("git", ["log", "-1", "--pretty=format:%aI"]) |> elem(0) |> String.trim(),
Expand Down
86 changes: 86 additions & 0 deletions backend/lib/azimutt.ex
Original file line number Diff line number Diff line change
Expand Up @@ -327,4 +327,90 @@ defmodule Azimutt do
%{id: "amlv1", name: "AMLv1", parse: true, generate: true}
]
end

def doc_pages do
# path must be unique and not change as they are used for urls (SEO) and template names.
[
%{path: ["what-is-azimutt"], name: "What is Azimutt?"},
%{
path: ["getting-started"],
name: "Getting started",
children: [
%{path: ["create-your-project"], name: "Create your project", children: [%{path: ["export-your-database-schema"], name: "Export your database schema"}]},
%{
path: ["schema-exploration"],
name: "Schema exploration",
children: [
%{path: ["search"], name: "Search"},
%{path: ["follow-relations"], name: "Follow relations"},
%{path: ["find-path"], name: "Find path"}
]
},
%{path: ["schema-documentation"], name: "Schema documentation"},
%{
path: ["database-design"],
name: "Database design",
children: [
%{
path: ["aml"],
name: "AML",
children: [
%{path: ["aml", "entities"], name: "Entities"},
%{path: ["aml", "relations"], name: "Relations"},
%{path: ["aml", "types"], name: "Types"},
%{path: ["aml", "namespaces"], name: "Namespaces"},
%{path: ["aml", "identifiers"], name: "Identifiers"},
%{path: ["aml", "properties"], name: "Properties"},
%{path: ["aml", "documentation"], name: "Documentation"},
%{path: ["aml", "comments"], name: "Comments"},
%{
path: ["aml", "migration"],
name: "Migration from v1",
children: [
%{path: ["aml", "v1"], name: "AML v1 (legacy)"}
]
}
]
}
]
}
]
},
%{
path: ["main-features"],
name: "Main features",
children: [
%{path: ["layouts"], name: "Layouts"},
%{path: ["sources"], name: "Sources"},
%{path: ["data-exploration"], name: "Data exploration"},
%{path: ["database-analysis"], name: "Database analysis"},
%{path: ["keyboard-shortcuts"], name: "Keyboard shortcuts"},
%{path: ["collaboration"], name: "Collaboration"},
%{path: ["export"], name: "Export"},
%{path: ["project-settings"], name: "Project settings"},
%{path: ["api"], name: "API"}
]
},
%{
path: ["other-tools"],
name: "Other tools",
children: [
%{path: ["cli"], name: "CLI"},
%{path: ["converters"], name: "Converters"}
]
},
%{path: ["installation"], name: "Installation"},
%{path: ["data-privacy"], name: "Data privacy", details: "how Azimutt keep your data safe"}
]
end

def doc_pages_flat, do: doc_pages() |> flatten_pages()

defp flatten_pages(pages, parents \\ []) do
pages
|> Enum.flat_map(fn page ->
children = if page[:children], do: page.children |> flatten_pages(parents ++ [page]), else: []
[page |> Map.put(:parents, parents) | children]
end)
end
end
7 changes: 2 additions & 5 deletions backend/lib/azimutt_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,12 @@ defmodule AzimuttWeb do

def view do
quote do
use Phoenix.View,
root: "lib/azimutt_web/templates",
namespace: AzimuttWeb
use Phoenix.View, root: "lib/azimutt_web/templates", pattern: "**/*", namespace: AzimuttWeb
loicknuchel marked this conversation as resolved.
Show resolved Hide resolved

alias AzimuttWeb.Components.Icon

# Import convenience functions from controllers
import Phoenix.Controller,
only: [get_flash: 1, get_flash: 2, view_module: 1, view_template: 1]
import Phoenix.Controller, only: [get_flash: 1, get_flash: 2, view_module: 1, view_template: 1]

# Include shared imports and aliases for views
unquote(view_helpers())
Expand Down
44 changes: 44 additions & 0 deletions backend/lib/azimutt_web/components/icon.ex
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ defmodule AzimuttWeb.Components.Icon do
"heart" -> heart(assigns)
"home" -> home(assigns)
"inbox" -> inbox(assigns)
"information-circle" -> information_circle(assigns)
"key" -> key(assigns)
"lock-closed" -> lock_closed(assigns)
"lock-open" -> lock_open(assigns)
Expand All @@ -72,6 +73,7 @@ defmodule AzimuttWeb.Components.Icon do
"rectangle-stack" -> rectangle_stack(assigns)
"rocket-launch" -> rocket_launch(assigns)
"server-stack" -> server_stack(assigns)
"slash" -> slash(assigns)
"sparkles" -> sparkles(assigns)
"shield-check" -> shield_check(assigns)
"shopping-cart" -> shopping_cart(assigns)
Expand Down Expand Up @@ -1123,6 +1125,27 @@ defmodule AzimuttWeb.Components.Icon do
end
end

def information_circle(assigns) do
classes = if assigns[:class], do: " #{assigns[:class]}", else: ""

case assigns[:kind] do
"outline" ->
~H"""
<.outline classes={classes}><path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /></.outline>
"""

"solid" ->
~H"""
<.solid classes={classes}><path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm8.706-1.442c1.146-.573 2.437.463 2.126 1.706l-.709 2.836.042-.02a.75.75 0 0 1 .67 1.34l-.04.022c-1.147.573-2.438-.463-2.127-1.706l.71-2.836-.042.02a.75.75 0 1 1-.671-1.34l.041-.022ZM12 9a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Z" clip-rule="evenodd" /></.solid>
"""

_ ->
~H"""
<.mini classes={classes}><path fill-rule="evenodd" d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-7-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM9 9a.75.75 0 0 0 0 1.5h.253a.25.25 0 0 1 .244.304l-.459 2.066A1.75 1.75 0 0 0 10.747 15H11a.75.75 0 0 0 0-1.5h-.253a.25.25 0 0 1-.244-.304l.459-2.066A1.75 1.75 0 0 0 9.253 9H9Z" clip-rule="evenodd" /></.mini>
"""
end
end

def key(assigns) do
classes = if assigns[:class], do: " #{assigns[:class]}", else: ""

Expand Down Expand Up @@ -1480,6 +1503,27 @@ defmodule AzimuttWeb.Components.Icon do
end
end

def slash(assigns) do
classes = if assigns[:class], do: " #{assigns[:class]}", else: ""

case assigns[:kind] do
"outline" ->
~H"""
<.outline classes={classes}><path stroke-linecap="round" stroke-linejoin="round" d="m9 20.247 6-16.5" /></.outline>
"""

"solid" ->
~H"""
<.solid classes={classes}><path fill-rule="evenodd" d="M15.256 3.042a.75.75 0 0 1 .449.962l-6 16.5a.75.75 0 1 1-1.41-.513l6-16.5a.75.75 0 0 1 .961-.449Z" clip-rule="evenodd" /></.solid>
"""

_ ->
~H"""
<.mini classes={classes}><path fill-rule="evenodd" d="M12.528 3.047a.75.75 0 0 1 .449.961L8.433 16.504a.75.75 0 1 1-1.41-.512l4.544-12.496a.75.75 0 0 1 .961-.449Z" clip-rule="evenodd" /></.mini>
"""
end
end

def shield_check(assigns) do
classes = if assigns[:class], do: " #{assigns[:class]}", else: ""

Expand Down
29 changes: 22 additions & 7 deletions backend/lib/azimutt_web/controllers/website_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ defmodule AzimuttWeb.WebsiteController do
end

def aml(conn, _params), do: conn |> render("aml.html")
def converters(conn, _params), do: conn |> render("converters.html")
def converters(conn, _params), do: conn |> render("converters/index.html")

def converter(conn, %{"from" => from}) do
Azimutt.converters()
|> Enum.find(fn c -> c.id == from end)
|> Result.from_nillable()
|> Result.map(fn converter -> conn |> render("converter.html", converter: converter) end)
|> Result.map(fn converter -> conn |> render("converters/converter.html", converter: converter) end)
end

def convert(conn, %{"from" => from_id, "to" => to_id}) do
Expand All @@ -42,12 +42,27 @@ defmodule AzimuttWeb.WebsiteController do

from_converter
|> Result.flat_map(fn f -> to_converter |> Result.map(fn t -> {f, t} end) end)
|> Result.map(fn {from, to} -> conn |> render("convert.html", from: from, to: to) end)
|> Result.map(fn {from, to} -> conn |> render("converters/convert.html", from: from, to: to) end)
end

def portal(conn, _params), do: conn |> render("portal.html")
def portal_subscribed(conn, _params), do: conn |> render("portal-subscribed.html")

def docs(conn, _params),
do: conn |> render("docs/index.html", page: %{path: [], name: "Azimutt Documentation", children: Azimutt.doc_pages(), parents: []}, prev: nil, next: nil)

def doc(conn, %{"path" => path}) do
slug = path |> Enum.join("/")
pages = Azimutt.doc_pages_flat()

pages
|> Enum.find_index(fn p -> Enum.join(p.path, "/") == slug end)
|> Result.from_nillable()
|> Result.map(fn index ->
conn |> render("docs/#{slug}.html", page: pages |> Enum.at(index), prev: if(index > 0, do: pages |> Enum.at(index - 1), else: nil), next: pages |> Enum.at(index + 1))
end)
end
loicknuchel marked this conversation as resolved.
Show resolved Hide resolved

def last(conn, _params) do
case conn |> last_used_project do
{:ok, p} -> conn |> redirect(to: Routes.elm_path(conn, :project_show, p.organization_id, p.id))
Expand All @@ -65,24 +80,24 @@ defmodule AzimuttWeb.WebsiteController do
conn |> get_req_header("referer") |> Enum.any?(fn h -> h |> String.contains?(Azimutt.config(:host)) end)
end

def use_cases_index(conn, _params), do: conn |> render("use-cases.html")
def use_cases_index(conn, _params), do: conn |> render("use-cases/index.html")

def use_cases_show(conn, %{"use_case_id" => use_case_id}) do
Azimutt.showcase_usages()
|> Enum.find(fn u -> u.id == use_case_id end)
|> Result.from_nillable()
|> Result.map(fn use_case -> conn |> render("use-case-#{use_case_id}.html", use_case: use_case) end)
|> Result.map(fn use_case -> conn |> render("use-cases/#{use_case_id}.html", use_case: use_case) end)
end

def features_index(conn, _params), do: conn |> render("features.html")
def features_index(conn, _params), do: conn |> render("features/index.html")

def features_show(conn, %{"feature_id" => feature_id}) do
Azimutt.showcase_features()
|> Enum.find_index(fn f -> f.id == feature_id end)
|> Result.from_nillable()
|> Result.map(fn index ->
conn
|> render("feature-#{feature_id}.html",
|> render("features/#{feature_id}.html",
feature: Azimutt.showcase_features() |> Enum.at(index),
previous: if(index > 0, do: Azimutt.showcase_features() |> Enum.at(index - 1), else: nil),
next: Azimutt.showcase_features() |> Enum.at(index + 1)
Expand Down
2 changes: 2 additions & 0 deletions backend/lib/azimutt_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ defmodule AzimuttWeb.Router do
get("/converters", WebsiteController, :converters)
get("/converters/:from", WebsiteController, :converter)
get("/converters/:from/to/:to", WebsiteController, :convert)
get("/docs", WebsiteController, :docs)
get("/docs/*path", WebsiteController, :doc)
get("/last", WebsiteController, :last)
get("/use-cases", WebsiteController, :use_cases_index)
get("/use-cases/:use_case_id", WebsiteController, :use_cases_show)
Expand Down
6 changes: 3 additions & 3 deletions backend/lib/azimutt_web/templates/blog/_blog_footer.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
</div>
</div>
<div class="flex justify-center pt-4 space-x-4 align-center">
<a href={Azimutt.config(:azimutt_github)} rel="noopener noreferrer" aria-label="GitHub" class="p-2 rounded-md">
<a href={Azimutt.config(:azimutt_github)} target="_blank" rel="noopener noreferrer" aria-label="GitHub" class="p-2 rounded-md">
<svg viewBox="0 0 496 512" xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 fill-current">
<path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"></path>
</svg>
</a>
<a href={Azimutt.config(:azimutt_twitter)} rel="noopener noreferrer" aria-label="Twitter" class="p-2 rounded-md">
<a href={Azimutt.config(:azimutt_twitter)} target="_blank" rel="noopener noreferrer" aria-label="Twitter" class="p-2 rounded-md">
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 fill-current">
<path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"></path>
</svg>
</a>
<a href={"mailto:#{Azimutt.config(:contact_email)}"} rel="noopener noreferrer" aria-label="Email" class="p-2 rounded-md">
<a href={"mailto:#{Azimutt.config(:contact_email)}"} target="_blank" rel="noopener noreferrer" aria-label="Email" class="p-2 rounded-md">
loicknuchel marked this conversation as resolved.
Show resolved Hide resolved
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 fill-current">
<path d="M464 64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V112c0-26.51-21.49-48-48-48zm0 48v40.805c-22.422 18.259-58.168 46.651-134.587 106.49-16.841 13.247-50.201 45.072-73.413 44.701-23.208.375-56.579-31.459-73.413-44.701C106.18 199.465 70.425 171.067 48 152.805V112h416zM48 400V214.398c22.914 18.251 55.409 43.862 104.938 82.646 21.857 17.205 60.134 55.186 103.062 54.955 42.717.231 80.509-37.199 103.053-54.947 49.528-38.783 82.032-64.401 104.947-82.653V400H48z"></path>
</svg>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</div>
<div class="mt-10 flex space-x-3 sm:border-l sm:border-transparent sm:pl-6">
<a href={CleverCloud.addon_settings_url(@resource.owner_id, @resource.addon_id)} class="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Go back to Clever Cloud</a>
<a href={"mailto:#{Azimutt.config(:support_email)}"} rel="noopener noreferrer" class="inline-flex items-center rounded-md border border-transparent bg-indigo-100 px-4 py-2 text-sm font-medium text-indigo-700 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Contact us</a>
<a href={"mailto:#{Azimutt.config(:support_email)}"} target="_blank" rel="noopener noreferrer" class="inline-flex items-center rounded-md border border-transparent bg-indigo-100 px-4 py-2 text-sm font-medium text-indigo-700 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Contact us</a>
</div>
</div>
</main>
Expand Down
Loading
Loading