Compare commits

..

No commits in common. "7813738f9131e2b392c7e8d73a9c72559713bb28" and "59283a0217383abd31e1d5c6f137cfc35a20cc59" have entirely different histories.

20 changed files with 45 additions and 231 deletions

View File

@ -1,7 +1,3 @@
# v0.1.6
- fix formatting in note/context/step contents
- add json export for data
# v0.1.5 # v0.1.5
- fix overflow on note/contexts/step contents - fix overflow on note/contexts/step contents

View File

@ -9,16 +9,6 @@ defmodule Memex.Accounts.User do
alias Ecto.{Changeset, UUID} alias Ecto.{Changeset, UUID}
alias Memex.Invites.Invite alias Memex.Invites.Invite
@derive {Jason.Encoder,
only: [
:id,
:email,
:confirmed_at,
:role,
:locale,
:inserted_at,
:updated_at
]}
@derive {Inspect, except: [:password]} @derive {Inspect, except: [:password]}
@primary_key {:id, :binary_id, autogenerate: true} @primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id @foreign_key_type :binary_id

View File

@ -9,15 +9,6 @@ defmodule Memex.Contexts.Context do
alias Ecto.{Changeset, UUID} alias Ecto.{Changeset, UUID}
alias Memex.{Accounts.User, Repo} alias Memex.{Accounts.User, Repo}
@derive {Jason.Encoder,
only: [
:slug,
:content,
:tags,
:visibility,
:inserted_at,
:updated_at
]}
@primary_key {:id, :binary_id, autogenerate: true} @primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id @foreign_key_type :binary_id
schema "contexts" do schema "contexts" do

View File

@ -8,15 +8,6 @@ defmodule Memex.Notes.Note do
alias Ecto.{Changeset, UUID} alias Ecto.{Changeset, UUID}
alias Memex.{Accounts.User, Repo} alias Memex.{Accounts.User, Repo}
@derive {Jason.Encoder,
only: [
:slug,
:content,
:tags,
:visibility,
:inserted_at,
:updated_at
]}
@primary_key {:id, :binary_id, autogenerate: true} @primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id @foreign_key_type :binary_id
schema "notes" do schema "notes" do

View File

@ -8,16 +8,6 @@ defmodule Memex.Pipelines.Pipeline do
alias Ecto.{Changeset, UUID} alias Ecto.{Changeset, UUID}
alias Memex.{Accounts.User, Pipelines.Steps.Step, Repo} alias Memex.{Accounts.User, Pipelines.Steps.Step, Repo}
@derive {Jason.Encoder,
only: [
:slug,
:description,
:tags,
:visibility,
:inserted_at,
:steps,
:updated_at
]}
@primary_key {:id, :binary_id, autogenerate: true} @primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id @foreign_key_type :binary_id
schema "pipelines" do schema "pipelines" do

View File

@ -7,14 +7,6 @@ defmodule Memex.Pipelines.Steps.Step do
alias Ecto.{Changeset, UUID} alias Ecto.{Changeset, UUID}
alias Memex.{Accounts.User, Pipelines.Pipeline} alias Memex.{Accounts.User, Pipelines.Pipeline}
@derive {Jason.Encoder,
only: [
:title,
:content,
:position,
:inserted_at,
:updated_at
]}
@primary_key {:id, :binary_id, autogenerate: true} @primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id @foreign_key_type :binary_id
schema "steps" do schema "steps" do

View File

@ -12,7 +12,7 @@ defmodule MemexWeb.Components.ContextContent do
~H""" ~H"""
<div <div
id={"show-context-content-#{@context.id}"} id={"show-context-content-#{@context.id}"}
class="input input-primary h-128 min-h-128 inline-block whitespace-pre-wrap overflow-x-hidden overflow-y-auto" class="input input-primary h-128 min-h-128 inline-block overflow-x-hidden overflow-y-auto"
phx-hook="MaintainAttrs" phx-hook="MaintainAttrs"
phx-update="ignore" phx-update="ignore"
readonly readonly
@ -39,6 +39,7 @@ defmodule MemexWeb.Components.ContextContent do
"</p>#{link}<p class=\"inline\">" "</p>#{link}<p class=\"inline\">"
end end
) )
|> String.replace("\n", "<br>")
|> HTML.raw() |> HTML.raw()
end end
end end

View File

