plain-rails 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +31 -9
- data/app/assets/builds/plain.css +1 -1
- data/app/assets/stylesheets/plain/application.tailwind.css +34 -1
- data/app/controllers/plain/conversations_controller.rb +8 -4
- data/app/controllers/plain/docs_controller.rb +51 -16
- data/app/controllers/plain/documents_controller.rb +28 -0
- data/app/controllers/plain/home_controller.rb +2 -2
- data/app/helpers/plain/documents_helper.rb +4 -0
- data/app/models/plain/document.rb +49 -0
- data/app/services/plain/ai_docs.rb +10 -9
- data/app/services/plain/docs_service.rb +21 -3
- data/app/views/layouts/plain/application.html.erb +133 -49
- data/app/views/plain/conversations/_conversation_item.html.erb +22 -15
- data/app/views/plain/conversations/_conversation_list.html.erb +1 -1
- data/app/views/plain/conversations/_modal.html.erb +9 -8
- data/app/views/plain/conversations/_status.erb +9 -0
- data/app/views/plain/conversations/destroy.turbo_stream.erb +1 -0
- data/app/views/plain/conversations/index.html.erb +9 -5
- data/app/views/plain/conversations/pin.turbo_stream.erb +3 -0
- data/app/views/plain/conversations/show.html.erb +3 -1
- data/app/views/plain/docs/_form.html.erb +41 -0
- data/app/views/plain/docs/_menu.erb +1 -5
- data/app/views/plain/docs/_sections.erb +1 -1
- data/app/views/plain/docs/edit.html.erb +3 -0
- data/app/views/plain/docs/show.html.erb +28 -9
- data/app/views/plain/docs/update.turbo_stream.erb +3 -0
- data/app/views/plain/documents/_form.erb +47 -0
- data/app/views/plain/documents/create.turbo_stream.erb +15 -0
- data/app/views/plain/documents/new.html.erb +3 -0
- data/app/views/plain/home/index.html.erb +8 -25
- data/app/views/plain/messages/_form.html.erb +7 -3
- data/app/views/plain/messages/_message_item.html.erb +35 -13
- data/app/views/plain/shared/_powered_by.erb +10 -0
- data/config/routes.rb +9 -1
- data/lib/plain/configuration.rb +2 -1
- data/lib/plain/engine.rb +1 -1
- data/lib/plain/version.rb +1 -1
- data/lib/tasks/plain_tasks.rake +40 -0
- metadata +19 -21
- data/app/views/plain/conversations/_conversation_item.erb +0 -15
@@ -40,11 +40,11 @@ module Langchain
|
|
40
40
|
end
|
41
41
|
|
42
42
|
module Plain
|
43
|
-
class Markdownray < Redcarpet::Render::HTML
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
43
|
+
#class Markdownray < Redcarpet::Render::HTML
|
44
|
+
# def block_code(code, language)
|
45
|
+
# CodeRay.scan(code, language).div() rescue "xxx"
|
46
|
+
# end
|
47
|
+
#end
|
48
48
|
|
49
49
|
class AiDocs
|
50
50
|
|
@@ -87,9 +87,10 @@ module Plain
|
|
87
87
|
# Distinguishing files from directories
|
88
88
|
files_without_extension, directories = Plain.configuration.paths.partition { |path| File.file?(path) }
|
89
89
|
|
90
|
+
|
90
91
|
# Getting files from directories based on the allowed extensions
|
91
92
|
files_with_extension = directories.flat_map do |dir|
|
92
|
-
Dir[File.join(dir, "*.{#{Plain.configuration.extensions.join(',')}}")]
|
93
|
+
Dir[File.join("#{dir}/*/**", "*.{#{Plain.configuration.extensions.join(',')}}")]
|
93
94
|
end
|
94
95
|
|
95
96
|
puts "FILES WITH EXTENSIONS"
|
@@ -109,15 +110,15 @@ module Plain
|
|
109
110
|
end
|
110
111
|
|
111
112
|
def self.convert_markdown(text)
|
112
|
-
rndr = Markdownray.new(filter_html: true, hard_wrap: true)
|
113
|
+
# rndr = Markdownray.new(filter_html: true, hard_wrap: true)
|
113
114
|
options = {
|
114
115
|
fenced_code_blocks: true,
|
115
116
|
no_intra_emphasis: true,
|
116
117
|
autolink: true,
|
117
118
|
lax_html_blocks: true
|
118
119
|
}
|
119
|
-
|
120
|
-
markdown_to_html = Redcarpet::Markdown.new(rndr, options)
|
120
|
+
markdown_to_html = Redcarpet::Markdown.new(Redcarpet::Render::HTML, options)
|
121
|
+
# markdown_to_html = Redcarpet::Markdown.new(rndr, options)
|
121
122
|
markdown_to_html.render(text) #rescue nil
|
122
123
|
end
|
123
124
|
|
@@ -13,6 +13,21 @@ class Plain::DocsService
|
|
13
13
|
}
|
14
14
|
end
|
15
15
|
|
16
|
+
# used in the compile rake task
|
17
|
+
def self.get_all_files(structure)
|
18
|
+
files = []
|
19
|
+
|
20
|
+
structure[:children].each do |child|
|
21
|
+
if child[:type] == 'file'
|
22
|
+
files << child
|
23
|
+
elsif child[:type] == 'directory'
|
24
|
+
files.concat(get_all_files(child))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
files
|
29
|
+
end
|
30
|
+
|
16
31
|
def self.parse_section_items
|
17
32
|
config = self.config
|
18
33
|
main_sections = config['sections']
|
@@ -50,9 +65,14 @@ class Plain::DocsService
|
|
50
65
|
# Sort by position and return children
|
51
66
|
all_sections.sort_by { |section| section[:position] }
|
52
67
|
end
|
68
|
+
|
69
|
+
def self.get_markdown(file_path)
|
70
|
+
parsed = FrontMatterParser::Parser.parse_file(Rails.root.join('docs', "#{file_path}.md"))
|
71
|
+
parsed
|
72
|
+
end
|
53
73
|
|
54
74
|
def self.get_content(file_path)
|
55
|
-
parsed =
|
75
|
+
parsed = self.get_markdown(file_path)
|
56
76
|
|
57
77
|
# markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
|
58
78
|
# markdown.render(parsed.content).html_safe
|
@@ -103,8 +123,6 @@ class Plain::DocsService
|
|
103
123
|
end
|
104
124
|
end
|
105
125
|
|
106
|
-
|
107
|
-
|
108
126
|
def self.assign_position_from_config(parent, path)
|
109
127
|
config = YAML.load_file(path)
|
110
128
|
parent[:position] = config&.fetch('position', DEFAULT_POSITION)
|
@@ -1,51 +1,135 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
2
|
+
<html data-controller="dark-mode">
|
3
|
+
<head>
|
4
|
+
<title>Plain</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
|
8
|
+
|
9
|
+
<% if params[:static].present? %>
|
10
|
+
<style>
|
11
|
+
<%= Rails.application.assets.find_asset('plain.css').to_s %>
|
12
|
+
</style>
|
13
|
+
<% else %>
|
14
|
+
<%= stylesheet_link_tag "plain", "data-turbo-track": "reload" %>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<!-- actual rails host app -->
|
18
|
+
<% #= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
|
19
|
+
|
20
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/dark.min.css">
|
21
|
+
<!--<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/default.min.css">-->
|
22
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
23
|
+
|
24
|
+
<link
|
25
|
+
rel="stylesheet"
|
26
|
+
href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css"
|
27
|
+
/>
|
28
|
+
<script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
|
29
|
+
|
30
|
+
<script type="module">
|
31
|
+
import Markdoc from "https://cdn.skypack.dev/@markdoc/markdoc";
|
32
|
+
window.Markdoc = Markdoc
|
33
|
+
</script>
|
34
|
+
|
35
|
+
<script type="module">
|
36
|
+
import {Turbo} from 'https://jspm.dev/@hotwired/turbo-rails';
|
37
|
+
window.Turbo = Turbo
|
38
|
+
</script>
|
39
|
+
|
40
|
+
<script type="module">
|
41
|
+
import { Application, Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js"
|
42
|
+
window.Stimulus = Application.start()
|
43
|
+
|
44
|
+
Stimulus.debug = true
|
45
|
+
Stimulus.register("scroll-to", class extends Controller {
|
46
|
+
// static targets = [ "scroll" ]
|
47
|
+
connect() {
|
48
|
+
this.element.scrollIntoView()
|
49
|
+
}
|
50
|
+
})
|
51
|
+
|
52
|
+
Stimulus.register("toggle-class", class extends Controller {
|
53
|
+
toggle(event) {
|
54
|
+
// Toggle 'active' class on button
|
55
|
+
event.currentTarget.classList.toggle('active');
|
56
|
+
|
57
|
+
// Toggle 'hidden' class on controller's root element
|
58
|
+
this.element.classList.toggle('hidden');
|
59
|
+
}
|
60
|
+
})
|
61
|
+
|
62
|
+
Stimulus.register("markdoc", class extends Controller {
|
63
|
+
static values = {
|
64
|
+
content: String
|
65
|
+
}
|
66
|
+
|
67
|
+
static targets = ["container"]
|
68
|
+
|
69
|
+
connect(){
|
70
|
+
console.log("content", this.contentValue)
|
71
|
+
this.renderMarkdoc()
|
72
|
+
}
|
73
|
+
|
74
|
+
contentValueChanged() {
|
75
|
+
this.renderMarkdoc()
|
76
|
+
}
|
77
|
+
|
78
|
+
renderMarkdoc(){
|
79
|
+
const ast = Markdoc.parse(this.contentValue)
|
80
|
+
console.log(ast)
|
81
|
+
const content = Markdoc.transform(ast, /* config */);
|
82
|
+
const html = Markdoc.renderers.html(content)
|
83
|
+
console.log(html)
|
84
|
+
|
85
|
+
this.containerTarget.innerHTML = html
|
86
|
+
|
87
|
+
this.containerTarget.querySelectorAll('pre').forEach((el) => {
|
88
|
+
hljs.highlightElement(el);
|
89
|
+
});
|
90
|
+
// console.log(`${Markdoc.renderers.html(content)}`)
|
91
|
+
}
|
92
|
+
})
|
93
|
+
|
94
|
+
Stimulus.register("highlight", class extends Controller {
|
95
|
+
connect(){
|
96
|
+
this.element.querySelectorAll('pre').forEach((el) => {
|
97
|
+
hljs.highlightElement(el);
|
98
|
+
});
|
99
|
+
}
|
100
|
+
})
|
101
|
+
|
102
|
+
Stimulus.register("dark-mode", class extends Controller {
|
103
|
+
initialize() {
|
104
|
+
if (localStorage.getItem('dark-mode') === 'enabled') {
|
105
|
+
this.element.classList.add('dark');
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
toggleDarkMode(e) {
|
110
|
+
e.preventDefault()
|
111
|
+
if (this.element.classList.toggle('dark')) {
|
112
|
+
localStorage.setItem('dark-mode', 'enabled');
|
113
|
+
} else {
|
114
|
+
localStorage.setItem('dark-mode', 'disabled');
|
115
|
+
}
|
116
|
+
}
|
117
|
+
});
|
118
|
+
|
119
|
+
Stimulus.register("markdown-editor", class extends Controller {
|
120
|
+
initialize() {
|
121
|
+
this.editor = new EasyMDE({element: this.element });
|
122
|
+
}
|
123
|
+
|
124
|
+
disconnect(){
|
125
|
+
this.editor && this.editor.cleanup()
|
126
|
+
}
|
127
|
+
});
|
128
|
+
</script>
|
129
|
+
|
130
|
+
</head>
|
131
|
+
|
132
|
+
<body class="antialiased text-zinc-500 dark:text-zinc-400 bg-white dark:bg-zinc-900">
|
133
|
+
<%= yield %>
|
134
|
+
</body>
|
51
135
|
</html>
|
@@ -1,21 +1,28 @@
|
|
1
|
-
|
2
|
-
<%= link_to conversation_path(conversation), data: {"turbo-frame": "plain"} do %>
|
3
|
-
<div class="p-2 rounded-sm hover:bg-black/5">
|
1
|
+
<div class="p-2 rounded-sm hover:bg-black/5" id="conversation-<%= conversation.id%>">
|
4
2
|
|
5
|
-
|
6
|
-
<% if conversation.pinned? %>
|
7
|
-
<div class="w-5 h-5">
|
8
|
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
9
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0111.186 0z" />
|
10
|
-
</svg>
|
11
|
-
</div>
|
12
|
-
<% end %>
|
3
|
+
<div class="flex justify-between">
|
13
4
|
|
5
|
+
<div class="flex space-x-2 ">
|
6
|
+
<%= render "plain/conversations/status", conversation: conversation %>
|
7
|
+
|
8
|
+
<%= link_to conversation_path(conversation), data: {"turbo-frame": "plain"} do %>
|
14
9
|
<span><%= conversation.subject || "new chat" %> </span>
|
15
|
-
|
16
|
-
<p class="text-xs">
|
17
|
-
<%= time_ago_in_words(conversation.created_at) %>
|
18
|
-
</p>
|
10
|
+
<% end %>
|
19
11
|
</div>
|
12
|
+
|
13
|
+
<% if !Rails.env.production? %>
|
14
|
+
<%= link_to conversation_path(conversation),
|
15
|
+
class: "rounded-full p-1 hover:border dark:border-gray-600",
|
16
|
+
"data-turbo-method": "delete",
|
17
|
+
"data-turbo-confirm": "sure?" do %>
|
18
|
+
<svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
19
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path>
|
20
|
+
</svg>
|
21
|
+
<% end %>
|
20
22
|
<% end %>
|
21
23
|
</div>
|
24
|
+
<p class="text-xs text-gray-400">
|
25
|
+
<%= time_ago_in_words(conversation.created_at) %>
|
26
|
+
</p>
|
27
|
+
|
28
|
+
</div>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<%= turbo_frame_tag "conversation-list-#{@current_page}" do %>
|
2
|
-
<div class="divide divide-y">
|
2
|
+
<div class="divide divide-y dark:divide-zinc-700">
|
3
3
|
<%= render partial: "plain/conversations/conversation_item", collection: @conversations, as: :conversation %>
|
4
4
|
</div>
|
5
5
|
<% if @conversations.size.positive? %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="relative z-50"
|
1
|
+
<div class="relative z-50 antialiased"
|
2
2
|
id="ai-assistant"
|
3
3
|
data-controller="toggle-class"
|
4
4
|
aria-labelledby="slide-over-title"
|
@@ -24,26 +24,27 @@
|
|
24
24
|
<div class="flex h-full flex-col divide-y divide-gray-200 bg-white shadow-xl">
|
25
25
|
|
26
26
|
|
27
|
-
<div class="h-0 flex-1 overflow-y-auto bg-
|
28
|
-
<div class="bg-
|
27
|
+
<div class="h-0 flex-1 overflow-y-auto bg-zinc-50 dark:bg-zinc-900 border-l dark:border-zinc-700">
|
28
|
+
<div class="bg-white/80 dark:bg-zinc-900/90 backdrop-blur shadow-[0_1px_rgba(202,206,214,.3),0_5px_10px_-5px_rgba(0,0,0,.05)] justify-between py-3 pl-3 pr-2">
|
29
29
|
<div class="flex items-center justify-between">
|
30
30
|
|
31
31
|
<% if @conversation.present? || @needs_back %>
|
32
|
-
<%= link_to plain.root_path, class: "p-
|
32
|
+
<%= link_to plain.root_path, class: "p-2 rounded-md hover:bg-black/10" do %>
|
33
33
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
34
34
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12h-15m0 0l6.75 6.75M4.5 12l6.75-6.75" />
|
35
35
|
</svg>
|
36
36
|
<% end %>
|
37
37
|
<% end %>
|
38
38
|
|
39
|
-
<h2 class="text-
|
39
|
+
<h2 class="text-lg font-bold leading-6 text-gray-900 dark:text-gray-100"
|
40
|
+
id="slide-over-title">
|
40
41
|
PLAIN AI ASSISTANT
|
41
42
|
</h2>
|
42
43
|
|
43
44
|
<div class="ml-3 flex h-7 items-center">
|
44
45
|
<button type="button"
|
45
46
|
data-action="toggle-class#toggle"
|
46
|
-
class="rounded-md bg-
|
47
|
+
class="rounded-md bg-black/20 text-gray-700 dark:text-gray-300 hover:text-white focus:outline-none focus:ring-2 focus:ring-white">
|
47
48
|
<span class="sr-only">Close panel</span>
|
48
49
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
49
50
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
@@ -52,13 +53,13 @@
|
|
52
53
|
</div>
|
53
54
|
</div>
|
54
55
|
<div class="mt-1 hidden">
|
55
|
-
<p class="text-sm text-brand-300">
|
56
|
+
<p class="text-sm text-brand-300 dark:text-brand-700">
|
56
57
|
Get started by filling in the information below to create your new project.
|
57
58
|
</p>
|
58
59
|
</div>
|
59
60
|
</div>
|
60
61
|
<div class="flex flex-1 flex-col justify-between">
|
61
|
-
<div class="divide-y divide-gray-200">
|
62
|
+
<div class="divide-y divide-gray-200 dark:divide-gray-800">
|
62
63
|
<div class="space-y-6-- py-6--">
|
63
64
|
<%= yield %>
|
64
65
|
</div>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%= turbo_frame_tag "conversation-#{conversation.id}-status" do %>
|
2
|
+
<%= link_to pin_conversation_path(conversation), "data-turbo-method": :put do %>
|
3
|
+
<div class="w-5 h-5 hover:text-green-600 <%= conversation.pinned? ? "text-green-500" : "text-gray-300" %> ">
|
4
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
5
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0111.186 0z" />
|
6
|
+
</svg>
|
7
|
+
</div>
|
8
|
+
<% end %>
|
9
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= turbo_stream.remove "conversation-#{@conversation.id}" %>
|
@@ -1,17 +1,21 @@
|
|
1
1
|
<%= turbo_frame_tag "plain" do %>
|
2
2
|
<%= render "modal" do %>
|
3
|
-
|
4
|
-
|
3
|
+
|
4
|
+
<div class="border dark:border-zinc-900 shadow-sm rounded-md bg-white dark:bg-zinc-800 m-4">
|
5
|
+
<h2 class=" p-4 inline-block text-md sm:text-lg font-extrabold text-zinc-900 tracking-tight dark:text-zinc-200">
|
5
6
|
Continue conversations
|
6
7
|
</h2>
|
7
8
|
|
8
9
|
<div class="h-[calc(100vh-255px)] overflow-y-scroll group">
|
9
10
|
<%= render "plain/conversations/conversation_list" %>
|
10
11
|
</div>
|
11
|
-
|
12
|
-
<div class="
|
13
|
-
<%= link_to "New conversation", new_conversation_path, class: "
|
12
|
+
|
13
|
+
<div class="flex justify-between px-3 py-2 text-xs font-medium border-t dark:border-zinc-700 rounded-b-lg bg-zinc-100/75 dark:bg-zinc-900/75">
|
14
|
+
<%= link_to "New conversation", new_conversation_path, class: "btn-dark" %>
|
15
|
+
<%= link_to "See previous chats", conversations_path, class: "link" %>
|
14
16
|
</div>
|
15
17
|
</div>
|
18
|
+
|
19
|
+
<%= render "plain/shared/powered_by" %>
|
16
20
|
<% end %>
|
17
21
|
<% end %>
|
@@ -1,14 +1,16 @@
|
|
1
1
|
<%= turbo_frame_tag "plain" do %>
|
2
2
|
<%= render "modal" do %>
|
3
3
|
<%= turbo_stream_from(@conversation) %>
|
4
|
-
<div class="h-[calc(100vh-
|
4
|
+
<div class="h-[calc(100vh-117px)] overflow-y-scroll">
|
5
5
|
<%= turbo_frame_tag "message-list-0", loading: :lazy,
|
6
6
|
src: plain.conversation_messages_path(@conversation, page: 0),
|
7
7
|
class: 'empty:block group' %>
|
8
8
|
<div id="new-messages-container"></div>
|
9
9
|
</div>
|
10
|
+
|
10
11
|
<div class="bg-red-600">
|
11
12
|
<%= render "plain/messages/form", conversation: @conversation %>
|
12
13
|
</div>
|
13
14
|
<% end %>
|
15
|
+
|
14
16
|
<% end %>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
<%= form_for @document, url: update_doc_path(@file_path), method: :put do |f| %>
|
3
|
+
<div class="flex space-x-2 dark:bg-zinc-800 p-10 rounded-lg ">
|
4
|
+
|
5
|
+
<% #= @document.errors.full_messages %>
|
6
|
+
<div class="w-2/3">
|
7
|
+
<%= f.text_area :content, "data-controller": "markdown-editor"%>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<div>
|
11
|
+
|
12
|
+
<div class="sm:col-span-3">
|
13
|
+
<%= f.label :title, class: "block text-sm font-medium leading-6 text-gray-900 dark:text-gray-100" %>
|
14
|
+
<div class="mt-2">
|
15
|
+
<%= f.text_field :title, class: "bg-white dark:bg-transparent block w-full rounded-md border-0 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" %>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<div class="sm:col-span-3">
|
20
|
+
<%= f.label :menu_position, class: "block text-sm font-medium leading-6 text-gray-900 dark:text-gray-100" %>
|
21
|
+
<div class="mt-2">
|
22
|
+
<%= f.number_field :menu_position, class: "bg-white dark:bg-transparent block w-full rounded-md border-0 py-1.5 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" %>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<div class="sm:col-span-4">
|
27
|
+
<%= f.label :path, class: "block text-sm font-medium leading-6 text-gray-900 dark:text-gray-100" %>
|
28
|
+
<div class="mt-2">
|
29
|
+
<div class="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600 sm:max-w-md">
|
30
|
+
<span class="flex select-none items-center pl-3 text-gray-500 sm:text-sm">/docs/</span>
|
31
|
+
<%= f.text_field :path, class: "block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 dark:text-gray-100 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6", placeholder: "janesmith" %>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<%= f.submit class: "btn-dark my-2" %>
|
37
|
+
|
38
|
+
</div>
|
39
|
+
|
40
|
+
</div>
|
41
|
+
<% end %>
|
@@ -1,14 +1,11 @@
|
|
1
|
-
|
2
1
|
<ul role="list" class="border-l border-transparent">
|
3
|
-
|
4
|
-
|
5
2
|
<% nodes.each do |node| %>
|
6
3
|
<% if node[:type] == 'directory' %>
|
7
4
|
<li class="relative">
|
8
5
|
<span class="<%= level == 1 ? 'text-xs font-semibold text-zinc-900 dark:text-white' : 'flex justify-between gap-2 py-1 pr-3 text-sm transition pl-4 text-zinc-900 dark:text-white'%>">
|
9
6
|
<%= node[:name].capitalize.humanize %>
|
10
7
|
</span>
|
11
|
-
<%= render partial: 'menu', locals: { nodes: node[:children], level: level + 1 } %>
|
8
|
+
<%= render partial: 'plain/docs/menu', locals: { nodes: node[:children], level: level + 1 } %>
|
12
9
|
</li>
|
13
10
|
<% else %>
|
14
11
|
<li class="relative">
|
@@ -16,5 +13,4 @@
|
|
16
13
|
</li>
|
17
14
|
<% end %>
|
18
15
|
<% end %>
|
19
|
-
|
20
16
|
</ul>
|
@@ -47,7 +47,7 @@
|
|
47
47
|
</svg>
|
48
48
|
</div>
|
49
49
|
</div>
|
50
|
-
<div class="absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20"></div>
|
50
|
+
<div class="dark:bg-zinc-800 absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20"></div>
|
51
51
|
<div class="relative rounded-2xl px-4 pb-4 pt-16">
|
52
52
|
<div class="flex h-7 w-7 items-center justify-center rounded-full bg-zinc-900/5 ring-1 ring-zinc-900/25 backdrop-blur-[2px] transition duration-300 group-hover:bg-white/50 group-hover:ring-zinc-900/25 dark:bg-white/7.5 dark:ring-white/15 dark:group-hover:bg-emerald-300/10 dark:group-hover:ring-emerald-400">
|
53
53
|
<svg viewBox="0 0 20 20" aria-hidden="true" class="h-5 w-5 fill-zinc-700/10 stroke-zinc-700 transition-colors duration-300 group-hover:stroke-zinc-900 dark:fill-white/10 dark:stroke-zinc-400 dark:group-hover:fill-emerald-300/10 dark:group-hover:stroke-emerald-400">
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<div class="contents lg:pointer-events-auto lg:block lg:w-72 lg:overflow-y-auto lg:border-r lg:border-zinc-900/10 lg:px-6 lg:pb-8 lg:pt-4 lg:dark:border-white/10 xl:w-80">
|
9
9
|
<div class="hidden lg:flex">
|
10
10
|
<a aria-label="Home" href="/" class="flex space-x-2 items-center">
|
11
|
-
<% if @config["logo"] %>
|
11
|
+
<% if @config["logo"] && params[:static].blank? %>
|
12
12
|
<%= image_tag(@config["logo"], class: "h-10") %>
|
13
13
|
<% end %>
|
14
14
|
<span class="font-extrabold uppercase text-xl">
|
@@ -73,16 +73,20 @@
|
|
73
73
|
<% end %>
|
74
74
|
</ul>
|
75
75
|
</nav>
|
76
|
-
<div class="
|
77
|
-
<div class="
|
76
|
+
<div class="md:block md:h-5 md:w-px md:bg-zinc-900/10 md:dark:bg-white/15"></div>
|
77
|
+
<div class="flex gap-4">
|
78
|
+
|
78
79
|
<div class="contents lg:hidden">
|
79
80
|
<button type="button" class="flex h-6 w-6 items-center justify-center rounded-md transition hover:bg-zinc-900/5 dark:hover:bg-white/5 lg:hidden focus:[&:not(:focus-visible)]:outline-none" aria-label="Find something...">
|
80
81
|
<svg viewBox="0 0 20 20" fill="none" aria-hidden="true" class="h-5 w-5 stroke-zinc-900 dark:stroke-white">
|
81
82
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12.01 12a4.25 4.25 0 1 0-6.02-6 4.25 4.25 0 0 0 6.02 6Zm0 0 3.24 3.25"></path>
|
82
83
|
</svg>
|
84
|
+
xxx
|
83
85
|
</button>
|
84
86
|
</div>
|
85
|
-
|
87
|
+
|
88
|
+
<a href="#" data-action="dark-mode#toggleDarkMode"
|
89
|
+
class="flex h-6 w-6 items-center justify-center rounded-md transition hover:bg-zinc-900/5 dark:hover:bg-white/5" aria-label="Toggle dark mode">
|
86
90
|
<svg viewBox="0 0 20 20" fill="none" aria-hidden="true" class="h-5 w-5 stroke-zinc-900 dark:hidden">
|
87
91
|
<path d="M12.5 10a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0Z"></path>
|
88
92
|
<path stroke-linecap="round" d="M10 5.5v-1M13.182 6.818l.707-.707M14.5 10h1M13.182 13.182l.707.707M10 15.5v-1M6.11 13.889l.708-.707M4.5 10h1M6.11 6.111l.708.707"></path>
|
@@ -90,7 +94,8 @@
|
|
90
94
|
<svg viewBox="0 0 20 20" fill="none" aria-hidden="true" class="hidden h-5 w-5 stroke-white dark:block">
|
91
95
|
<path d="M15.224 11.724a5.5 5.5 0 0 1-6.949-6.949 5.5 5.5 0 1 0 6.949 6.949Z"></path>
|
92
96
|
</svg>
|
93
|
-
</
|
97
|
+
</a>
|
98
|
+
|
94
99
|
</div>
|
95
100
|
<!--
|
96
101
|
<div class="hidden min-[416px]:contents">
|
@@ -102,7 +107,7 @@
|
|
102
107
|
|
103
108
|
</div>
|
104
109
|
|
105
|
-
<nav class="hidden lg:mt-10 lg:block">
|
110
|
+
<nav id="docs-menu" class="hidden lg:mt-10 lg:block">
|
106
111
|
<%= render partial: 'menu', locals: { nodes: @docs_structure[:children], level: 1 } %>
|
107
112
|
</nav>
|
108
113
|
|
@@ -111,9 +116,23 @@
|
|
111
116
|
|
112
117
|
<div class="relative px-4 pt-14 sm:px-6 lg:px-8">
|
113
118
|
<main class="py-16">
|
114
|
-
|
115
|
-
|
116
|
-
|
119
|
+
|
120
|
+
<%= turbo_frame_tag "doc-frame" do %>
|
121
|
+
<article class="prose dark:prose-invert" data-controller="highlight">
|
122
|
+
<%= @content.html_safe unless @content.nil? %>
|
123
|
+
</article>
|
124
|
+
<% end %>
|
125
|
+
|
126
|
+
<% if params[:file_path].present? && Rails.env.development? %>
|
127
|
+
<div class="flex justify-start">
|
128
|
+
<%= link_to edit_doc_path(params[:file_path]), "data-turbo-frame": "doc-frame", class: "rounded-link flex space-x-2 items-center" do %>
|
129
|
+
<span>Edit</span>
|
130
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
131
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
|
132
|
+
</svg>
|
133
|
+
<% end %>
|
134
|
+
</div>
|
135
|
+
<% end %>
|
117
136
|
</main>
|
118
137
|
|
119
138
|
|