@ -12,7 +12,7 @@ defmodule MemexWeb.Components.NoteContent do
~H""" ~H"""
<div <div
id={"show-note-content-#{@note.id}"} id={"show-note-content-#{@note.id}"}
class="input input-primary h-128 min-h-128 inline-block whitespace-pre-wrap overflow-x-hidden overflow-y-auto" class="input input-primary h-128 min-h-128 inline-block overflow-x-hidden overflow-y-auto"
phx-hook="MaintainAttrs" phx-hook="MaintainAttrs"
phx-update="ignore" phx-update="ignore"
readonly readonly
@ -39,6 +39,7 @@ defmodule MemexWeb.Components.NoteContent do
"</p>#{link}<p class=\"inline\">" "</p>#{link}<p class=\"inline\">"
end end
) )
|> String.replace("\n", "<br>")
|> HTML.raw() |> HTML.raw()
end end
end end

View File

@ -12,7 +12,7 @@ defmodule MemexWeb.Components.StepContent do
~H""" ~H"""
<div <div
id={"show-step-content-#{@step.id}"} id={"show-step-content-#{@step.id}"}
class="input input-primary h-32 min-h-32 inline-block whitespace-pre-wrap overflow-x-hidden overflow-y-auto" class="input input-primary h-32 min-h-32 inline-block overflow-x-hidden overflow-y-auto"
phx-hook="MaintainAttrs" phx-hook="MaintainAttrs"
phx-update="ignore" phx-update="ignore"
readonly readonly
@ -39,6 +39,7 @@ defmodule MemexWeb.Components.StepContent do
"</p>#{link}<p class=\"inline\">" "</p>#{link}<p class=\"inline\">"
end end
) )
|> String.replace("\n", "<br>")
|> HTML.raw() |> HTML.raw()
end end
end end

View File

@ -1,17 +0,0 @@
defmodule MemexWeb.ExportController do
use MemexWeb, :controller
alias Memex.{Contexts, Notes, Pipelines, Pipelines.Steps}
def export(%{assigns: %{current_user: current_user}} = conn, %{"mode" => "json"}) do
pipelines =
Pipelines.list_pipelines(current_user)
|> Enum.map(fn pipeline -> Steps.preload_steps(pipeline, current_user) end)
json(conn, %{
user: current_user,
notes: Notes.list_notes(current_user),
contexts: Contexts.list_contexts(current_user),
pipelines: pipelines
})
end
end

View File

@ -76,7 +76,6 @@ defmodule MemexWeb.Router do
put "/users/settings", UserSettingsController, :update put "/users/settings", UserSettingsController, :update
delete "/users/settings/:id", UserSettingsController, :delete delete "/users/settings/:id", UserSettingsController, :delete
get "/users/settings/confirm_email/:token", UserSettingsController, :confirm_email get "/users/settings/confirm_email/:token", UserSettingsController, :confirm_email
get "/export/:mode", ExportController, :export
end end
scope "/", MemexWeb do scope "/", MemexWeb do

View File

@ -136,22 +136,12 @@
<hr class="hr" /> <hr class="hr" />
<div class="flex justify-center items-center">
<.link
href={Routes.export_path(@conn, :export, :json)}
class="mx-4 my-2 btn btn-primary"
target="_blank"
>
<%= dgettext("actions", "export data as json") %>
</.link>
<.link <.link
href={Routes.user_settings_path(@conn, :delete, @current_user)} href={Routes.user_settings_path(@conn, :delete, @current_user)}
method={:delete} method={:delete}
class="mx-4 my-2 btn btn-alert" class="btn btn-alert"
data-confirm={dgettext("prompts", "are you sure you want to delete your account?")} data-confirm={dgettext("prompts", "are you sure you want to delete your account?")}
> >
<%= dgettext("actions", "delete user") %> <%= dgettext("actions", "delete user") %>
</.link> </.link>
</div>
</div> </div>

View File

@ -4,7 +4,7 @@ defmodule Memex.MixProject do
def project do def project do
[ [
app: :memex, app: :memex,
version: "0.1.6", version: "0.1.5",
elixir: "~> 1.14", elixir: "~> 1.14",
elixirc_paths: elixirc_paths(Mix.env()), elixirc_paths: elixirc_paths(Mix.env()),
compilers: Mix.compilers(), compilers: Mix.compilers(),

View File

@ -66,7 +66,7 @@ msgstr ""
msgid "delete" msgid "delete"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:154 #: lib/memex_web/templates/user_settings/edit.html.heex:145
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "delete user" msgid "delete user"
msgstr "" msgstr ""
@ -155,8 +155,3 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "send instructions to reset password" msgid "send instructions to reset password"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:145
#, elixir-autogen, elixir-format
msgid "export data as json"
msgstr ""

View File

@ -67,7 +67,7 @@ msgstr ""
msgid "delete" msgid "delete"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:154 #: lib/memex_web/templates/user_settings/edit.html.heex:145
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "delete user" msgid "delete user"
msgstr "" msgstr ""
@ -156,8 +156,3 @@ msgstr ""
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "send instructions to reset password" msgid "send instructions to reset password"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:145
#, elixir-autogen, elixir-format
msgid "export data as json"
msgstr ""

View File

@ -76,22 +76,22 @@ msgstr ""
msgid "You must confirm your account and log in to access this page." msgid "You must confirm your account and log in to access this page."
msgstr "" msgstr ""
#: lib/memex/accounts/user.ex:139 #: lib/memex/accounts/user.ex:129
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "did not change" msgid "did not change"
msgstr "" msgstr ""
#: lib/memex/accounts/user.ex:160 #: lib/memex/accounts/user.ex:150
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "does not match password" msgid "does not match password"
msgstr "" msgstr ""
#: lib/memex/accounts/user.ex:197 #: lib/memex/accounts/user.ex:187
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "is not valid" msgid "is not valid"
msgstr "" msgstr ""
#: lib/memex/accounts/user.ex:95 #: lib/memex/accounts/user.ex:85
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "must have the @ sign and no spaces" msgid "must have the @ sign and no spaces"
msgstr "" msgstr ""
@ -102,12 +102,12 @@ msgstr ""
msgid "oops, something went wrong! Please check the errors below" msgid "oops, something went wrong! Please check the errors below"
msgstr "" msgstr ""
#: lib/memex/contexts/context.ex:58 #: lib/memex/contexts/context.ex:49
#: lib/memex/contexts/context.ex:71 #: lib/memex/contexts/context.ex:62
#: lib/memex/notes/note.ex:57 #: lib/memex/notes/note.ex:48
#: lib/memex/notes/note.ex:70 #: lib/memex/notes/note.ex:61
#: lib/memex/pipelines/pipeline.ex:60 #: lib/memex/pipelines/pipeline.ex:50
#: lib/memex/pipelines/pipeline.ex:73 #: lib/memex/pipelines/pipeline.ex:63
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "invalid format: only numbers, letters and hyphen are accepted" msgid "invalid format: only numbers, letters and hyphen are accepted"
msgstr "" msgstr ""
@ -132,9 +132,9 @@ msgstr ""
msgid "unauthorized" msgid "unauthorized"
msgstr "" msgstr ""
#: lib/memex/contexts/context.ex:84 #: lib/memex/contexts/context.ex:75
#: lib/memex/notes/note.ex:83 #: lib/memex/notes/note.ex:74
#: lib/memex/pipelines/pipeline.ex:86 #: lib/memex/pipelines/pipeline.ex:76
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited" msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited"
msgstr "" msgstr ""

View File

@ -122,7 +122,7 @@ msgstr ""
msgid "are you sure you want to delete the invite for %{invite_name}?" msgid "are you sure you want to delete the invite for %{invite_name}?"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:152 #: lib/memex_web/templates/user_settings/edit.html.heex:143
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "are you sure you want to delete your account?" msgid "are you sure you want to delete your account?"
msgstr "" msgstr ""

View File

@ -75,22 +75,22 @@ msgstr ""
msgid "You must confirm your account and log in to access this page." msgid "You must confirm your account and log in to access this page."
msgstr "" msgstr ""
#: lib/memex/accounts/user.ex:139 #: lib/memex/accounts/user.ex:129
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "did not change" msgid "did not change"
msgstr "" msgstr ""
#: lib/memex/accounts/user.ex:160 #: lib/memex/accounts/user.ex:150
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "does not match password" msgid "does not match password"
msgstr "" msgstr ""
#: lib/memex/accounts/user.ex:197 #: lib/memex/accounts/user.ex:187
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "is not valid" msgid "is not valid"
msgstr "" msgstr ""
#: lib/memex/accounts/user.ex:95 #: lib/memex/accounts/user.ex:85
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "must have the @ sign and no spaces" msgid "must have the @ sign and no spaces"
msgstr "" msgstr ""
@ -101,12 +101,12 @@ msgstr ""
msgid "oops, something went wrong! Please check the errors below" msgid "oops, something went wrong! Please check the errors below"
msgstr "" msgstr ""
#: lib/memex/contexts/context.ex:58 #: lib/memex/contexts/context.ex:49
#: lib/memex/contexts/context.ex:71 #: lib/memex/contexts/context.ex:62
#: lib/memex/notes/note.ex:57 #: lib/memex/notes/note.ex:48
#: lib/memex/notes/note.ex:70 #: lib/memex/notes/note.ex:61
#: lib/memex/pipelines/pipeline.ex:60 #: lib/memex/pipelines/pipeline.ex:50
#: lib/memex/pipelines/pipeline.ex:73 #: lib/memex/pipelines/pipeline.ex:63
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "invalid format: only numbers, letters and hyphen are accepted" msgid "invalid format: only numbers, letters and hyphen are accepted"
msgstr "" msgstr ""
@ -131,9 +131,9 @@ msgstr ""
msgid "unauthorized" msgid "unauthorized"
msgstr "" msgstr ""
#: lib/memex/contexts/context.ex:84 #: lib/memex/contexts/context.ex:75
#: lib/memex/notes/note.ex:83 #: lib/memex/notes/note.ex:74
#: lib/memex/pipelines/pipeline.ex:86 #: lib/memex/pipelines/pipeline.ex:76
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited" msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited"
msgstr "" msgstr ""

View File

@ -121,7 +121,7 @@ msgstr ""
msgid "are you sure you want to delete the invite for %{invite_name}?" msgid "are you sure you want to delete the invite for %{invite_name}?"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:152 #: lib/memex_web/templates/user_settings/edit.html.heex:143
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "are you sure you want to delete your account?" msgid "are you sure you want to delete your account?"
msgstr "" msgstr ""

View File

@ -1,101 +0,0 @@
defmodule MemexWeb.ExportControllerTest do
@moduledoc """
Tests the export function
"""
use MemexWeb.ConnCase
import Memex.{ContextsFixtures, NotesFixtures, PipelinesFixtures, StepsFixtures}
@moduletag :export_controller_test
setup %{conn: conn} do
current_user = user_fixture() |> confirm_user()
[
current_user: current_user,
conn: conn |> log_in_user(current_user)
]
end
defp add_data(%{current_user: current_user}) do
note = note_fixture(current_user)
context = context_fixture(current_user)
pipeline = pipeline_fixture(current_user)
step = step_fixture(0, pipeline, current_user)
%{
note: note,
context: context,
pipeline: pipeline,
step: step
}
end
describe "Exports data" do
setup [:add_data]
test "in JSON", %{
conn: conn,
current_user: current_user,
note: note,
context: context,
pipeline: pipeline,
step: step
} do
conn = get(conn, Routes.export_path(conn, :export, :json))
ideal_note = %{
"slug" => note.slug,
"content" => note.content,
"tags" => note.tags,
"visibility" => note.visibility |> to_string(),
"inserted_at" => note.inserted_at |> NaiveDateTime.to_iso8601(),
"updated_at" => note.updated_at |> NaiveDateTime.to_iso8601()
}
ideal_context = %{
"slug" => context.slug,
"content" => context.content,
"tags" => context.tags,
"visibility" => context.visibility |> to_string(),
"inserted_at" => context.inserted_at |> NaiveDateTime.to_iso8601(),
"updated_at" => context.updated_at |> NaiveDateTime.to_iso8601()
}
ideal_pipeline = %{
"slug" => pipeline.slug,
"description" => pipeline.description,
"tags" => pipeline.tags,
"visibility" => pipeline.visibility |> to_string(),
"inserted_at" => pipeline.inserted_at |> NaiveDateTime.to_iso8601(),
"updated_at" => pipeline.updated_at |> NaiveDateTime.to_iso8601(),
"steps" => [
%{
"title" => step.title,
"content" => step.content,
"position" => step.position,
"inserted_at" => step.inserted_at |> NaiveDateTime.to_iso8601(),
"updated_at" => step.updated_at |> NaiveDateTime.to_iso8601()
}
]
}
ideal_user = %{
"confirmed_at" =>
current_user.confirmed_at |> Jason.encode!() |> String.replace(~r/\"/, ""),
"email" => current_user.email,
"id" => current_user.id,
"locale" => current_user.locale,
"role" => to_string(current_user.role),
"inserted_at" => current_user.inserted_at |> NaiveDateTime.to_iso8601(),
"updated_at" => current_user.updated_at |> NaiveDateTime.to_iso8601()
}
json_resp = conn |> json_response(200)
assert %{"notes" => [^ideal_note]} = json_resp
assert %{"contexts" => [^ideal_context]} = json_resp
assert %{"pipelines" => [^ideal_pipeline]} = json_resp
assert %{"user" => ^ideal_user} = json_resp
end
end
end