collavre 0.20.3 β 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/collavre/actiontext.css +92 -2
- data/app/assets/stylesheets/collavre/code_highlight.css +144 -26
- data/app/assets/stylesheets/collavre/comments_popup.css +133 -2
- data/app/assets/stylesheets/collavre/landing.css +507 -0
- data/app/assets/stylesheets/collavre/popup.css +148 -0
- data/app/channels/collavre/agent_channel.rb +205 -0
- data/app/channels/collavre/comments_presence_channel.rb +7 -0
- data/app/controllers/collavre/admin/integrations_controller.rb +93 -0
- data/app/controllers/collavre/admin/settings_controller.rb +22 -17
- data/app/controllers/collavre/api/v1/agents_controller.rb +777 -0
- data/app/controllers/collavre/api/v1/base_controller.rb +46 -0
- data/app/controllers/collavre/application_controller.rb +27 -0
- data/app/controllers/collavre/attachments_controller.rb +30 -2
- data/app/controllers/collavre/channels_controller.rb +23 -0
- data/app/controllers/collavre/comments_controller.rb +1 -1
- data/app/controllers/collavre/creatives/attachments_controller.rb +79 -0
- data/app/controllers/collavre/creatives_controller.rb +141 -7
- data/app/controllers/collavre/landing_controller.rb +8 -0
- data/app/controllers/collavre/public_assets_controller.rb +24 -0
- data/app/controllers/collavre/tasks_controller.rb +12 -4
- data/app/controllers/collavre/topics_controller.rb +36 -30
- data/app/controllers/concerns/collavre/comments/approval_actions.rb +57 -14
- data/app/helpers/collavre/comments_helper.rb +7 -0
- data/app/helpers/collavre/public_assets_helper.rb +14 -0
- data/app/javascript/components/InlineLexicalEditor.jsx +42 -59
- data/app/javascript/components/plugins/attachment_cleanup_plugin.jsx +3 -0
- data/app/javascript/components/plugins/image_upload_plugin.jsx +12 -0
- data/app/javascript/controllers/__tests__/link_creative_controller.test.js +447 -0
- data/app/javascript/controllers/comment_controller.js +15 -1
- data/app/javascript/controllers/comments/__tests__/presence_controller.test.js +108 -0
- data/app/javascript/controllers/comments/form_controller.js +4 -0
- data/app/javascript/controllers/comments/list_controller.js +27 -9
- data/app/javascript/controllers/comments/popup_controller.js +9 -0
- data/app/javascript/controllers/comments/presence_controller.js +137 -4
- data/app/javascript/controllers/comments/topics_controller.js +15 -0
- data/app/javascript/controllers/creatives/__tests__/sync_controller.test.js +89 -0
- data/app/javascript/controllers/creatives/__tests__/tree_controller.test.js +120 -0
- data/app/javascript/controllers/creatives/sync_controller.js +30 -9
- data/app/javascript/controllers/creatives/tree_controller.js +23 -0
- data/app/javascript/controllers/index.js +4 -1
- data/app/javascript/controllers/landing_video_controller.js +53 -0
- data/app/javascript/controllers/link_creative_controller.js +451 -29
- data/app/javascript/creatives/tree_renderer.js +6 -0
- data/app/javascript/lib/api/__tests__/queue_manager.test.js +27 -0
- data/app/javascript/lib/api/creatives.js +13 -0
- data/app/javascript/lib/api/queue_manager.js +17 -5
- data/app/javascript/lib/lexical/__tests__/color_import.test.js +318 -0
- data/app/javascript/lib/lexical/__tests__/minimize_html.test.js +259 -0
- data/app/javascript/lib/lexical/color_import.js +186 -0
- data/app/javascript/lib/lexical/minimize_html.js +182 -0
- data/app/javascript/lib/lexical/video_node.jsx +96 -0
- data/app/javascript/modules/__tests__/command_args_form.test.js +103 -0
- data/app/javascript/modules/__tests__/html_content_empty.test.js +41 -0
- data/app/javascript/modules/__tests__/markdown_source_reconcile.test.js +70 -0
- data/app/javascript/modules/command_args_form.js +22 -4
- data/app/javascript/modules/command_menu.js +27 -0
- data/app/javascript/modules/creative_row_editor.js +227 -17
- data/app/javascript/modules/html_content_empty.js +12 -0
- data/app/javascript/modules/markdown_source_reconcile.js +53 -0
- data/app/jobs/collavre/ai_agent_job.rb +89 -3
- data/app/jobs/collavre/cancel_offline_delegated_tasks_job.rb +134 -0
- data/app/jobs/collavre/claude_channel_presence_job.rb +91 -0
- data/app/jobs/collavre/drop_trigger_job.rb +37 -8
- data/app/mailers/collavre/application_mailer.rb +1 -1
- data/app/models/collavre/agent_subscription.rb +52 -0
- data/app/models/collavre/channel/injected_message.rb +5 -0
- data/app/models/collavre/channel.rb +87 -0
- data/app/models/collavre/comment/claude_channel_permission.rb +145 -0
- data/app/models/collavre/comment.rb +70 -5
- data/app/models/collavre/creative/describable.rb +202 -3
- data/app/models/collavre/creative.rb +2 -0
- data/app/models/collavre/creative_share.rb +1 -0
- data/app/models/collavre/integration_setting.rb +35 -0
- data/app/models/collavre/preview_channel.rb +93 -0
- data/app/models/collavre/system_setting.rb +13 -2
- data/app/models/collavre/task.rb +34 -5
- data/app/models/collavre/topic.rb +8 -25
- data/app/models/collavre/user.rb +4 -0
- data/app/models/concerns/collavre/ai_agent_resolvable.rb +12 -3
- data/app/services/collavre/agent_session_abort.rb +28 -0
- data/app/services/collavre/ai_agent/claude_channel_adapter.rb +79 -0
- data/app/services/collavre/ai_agent/response_finalizer.rb +4 -2
- data/app/services/collavre/ai_agent_service.rb +68 -49
- data/app/services/collavre/ai_client.rb +3 -3
- data/app/services/collavre/attachment_backfill.rb +26 -0
- data/app/services/collavre/channel_attacher.rb +58 -0
- data/app/services/collavre/comments/mcp_command.rb +31 -1
- data/app/services/collavre/creatives/breadcrumb_resolver.rb +91 -0
- data/app/services/collavre/creatives/filter_pipeline.rb +26 -42
- data/app/services/collavre/creatives/filters/search_filter.rb +12 -2
- data/app/services/collavre/creatives/index_query.rb +110 -8
- data/app/services/collavre/creatives/permission_filter.rb +50 -0
- data/app/services/collavre/creatives/reveal_path_resolver.rb +118 -0
- data/app/services/collavre/creatives/tree_builder.rb +7 -3
- data/app/services/collavre/crons/recurring_task_arguments.rb +28 -0
- data/app/services/collavre/google_calendar_service.rb +4 -2
- data/app/services/collavre/markdown_converter.rb +130 -15
- data/app/services/collavre/markdown_importer.rb +7 -2
- data/app/services/collavre/orchestration/policy_resolver.rb +11 -1
- data/app/services/collavre/orchestration/stuck_detector.rb +22 -2
- data/app/services/collavre/tools/creative_attach_files_service.rb +62 -0
- data/app/services/collavre/tools/creative_list_attachments_service.rb +42 -0
- data/app/services/collavre/tools/creative_remove_attachment_service.rb +37 -0
- data/app/services/collavre/tools/cron_list_service.rb +1 -14
- data/app/services/collavre/tools/permission_denied_error.rb +9 -0
- data/app/services/collavre/tools/preview_attach_service.rb +128 -0
- data/app/services/collavre/tools/preview_detach_service.rb +61 -0
- data/app/services/collavre/tools/topic_authorizer.rb +24 -0
- data/app/services/collavre/topic_branch_service.rb +34 -26
- data/app/services/collavre/topics/orphaned_cron_notifier.rb +68 -0
- data/app/views/admin/shared/_tabs.html.erb +1 -0
- data/app/views/collavre/admin/integrations/_category.html.erb +22 -0
- data/app/views/collavre/admin/integrations/_setting_row.html.erb +70 -0
- data/app/views/collavre/admin/integrations/index.html.erb +42 -0
- data/app/views/collavre/admin/settings/_system_tab.html.erb +8 -0
- data/app/views/collavre/comments/_channel_chips.html.erb +33 -0
- data/app/views/collavre/comments/_comment.html.erb +16 -2
- data/app/views/collavre/comments/_comments_popup.html.erb +4 -1
- data/app/views/collavre/creatives/_inline_edit_form.html.erb +19 -0
- data/app/views/collavre/creatives/index.html.erb +10 -2
- data/app/views/collavre/landing/show.html.erb +130 -0
- data/app/views/collavre/shared/_link_creative_modal.html.erb +6 -2
- data/app/views/layouts/collavre/landing.html.erb +33 -0
- data/config/locales/admin.en.yml +4 -2
- data/config/locales/admin.ko.yml +4 -2
- data/config/locales/channels.en.yml +13 -0
- data/config/locales/channels.ko.yml +13 -0
- data/config/locales/claude_channel.en.yml +16 -0
- data/config/locales/claude_channel.ko.yml +16 -0
- data/config/locales/comments.en.yml +5 -0
- data/config/locales/comments.ko.yml +5 -0
- data/config/locales/creatives.en.yml +11 -0
- data/config/locales/creatives.ko.yml +10 -0
- data/config/locales/integrations.en.yml +55 -0
- data/config/locales/integrations.ko.yml +55 -0
- data/config/locales/landing.en.yml +51 -0
- data/config/locales/landing.ko.yml +51 -0
- data/config/routes.rb +30 -0
- data/db/migrate/20260526000000_create_channels.rb +42 -0
- data/db/migrate/20260527000000_add_dismissed_at_to_channels.rb +6 -0
- data/db/migrate/20260527000100_backfill_dismissed_at_for_legacy_detached_channels.rb +28 -0
- data/db/migrate/20260528000000_add_preview_channel_unique_index.rb +31 -0
- data/db/migrate/20260529000000_add_primary_agent_id_to_topics.rb +40 -0
- data/db/migrate/20260529100000_create_integration_settings.rb +15 -0
- data/db/migrate/20260609000000_drop_action_text_rich_texts.rb +20 -0
- data/db/migrate/20260609005000_add_session_id_to_topics.rb +16 -0
- data/db/migrate/20260609010000_create_agent_subscriptions.rb +19 -0
- data/db/migrate/20260609020000_add_last_seen_at_to_agent_subscriptions.rb +23 -0
- data/db/migrate/20260609030000_add_session_id_to_agent_subscriptions.rb +17 -0
- data/db/migrate/20260609190659_backfill_creative_files_into_description.rb +24 -0
- data/db/seeds.rb +19 -0
- data/lib/collavre/aws_credentials.rb +75 -0
- data/lib/collavre/engine.rb +50 -0
- data/lib/collavre/integration_settings/key_definition.rb +35 -0
- data/lib/collavre/integration_settings/registry.rb +60 -0
- data/lib/collavre/integration_settings/resolver.rb +71 -0
- data/lib/collavre/integration_settings.rb +46 -0
- data/lib/collavre/ses_settings_interceptor.rb +72 -0
- data/lib/collavre/version.rb +1 -1
- data/lib/collavre.rb +3 -0
- metadata +82 -2
- data/app/services/collavre/openclaw_abort_service.rb +0 -45
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<h1 class="no-top-margin"><%= t("collavre.admin.integrations.title") %></h1>
|
|
2
|
+
|
|
3
|
+
<%= render "admin/shared/tabs" %>
|
|
4
|
+
|
|
5
|
+
<div class="tab-panels">
|
|
6
|
+
<section class="tab-panel active">
|
|
7
|
+
<%= tag.div(flash[:alert], class: "flash-alert") if flash[:alert] %>
|
|
8
|
+
<%= tag.div(flash[:warning], class: "flash-warning") if flash[:warning] %>
|
|
9
|
+
<%= tag.div(flash[:notice], class: "flash-notice") if flash[:notice] %>
|
|
10
|
+
|
|
11
|
+
<p style="color: var(--color-muted); margin-bottom: 1.5em;">
|
|
12
|
+
<%= t("collavre.admin.integrations.subtitle") %>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<% if @grouped_settings.empty? %>
|
|
16
|
+
<p class="empty-state" style="padding: 2em; text-align: center; color: var(--color-muted);">
|
|
17
|
+
<%= t("collavre.admin.integrations.empty_state") %>
|
|
18
|
+
</p>
|
|
19
|
+
<% else %>
|
|
20
|
+
<%# Bulk-save form is an empty container. Row inputs reference it via the HTML5
|
|
21
|
+
`form` attribute; per-row Reset/Seed `button_to` forms sit as siblings,
|
|
22
|
+
so we never nest <form> inside <form>. %>
|
|
23
|
+
<%= form_with url: collavre.bulk_update_admin_integrations_path,
|
|
24
|
+
method: :patch,
|
|
25
|
+
local: true,
|
|
26
|
+
id: "integrations-bulk-form",
|
|
27
|
+
html: { id: "integrations-bulk-form", class: "profile-form" } do %>
|
|
28
|
+
<% end %>
|
|
29
|
+
|
|
30
|
+
<% @grouped_settings.each do |category, rows| %>
|
|
31
|
+
<%= render partial: "category", locals: { category: category, rows: rows, bulk_form_id: "integrations-bulk-form" } %>
|
|
32
|
+
<% end %>
|
|
33
|
+
|
|
34
|
+
<div style="margin-top: 2em;">
|
|
35
|
+
<%= button_tag t("collavre.admin.integrations.actions.save"),
|
|
36
|
+
type: :submit,
|
|
37
|
+
form: "integrations-bulk-form",
|
|
38
|
+
class: "btn btn-primary" %>
|
|
39
|
+
</div>
|
|
40
|
+
<% end %>
|
|
41
|
+
</section>
|
|
42
|
+
</div>
|
|
@@ -38,6 +38,14 @@
|
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
40
|
|
|
41
|
+
<div style="margin-top: 1.5em;">
|
|
42
|
+
<%= f.label :home_page_path_authenticated, t('admin.settings.home_page_path_authenticated') %>
|
|
43
|
+
<%= f.text_field :home_page_path_authenticated, value: @home_page_path_authenticated, placeholder: "/creatives" %>
|
|
44
|
+
<div class="help-text" style="font-size: 0.85em; color: var(--color-text-muted); margin-top: 0.25em;">
|
|
45
|
+
<%= t('admin.settings.home_page_path_authenticated_hint') %>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
41
49
|
<div style="margin-top: 2em; border-top: 1px solid var(--color-border); padding-top: 1.5em;">
|
|
42
50
|
<h3 style="font-size: 1.1em; margin-bottom: 1em;"><%= t('admin.settings.account_lockout') %></h3>
|
|
43
51
|
<div style="display: flex; gap: 2em; flex-wrap: wrap;">
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<%# locals: { topic: Collavre::Topic } %>
|
|
2
|
+
<div class="channel-chips" data-comments--presence-target="channelChips" data-topic-id="<%= topic.id %>">
|
|
3
|
+
<% topic.channels.not_dismissed.each do |channel| %>
|
|
4
|
+
<%# Chip is kept after detach so the final closed/stopped badge stays
|
|
5
|
+
visible until the user dismisses it with the X button. Subclasses
|
|
6
|
+
drive the colored badge via badge_state / badge_title; returning nil
|
|
7
|
+
from badge_state hides the badge entirely. %>
|
|
8
|
+
<% badge_state = channel.badge_state %>
|
|
9
|
+
<% badge_title = channel.badge_title %>
|
|
10
|
+
<% chip_classes = [ "channel-chip" ]
|
|
11
|
+
chip_classes << "channel-chip--detached" if channel.detached? %>
|
|
12
|
+
<% chip_label = channel.latest_label.presence || channel.default_label.presence || channel.class.name.demodulize %>
|
|
13
|
+
<% chip_link = channel.latest_link.presence || channel.default_link.presence %>
|
|
14
|
+
<span class="<%= chip_classes.join(' ') %>" data-channel-id="<%= channel.id %>">
|
|
15
|
+
<% if badge_state %>
|
|
16
|
+
<span class="channel-chip-badge channel-chip-badge--<%= badge_state %>"
|
|
17
|
+
title="<%= badge_title %>"
|
|
18
|
+
aria-label="<%= badge_title %>"></span>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% if chip_link %>
|
|
21
|
+
<a href="<%= chip_link %>" target="_blank" rel="noopener">
|
|
22
|
+
<%= chip_label %>
|
|
23
|
+
</a>
|
|
24
|
+
<% else %>
|
|
25
|
+
<%= chip_label %>
|
|
26
|
+
<% end %>
|
|
27
|
+
<button type="button"
|
|
28
|
+
data-action="comments--presence#detachChannel"
|
|
29
|
+
data-channel-id="<%= channel.id %>"
|
|
30
|
+
aria-label="<%= t('collavre.channels.detach', default: 'Detach') %>">×</button>
|
|
31
|
+
</span>
|
|
32
|
+
<% end %>
|
|
33
|
+
</div>
|
|
@@ -36,7 +36,11 @@
|
|
|
36
36
|
<span class="comment-status-label private-label">π <%= t('collavre.comments.private') %></span>
|
|
37
37
|
<% end %>
|
|
38
38
|
<% if comment.action_executed_at.present? %>
|
|
39
|
-
|
|
39
|
+
<% if comment.claude_channel_permission_denied? %>
|
|
40
|
+
<span class="comment-status-label denied-label">π« <%= t('collavre.comments.denied_label') %></span>
|
|
41
|
+
<% else %>
|
|
42
|
+
<span class="comment-status-label approved-label">β
<%= t('collavre.comments.approved_label') %></span>
|
|
43
|
+
<% end %>
|
|
40
44
|
<% end %>
|
|
41
45
|
<% can_convert_comment = comment.user == Current.user || comment.creative.has_permission?(Current.user, :admin) %>
|
|
42
46
|
</div>
|
|
@@ -57,6 +61,11 @@
|
|
|
57
61
|
<button class="approve-comment-btn comment-approve-hidden" data-comment-target="approveButton" data-comment-id="<%= comment.id %>" title="<%= t('collavre.comments.approve_button') %>">
|
|
58
62
|
<%= t('collavre.comments.approve_button') %>
|
|
59
63
|
</button>
|
|
64
|
+
<% if comment.claude_channel_permission? %>
|
|
65
|
+
<button class="deny-comment-btn comment-approve-hidden" data-comment-target="denyButton" data-comment-id="<%= comment.id %>" title="<%= t('collavre.comments.deny_button') %>">
|
|
66
|
+
<%= t('collavre.comments.deny_button') %>
|
|
67
|
+
</button>
|
|
68
|
+
<% end %>
|
|
60
69
|
<% end %>
|
|
61
70
|
<button class="edit-comment-btn comment-owner-only" data-comment-target="ownerButton" data-comment-id="<%= comment.id %>" data-comment-content="<%= comment.content %>" data-comment-private="<%= comment.private? %>" title="<%= t('collavre.comments.update_comment') %>">
|
|
62
71
|
<%= t('collavre.comments.edit_button') %>
|
|
@@ -164,7 +173,12 @@
|
|
|
164
173
|
<details class="comment-action-details">
|
|
165
174
|
<summary class="comment-action-summary"><%= t("collavre.comments.action_summary") %></summary>
|
|
166
175
|
<div class="comment-action-body">
|
|
167
|
-
|
|
176
|
+
<% action_md = comment_action_markdown(comment) %>
|
|
177
|
+
<% if action_md && !has_pending_action %>
|
|
178
|
+
<div class="comment-content comment-action-markdown"><%= action_md %></div>
|
|
179
|
+
<% else %>
|
|
180
|
+
<pre class="comment-action-json" data-comment-action-json><%= formatted_comment_action(comment) %></pre>
|
|
181
|
+
<% end %>
|
|
168
182
|
<% if has_pending_action %>
|
|
169
183
|
<div class="comment-action-approve-controls comment-approve-hidden" data-comment-target="actionApproveControls">
|
|
170
184
|
<button class="edit-comment-action-btn" type="button" data-comment-id="<%= comment.id %>"><%= t("collavre.comments.edit_action_button") %></button>
|
|
@@ -120,7 +120,10 @@
|
|
|
120
120
|
<div id="comments-list" data-comments--popup-target="list" data-comments--list-target="list"><%= t('app.loading') %></div>
|
|
121
121
|
<div id="typing-indicator-row">
|
|
122
122
|
<button type="button" id="scroll-prev-msg-btn" class="scroll-prev-msg-btn" data-action="click->comments--list#scrollToPreviousMessage" title="<%= t('collavre.comments.scroll_to_prev', default: 'Previous message') %>" aria-label="<%= t('collavre.comments.scroll_to_prev', default: 'Previous message') %>">⌃</button>
|
|
123
|
-
<div id="typing-
|
|
123
|
+
<div id="typing-scroll-viewport" data-comments--presence-target="scrollRow">
|
|
124
|
+
<div id="channel-chips-container" data-comments--presence-target="channelChips"></div>
|
|
125
|
+
<div id="typing-indicator" data-comments--presence-target="typingIndicator" data-comments--popup-target="typingIndicator" data-stop-agent-text="<%= t('collavre.comments.stop_agent') %>"></div>
|
|
126
|
+
</div>
|
|
124
127
|
</div>
|
|
125
128
|
<form id="new-comment-form" data-comments--popup-target="form" data-comments--form-target="form" style="display:none;">
|
|
126
129
|
<input type="hidden" name="comment[quoted_comment_id]" data-comments--form-target="quotedCommentId" value="" />
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
<input type="hidden" id="inline-method" name="_method" value="patch" />
|
|
4
4
|
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
|
5
5
|
<input type="hidden" id="inline-creative-description" name="creative[description]" />
|
|
6
|
+
<input type="hidden" id="inline-content-type" name="creative[content_type_input]" value="html" />
|
|
7
|
+
<input type="hidden" id="inline-markdown-source" name="creative[markdown_source]" />
|
|
6
8
|
<input type="hidden" id="inline-parent-id" name="creative[parent_id]" />
|
|
7
9
|
<input type="hidden" id="inline-before-id" name="before_id" />
|
|
8
10
|
<input type="hidden" id="inline-after-id" name="after_id" />
|
|
@@ -14,6 +16,14 @@
|
|
|
14
16
|
data-direct-upload-url="<%= main_app.rails_direct_uploads_path %>"
|
|
15
17
|
data-blob-url-template="<%= main_app.rails_service_blob_path(':signed_id', ':filename') %>"
|
|
16
18
|
data-placeholder="<%= t('collavre.creatives.inline_editor.placeholder') %>"></div>
|
|
19
|
+
<div id="markdown-editor-wrapper" class="markdown-editor-wrapper" style="display:none;">
|
|
20
|
+
<textarea id="markdown-editor-textarea"
|
|
21
|
+
class="markdown-editor-textarea"
|
|
22
|
+
rows="10"
|
|
23
|
+
placeholder="<%= t('collavre.creatives.inline_editor.markdown_placeholder') %>"></textarea>
|
|
24
|
+
<div id="markdown-preview" class="markdown-preview"
|
|
25
|
+
data-placeholder="<%= t('collavre.creatives.inline_editor.markdown_preview_placeholder') %>"></div>
|
|
26
|
+
</div>
|
|
17
27
|
<div id="actions-inline-editor" style="padding: 0px 8px;">
|
|
18
28
|
<div style="margin-top:0.5em;display:flex;align-items:center;gap:0.5em;">
|
|
19
29
|
<input type="hidden" name="creative[progress]" value="0">
|
|
@@ -30,6 +40,15 @@
|
|
|
30
40
|
<button type="button" id="inline-metadata-btn" class="creative-action-btn" title="<%= t('collavre.creatives.index.metadata_tooltip') %>" style="margin-left:0.5em;font-family:monospace;font-size:0.9em;">
|
|
31
41
|
{ }
|
|
32
42
|
</button>
|
|
43
|
+
<button type="button" id="inline-toggle-markdown" class="creative-action-btn"
|
|
44
|
+
title="<%= t('collavre.creatives.index.toggle_markdown') %>"
|
|
45
|
+
data-label-markdown="<%= t('collavre.creatives.index.toggle_markdown') %>"
|
|
46
|
+
data-label-richtext="<%= t('collavre.creatives.index.toggle_richtext') %>"
|
|
47
|
+
data-confirm-to-richtext="<%= t('collavre.creatives.index.markdown_to_richtext_confirm') %>"
|
|
48
|
+
data-confirm-to-markdown="<%= t('collavre.creatives.index.richtext_to_markdown_confirm') %>"
|
|
49
|
+
style="margin-left:0.5em;font-family:monospace;font-size:0.9em;">
|
|
50
|
+
<%= t('collavre.creatives.index.toggle_markdown') %>
|
|
51
|
+
</button>
|
|
33
52
|
</div>
|
|
34
53
|
<div style="margin-top:0.5em;">
|
|
35
54
|
<button type="button" id="inline-move-up" class="creative-action-btn" title="<%= t('collavre.creatives.index.inline_move_up_tooltip') %>">
|
|
@@ -154,17 +154,25 @@
|
|
|
154
154
|
title_row_content += content_tag(:template, data: { part: "edit-icon" }) { svg_tag("edit.svg", class: "icon-edit") }
|
|
155
155
|
title_row_content += content_tag(:template, data: { part: "edit-off-icon" }) { svg_tag("edit-off.svg", class: "icon-edit") }
|
|
156
156
|
%>
|
|
157
|
+
<%
|
|
158
|
+
title_can_write = @parent_creative.has_permission?(Current.user, :write)
|
|
159
|
+
title_effective_origin = @parent_creative.effective_origin(Set.new)
|
|
160
|
+
title_content_type = title_effective_origin.data&.dig("content_type")
|
|
161
|
+
title_markdown_source = title_can_write ? title_effective_origin.data&.dig("markdown_source") : nil
|
|
162
|
+
%>
|
|
157
163
|
<%= content_tag(
|
|
158
164
|
"creative-tree-row",
|
|
159
165
|
title_row_content,
|
|
160
166
|
"dom-id": "creative-markdown-block",
|
|
161
167
|
"creative-id": @parent_creative.id,
|
|
162
168
|
"parent-id": @parent_creative.parent_id,
|
|
163
|
-
"can-write":
|
|
169
|
+
"can-write": title_can_write ? "true" : "false",
|
|
164
170
|
"is-title": "",
|
|
165
171
|
"data-description-raw-html": @parent_creative.description,
|
|
166
172
|
"data-progress-value": @parent_creative.progress,
|
|
167
|
-
"data-origin-id": @parent_creative.origin_id
|
|
173
|
+
"data-origin-id": @parent_creative.origin_id,
|
|
174
|
+
"data-content-type": title_content_type,
|
|
175
|
+
"data-markdown-source": title_markdown_source
|
|
168
176
|
) %>
|
|
169
177
|
<% else %>
|
|
170
178
|
<%= content_tag(
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<%# Landing Page β Collavre %>
|
|
2
|
+
|
|
3
|
+
<div class="landing">
|
|
4
|
+
<%# βββββββββββββββββββββββββββββββββββββββββββ HERO ββββββββββββββββββββββββββββββββββββββββββ %>
|
|
5
|
+
<section class="landing-hero">
|
|
6
|
+
<div class="landing-hero-glow"></div>
|
|
7
|
+
<div class="landing-container">
|
|
8
|
+
<h1 class="landing-hero-title"><%= t('collavre.landing.hero.headline_html') %></h1>
|
|
9
|
+
<p class="landing-hero-sub"><%= t('collavre.landing.hero.subline') %></p>
|
|
10
|
+
<p class="landing-hero-brand"><%= t('app.name') %></p>
|
|
11
|
+
<div class="landing-hero-actions">
|
|
12
|
+
<a href="#problem" class="landing-btn landing-btn-lg"><%= t('collavre.landing.hero.learn_more') %></a>
|
|
13
|
+
<%= link_to t('app.sign_in'), collavre.new_session_path, class: "landing-btn landing-btn-ghost landing-btn-lg" %>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</section>
|
|
17
|
+
|
|
18
|
+
<%# ββββββββββββββββββββββββββββββββββββββ PROBLEM STATEMENT ββββββββββββββββββββββββββββββββββ %>
|
|
19
|
+
<section id="problem" class="landing-section landing-problem">
|
|
20
|
+
<div class="landing-container">
|
|
21
|
+
<h2 class="landing-section-title"><%= t('collavre.landing.problem.title') %></h2>
|
|
22
|
+
<div class="landing-problem-grid">
|
|
23
|
+
<div class="landing-problem-card">
|
|
24
|
+
<span class="landing-problem-icon">π</span>
|
|
25
|
+
<h3><%= t('collavre.landing.problem.notion.title') %></h3>
|
|
26
|
+
<p><%= t('collavre.landing.problem.notion.desc') %></p>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="landing-problem-card">
|
|
29
|
+
<span class="landing-problem-icon">π</span>
|
|
30
|
+
<h3><%= t('collavre.landing.problem.jira.title') %></h3>
|
|
31
|
+
<p><%= t('collavre.landing.problem.jira.desc') %></p>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="landing-problem-card">
|
|
34
|
+
<span class="landing-problem-icon">π¬</span>
|
|
35
|
+
<h3><%= t('collavre.landing.problem.slack.title') %></h3>
|
|
36
|
+
<p><%= t('collavre.landing.problem.slack.desc') %></p>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</section>
|
|
41
|
+
|
|
42
|
+
<%# βββββββββββββββββββββββββββββββββββββββ FEATURES βββββββββββββββββββββββββββββββββββββββββ %>
|
|
43
|
+
<section id="features" class="landing-section landing-features">
|
|
44
|
+
<div class="landing-container">
|
|
45
|
+
<h2 class="landing-section-title"><%= t('collavre.landing.features.title') %></h2>
|
|
46
|
+
<p class="landing-section-sub"><%= t('collavre.landing.features.subtitle') %></p>
|
|
47
|
+
|
|
48
|
+
<div class="landing-features-grid">
|
|
49
|
+
<div class="landing-feature-card">
|
|
50
|
+
<div class="landing-feature-icon">π³</div>
|
|
51
|
+
<h3><%= t('collavre.landing.features.tree.title') %></h3>
|
|
52
|
+
<p><%= t('collavre.landing.features.tree.desc') %></p>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="landing-feature-card">
|
|
56
|
+
<div class="landing-feature-icon">π€</div>
|
|
57
|
+
<h3><%= t('collavre.landing.features.ai.title') %></h3>
|
|
58
|
+
<p><%= t('collavre.landing.features.ai.desc') %></p>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div class="landing-feature-card">
|
|
62
|
+
<div class="landing-feature-icon">π‘</div>
|
|
63
|
+
<h3><%= t('collavre.landing.features.context.title') %></h3>
|
|
64
|
+
<p><%= t('collavre.landing.features.context.desc') %></p>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div class="landing-feature-card">
|
|
68
|
+
<div class="landing-feature-icon">π¬</div>
|
|
69
|
+
<h3><%= t('collavre.landing.features.chat.title') %></h3>
|
|
70
|
+
<p><%= t('collavre.landing.features.chat.desc') %></p>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</section>
|
|
77
|
+
|
|
78
|
+
<%# ββββββββββββββββββββββββββββββββββββββββββ DEMO ββββββββββββββββββββββββββββββββββββββββββ %>
|
|
79
|
+
<section id="demo" class="landing-section landing-demo">
|
|
80
|
+
<div class="landing-container">
|
|
81
|
+
<h2 class="landing-section-title"><%= t('collavre.landing.demo.title') %></h2>
|
|
82
|
+
<%# Light mode video %>
|
|
83
|
+
<div class="landing-demo-frame landing-demo-light" data-controller="landing-video">
|
|
84
|
+
<video class="landing-demo-video"
|
|
85
|
+
data-landing-video-target="video"
|
|
86
|
+
autoplay muted loop playsinline
|
|
87
|
+
poster="/public-assets/blobs/eyJfcmFpbHMiOnsiZGF0YSI6NDEyLCJwdXIiOiJibG9iX2lkIn19--33811afcd451cef0cf10313fa1bfecca15b41299/demo-poster.jpg">
|
|
88
|
+
<source src="/public-assets/blobs/eyJfcmFpbHMiOnsiZGF0YSI6NDEwLCJwdXIiOiJibG9iX2lkIn19--c272341a19ed8e847208c52da0617ebc801e2e67/demo.mp4" type="video/mp4">
|
|
89
|
+
</video>
|
|
90
|
+
<div class="landing-demo-progress" data-landing-video-target="progressBar">
|
|
91
|
+
<div class="landing-demo-progress-fill" data-landing-video-target="progressFill"></div>
|
|
92
|
+
</div>
|
|
93
|
+
<button class="landing-demo-toggle" data-landing-video-target="toggle" data-action="click->landing-video#togglePlay">
|
|
94
|
+
<span class="landing-demo-toggle-icon" data-landing-video-target="icon">ββ</span>
|
|
95
|
+
</button>
|
|
96
|
+
</div>
|
|
97
|
+
<%# Dark mode video %>
|
|
98
|
+
<div class="landing-demo-frame landing-demo-dark" data-controller="landing-video">
|
|
99
|
+
<video class="landing-demo-video"
|
|
100
|
+
data-landing-video-target="video"
|
|
101
|
+
autoplay muted loop playsinline
|
|
102
|
+
poster="/public-assets/blobs/eyJfcmFpbHMiOnsiZGF0YSI6NDEzLCJwdXIiOiJibG9iX2lkIn19--53c3c505596bca0befbbebb5958764a153ffee5e/demo-dark-poster.jpg">
|
|
103
|
+
<source src="/public-assets/blobs/eyJfcmFpbHMiOnsiZGF0YSI6NDExLCJwdXIiOiJibG9iX2lkIn19--758c90c311bb68f46a2bda87553e3cdfd800420b/demo-dark.mp4" type="video/mp4">
|
|
104
|
+
</video>
|
|
105
|
+
<div class="landing-demo-progress" data-landing-video-target="progressBar">
|
|
106
|
+
<div class="landing-demo-progress-fill" data-landing-video-target="progressFill"></div>
|
|
107
|
+
</div>
|
|
108
|
+
<button class="landing-demo-toggle" data-landing-video-target="toggle" data-action="click->landing-video#togglePlay">
|
|
109
|
+
<span class="landing-demo-toggle-icon" data-landing-video-target="icon">ββ</span>
|
|
110
|
+
</button>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</section>
|
|
114
|
+
|
|
115
|
+
<%# βββββββββββββββββββββββββββββββββββββββ FINAL CTA ββββββββββββββββββββββββββββββββββββββββ %>
|
|
116
|
+
<section class="landing-section landing-cta">
|
|
117
|
+
<div class="landing-container">
|
|
118
|
+
<h2 class="landing-cta-title"><%= t('collavre.landing.cta.title') %></h2>
|
|
119
|
+
<p class="landing-cta-sub"><%= t('collavre.landing.cta.subtitle') %></p>
|
|
120
|
+
<%= link_to t('collavre.landing.cta.start'), collavre.new_user_path, class: "landing-btn landing-btn-lg" %>
|
|
121
|
+
</div>
|
|
122
|
+
</section>
|
|
123
|
+
|
|
124
|
+
<%# βββββββββββββββββββββββββββββββββββββββ FOOTER βββββββββββββββββββββββββββββββββββββββββββ %>
|
|
125
|
+
<footer class="landing-footer">
|
|
126
|
+
<div class="landing-container landing-footer-inner">
|
|
127
|
+
<p class="landing-footer-copy">Β© <%= Date.today.year %> <%= t('app.name') %>. <%= t('collavre.landing.footer.rights') %></p>
|
|
128
|
+
</div>
|
|
129
|
+
</footer>
|
|
130
|
+
</div>
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
<div id="link-creative-modal" class="common-popup" style="display:none;" data-controller="link-creative"
|
|
1
|
+
<div id="link-creative-modal" class="common-popup" style="display:none;" data-controller="link-creative"
|
|
2
|
+
data-link-creative-loading-text="<%= t('collavre.creatives.index.link_loading', default: 'Loadingβ¦') %>"
|
|
3
|
+
data-link-creative-no-results-text="<%= t('collavre.creatives.index.no_search_results', default: 'No creatives match your search.') %>"
|
|
4
|
+
data-link-creative-empty-text="<%= t('collavre.creatives.index.no_sub_creatives', default: 'No sub-creatives found.') %>"
|
|
5
|
+
data-link-creative-expand-text="<%= t('collavre.creatives.index.link_expand', default: 'Expand') %>">
|
|
2
6
|
<button type="button" id="close-link-creative-modal" class="popup-close-btn" data-link-creative-target="close">×</button>
|
|
3
7
|
<h3><%= t('collavre.creatives.index.link', default: 'Link') %></h3>
|
|
4
8
|
<input type="text" id="link-creative-search" class="shared-input-surface" style="width:100%;margin-bottom:0.5em;" placeholder="<%= t('collavre.creatives.index.search_placeholder', default: 'Search creative') %>" data-link-creative-target="input">
|
|
5
|
-
<ul id="link-creative-results" class="common-popup-list" data-popup-list data-link-creative-target="list"></ul>
|
|
9
|
+
<ul id="link-creative-results" class="common-popup-list link-creative-list" data-popup-list data-link-creative-target="list"></ul>
|
|
6
10
|
</div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title><%= t('app.name') %> β <%= t('collavre.landing.meta.title') %></title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<meta name="description" content="<%= t('collavre.landing.meta.description') %>">
|
|
7
|
+
<meta property="og:title" content="<%= t('app.name') %> β <%= t('collavre.landing.meta.title') %>">
|
|
8
|
+
<meta property="og:description" content="<%= t('collavre.landing.meta.description') %>">
|
|
9
|
+
<%= csrf_meta_tags %>
|
|
10
|
+
<%= csp_meta_tag %>
|
|
11
|
+
|
|
12
|
+
<link rel="icon" href="/icon-1e3cf549d2.png" type="image/png">
|
|
13
|
+
<link rel="icon" href="/icon-1e3cf549d2.svg" type="image/svg+xml">
|
|
14
|
+
<link rel="apple-touch-icon" href="/icon-1e3cf549d2.png">
|
|
15
|
+
|
|
16
|
+
<%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
|
|
17
|
+
<%= collavre_stylesheets %>
|
|
18
|
+
<%= stylesheet_link_tag "collavre/landing", "data-turbo-track": "reload" %>
|
|
19
|
+
|
|
20
|
+
<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true, type: "module" %>
|
|
21
|
+
|
|
22
|
+
<%# Admin-configured default themes for users without personal theme %>
|
|
23
|
+
<% default_styles = default_theme_styles %>
|
|
24
|
+
<% if default_styles.present? %>
|
|
25
|
+
<style id="default-theme-styles" data-turbo-track="reload"><%= default_styles %></style>
|
|
26
|
+
<% end %>
|
|
27
|
+
</head>
|
|
28
|
+
<body class="<%= body_theme_class %> landing-page">
|
|
29
|
+
<main>
|
|
30
|
+
<%= yield %>
|
|
31
|
+
</main>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
data/config/locales/admin.en.yml
CHANGED
|
@@ -13,8 +13,10 @@ en:
|
|
|
13
13
|
mcp_tool_approval_hint: "Require system administrator approval for new MCP tools."
|
|
14
14
|
creatives_login_required: "Require Login for Creatives"
|
|
15
15
|
creatives_login_required_hint: "If checked, users must be logged in to view /creatives."
|
|
16
|
-
home_page_path: "Home Page Path"
|
|
17
|
-
home_page_path_hint: "Path to render
|
|
16
|
+
home_page_path: "Home Page Path (Unauthenticated)"
|
|
17
|
+
home_page_path_hint: "Path to render for visitors who hit '/' while signed out. The URL stays as '/' but the response shows content from the specified path. Leave empty to use default (/creatives). Examples: /landing, /creatives"
|
|
18
|
+
home_page_path_authenticated: "Home Page Path (Authenticated)"
|
|
19
|
+
home_page_path_authenticated_hint: "Signed-in users who hit '/' are redirected to this path. Unlike the unauthenticated path, the URL actually changes. Leave empty to use default (/creatives). Set to '/' to disable the redirect and fall back to the unauthenticated path above. Examples: /creatives, /dashboard"
|
|
18
20
|
home_page_path_invalid_url: "Home page path cannot be a full URL. Please enter a path like /creatives or /user."
|
|
19
21
|
home_page_path_not_routable: "Home page path '%{path}' is not a valid route. Please enter an existing path."
|
|
20
22
|
home_page_path_not_html: "Home page path '%{path}' does not serve HTML content. Please enter a path to an HTML page."
|
data/config/locales/admin.ko.yml
CHANGED
|
@@ -13,8 +13,10 @@ ko:
|
|
|
13
13
|
mcp_tool_approval_hint: "μ MCP λꡬ λ±λ‘ μ μμ€ν
κ΄λ¦¬μμ μΉμΈμ΄ νμν©λλ€."
|
|
14
14
|
creatives_login_required: "Creatives λ‘κ·ΈμΈ νμ"
|
|
15
15
|
creatives_login_required_hint: "μ²΄ν¬ μ, λ‘κ·ΈμΈμ ν μ¬μ©μλ§ /creatives μ μ κ·Όν μ μμ΅λλ€."
|
|
16
|
-
home_page_path: "ν νμ΄μ§ κ²½λ‘"
|
|
17
|
-
home_page_path_hint: "'/' μ μ μ νμν κ²½λ‘μ
λλ€. URLμ '/'λ‘ μ μ§λλ©° μ§μ λ κ²½λ‘μ μ½ν
μΈ κ° νμλ©λλ€. λΉμλλ©΄ κΈ°λ³Έκ°(/creatives)μ μ¬μ©ν©λλ€. μ: /
|
|
16
|
+
home_page_path: "ν νμ΄μ§ κ²½λ‘ (λΉλ‘κ·ΈμΈ)"
|
|
17
|
+
home_page_path_hint: "λΉλ‘κ·ΈμΈ μ¬μ©μκ° '/' μ μ μ νμν κ²½λ‘μ
λλ€. URLμ '/'λ‘ μ μ§λλ©° μ§μ λ κ²½λ‘μ μ½ν
μΈ κ° νμλ©λλ€. λΉμλλ©΄ κΈ°λ³Έκ°(/creatives)μ μ¬μ©ν©λλ€. μ: /landing, /creatives"
|
|
18
|
+
home_page_path_authenticated: "ν νμ΄μ§ κ²½λ‘ (λ‘κ·ΈμΈ)"
|
|
19
|
+
home_page_path_authenticated_hint: "λ‘κ·ΈμΈ μ¬μ©μκ° '/' μ μ μ μ΄ κ²½λ‘λ‘ λ¦¬λ€μ΄λ νΈλ©λλ€. λΉλ‘κ·ΈμΈ κ²½λ‘μ λ¬λ¦¬ URLμ΄ μ€μ λ‘ λ³κ²½λ©λλ€. λΉμλλ©΄ κΈ°λ³Έκ°(/creatives)μ μ¬μ©ν©λλ€. '/'λ‘ μ€μ νλ©΄ 리λ€μ΄λ νΈνμ§ μκ³ μμ λΉλ‘κ·ΈμΈ κ²½λ‘ μ€μ μ λ°λ¦
λλ€. μ: /creatives, /dashboard"
|
|
18
20
|
home_page_path_invalid_url: "ν νμ΄μ§ κ²½λ‘λ μ 체 URLμ΄ λ μ μμ΅λλ€. /creatives λλ /userμ κ°μ κ²½λ‘λ₯Ό μ
λ ₯νμΈμ."
|
|
19
21
|
home_page_path_not_routable: "ν νμ΄μ§ κ²½λ‘ '%{path}'λ μ ν¨ν λΌμ°νΈκ° μλλλ€. μ‘΄μ¬νλ κ²½λ‘λ₯Ό μ
λ ₯νμΈμ."
|
|
20
22
|
home_page_path_not_html: "ν νμ΄μ§ κ²½λ‘ '%{path}'λ HTML μ½ν
μΈ λ₯Ό μ 곡νμ§ μμ΅λλ€. HTML νμ΄μ§ κ²½λ‘λ₯Ό μ
λ ₯νμΈμ."
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
en:
|
|
2
|
+
collavre:
|
|
3
|
+
channels:
|
|
4
|
+
detach: "Detach"
|
|
5
|
+
channel:
|
|
6
|
+
preview:
|
|
7
|
+
label_default: "Preview"
|
|
8
|
+
attached_message: "%{label} server started.\n\n%{url}"
|
|
9
|
+
badge:
|
|
10
|
+
running: "Running"
|
|
11
|
+
stopped: "Stopped"
|
|
12
|
+
claude_channel:
|
|
13
|
+
disconnected: "π Not connected to Claude Channel β your message will be delivered once it reconnects."
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ko:
|
|
2
|
+
collavre:
|
|
3
|
+
channels:
|
|
4
|
+
detach: "ν΄μ "
|
|
5
|
+
channel:
|
|
6
|
+
preview:
|
|
7
|
+
label_default: "ν리뷰"
|
|
8
|
+
attached_message: "%{label} μλ²κ° μμλμμ΅λλ€.\n\n%{url}"
|
|
9
|
+
badge:
|
|
10
|
+
running: "μ€ν μ€"
|
|
11
|
+
stopped: "μ€μ§λ¨"
|
|
12
|
+
claude_channel:
|
|
13
|
+
disconnected: "π Claude Channelκ³Ό μ°κ²°λμ΄ μμ§ μμ΅λλ€ β λ€μ μ°κ²°λλ©΄ λ©μμ§κ° μ λ¬λ©λλ€."
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
en:
|
|
2
|
+
collavre:
|
|
3
|
+
claude_channel:
|
|
4
|
+
permission:
|
|
5
|
+
message: |
|
|
6
|
+
π **Tool Permission Required**
|
|
7
|
+
|
|
8
|
+
%{description}Claude Code wants to run **%{tool_name}** with the following arguments:
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
%{arguments}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Approve or deny to continue.
|
|
15
|
+
description: "> %{text}\n\n"
|
|
16
|
+
no_arguments: "(no arguments)"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
ko:
|
|
2
|
+
collavre:
|
|
3
|
+
claude_channel:
|
|
4
|
+
permission:
|
|
5
|
+
message: |
|
|
6
|
+
π **λꡬ κΆν μμ²**
|
|
7
|
+
|
|
8
|
+
%{description}Claude Codeκ° λ€μ μΈμλ‘ **%{tool_name}** λꡬλ₯Ό μ€ννλ €κ³ ν©λλ€:
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
%{arguments}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
κ³μνλ €λ©΄ μΉμΈ λλ κ±°λΆλ₯Ό μ ννμΈμ.
|
|
15
|
+
description: "> %{text}\n\n"
|
|
16
|
+
no_arguments: "(μΈμ μμ)"
|
|
@@ -13,6 +13,7 @@ en:
|
|
|
13
13
|
branch_prefix: "Branch"
|
|
14
14
|
main_name: "Main"
|
|
15
15
|
cannot_delete_main: "Cannot delete the Main topic."
|
|
16
|
+
orphaned_cron_notice: "[System] The topic '%{topic_name}' was deleted, but a recurring cron job (%{cron_key}) still targets it and will silently do nothing on each run. Original message: \"%{message}\". Re-point it to another topic or cancel it with cron_cancel."
|
|
16
17
|
create_and_move: 'Create "%{name}" and move'
|
|
17
18
|
move:
|
|
18
19
|
no_target_permission: You don't have write permission on the target creative.
|
|
@@ -46,6 +47,7 @@ en:
|
|
|
46
47
|
copy_link_success: Link copied to clipboard
|
|
47
48
|
copy_link_error: Unable to copy link
|
|
48
49
|
approve_button: Approve
|
|
50
|
+
deny_button: Deny
|
|
49
51
|
approve_not_allowed: Only the assigned approver can approve this comment.
|
|
50
52
|
approve_invalid_format: Invalid action format.
|
|
51
53
|
approve_admin_required: System administrator approval required.
|
|
@@ -63,6 +65,7 @@ en:
|
|
|
63
65
|
approve_invalid_progress: Comment action progress must be a number.
|
|
64
66
|
approve_invalid_description: Comment action description must be text.
|
|
65
67
|
approved_label: Approved
|
|
68
|
+
denied_label: Denied
|
|
66
69
|
action_summary: Action JSON
|
|
67
70
|
edit_action_button: Edit action
|
|
68
71
|
action_update_success: Action updated.
|
|
@@ -211,6 +214,8 @@ en:
|
|
|
211
214
|
delete: Delete
|
|
212
215
|
delete_confirm: Delete this image?
|
|
213
216
|
counter: "%{current} / %{total}"
|
|
217
|
+
channels:
|
|
218
|
+
detach: "Detach"
|
|
214
219
|
calendar_events:
|
|
215
220
|
deleted: Calendar event deleted.
|
|
216
221
|
google_calendar:
|
|
@@ -13,6 +13,7 @@ ko:
|
|
|
13
13
|
branch_prefix: "λΆκΈ°"
|
|
14
14
|
main_name: "λ©μΈ"
|
|
15
15
|
cannot_delete_main: "λ©μΈ ν ν½μ μμ ν μ μμ΅λλ€."
|
|
16
|
+
orphaned_cron_notice: "[μμ€ν
] '%{topic_name}' ν ν½μ΄ μμ λμμ§λ§, μ΄ ν ν½μ λμμΌλ‘ νλ λ°λ³΅ ν¬λ‘ μμ
(%{cron_key})μ΄ μμ§ λ¨μ μμ΄ μ€νλ λλ§λ€ μ무 λμλ νμ§ μκ³ μ‘°μ©ν μ’
λ£λ©λλ€. μλ λ©μμ§: \"%{message}\". λ€λ₯Έ ν ν½μΌλ‘ λ€μ μ§μ νκ±°λ cron_cancelλ‘ μ·¨μνμΈμ."
|
|
16
17
|
create_and_move: '"%{name}" μμ±ν μ΄λ'
|
|
17
18
|
move:
|
|
18
19
|
no_target_permission: λμ ν¬λ¦¬μμ΄ν°λΈμ λν μ°κΈ° κΆνμ΄ μμ΅λλ€.
|
|
@@ -44,6 +45,7 @@ ko:
|
|
|
44
45
|
copy_link_success: λ§ν¬κ° 볡μ¬λμμ΅λλ€
|
|
45
46
|
copy_link_error: λ§ν¬λ₯Ό 볡μ¬ν μ μμ΅λλ€
|
|
46
47
|
approve_button: μΉμΈ
|
|
48
|
+
deny_button: κ±°λΆ
|
|
47
49
|
approve_not_allowed: μ§μ λ μΉμΈμλ§ μ΄ λκΈμ μΉμΈν μ μμ΅λλ€.
|
|
48
50
|
approve_invalid_format: μ ν¨νμ§ μμ μ‘μ
νμμ
λλ€.
|
|
49
51
|
approve_admin_required: μμ€ν
κ΄λ¦¬μ μΉμΈμ΄ νμν©λλ€.
|
|
@@ -61,6 +63,7 @@ ko:
|
|
|
61
63
|
approve_invalid_progress: λκΈ μμ
μ§νλ₯ μ μ«μμ¬μΌ ν©λλ€.
|
|
62
64
|
approve_invalid_description: λκΈ μμ
μ€λͺ
μ ν
μ€νΈμ¬μΌ ν©λλ€.
|
|
63
65
|
approved_label: μΉμΈλ¨
|
|
66
|
+
denied_label: κ±°λΆλ¨
|
|
64
67
|
action_summary: Action JSON
|
|
65
68
|
edit_action_button: Action μμ
|
|
66
69
|
action_update_success: Action μ΄ μ
λ°μ΄νΈλμμ΅λλ€.
|
|
@@ -208,6 +211,8 @@ ko:
|
|
|
208
211
|
delete: μμ
|
|
209
212
|
delete_confirm: μ΄ μ΄λ―Έμ§λ₯Ό μμ νμκ² μ΅λκΉ?
|
|
210
213
|
counter: "%{current} / %{total}"
|
|
214
|
+
channels:
|
|
215
|
+
detach: "ν΄μ "
|
|
211
216
|
calendar_events:
|
|
212
217
|
deleted: μΊλ¦°λ μ΄λ²€νΈκ° μμ λμμ΅λλ€.
|
|
213
218
|
google_calendar:
|
|
@@ -44,6 +44,8 @@ en:
|
|
|
44
44
|
no_creatives: No creatives found.
|
|
45
45
|
no_sub_creatives: No sub-creatives found.
|
|
46
46
|
no_search_results: No creatives match your search.
|
|
47
|
+
link_loading: Loadingβ¦
|
|
48
|
+
link_expand: Expand
|
|
47
49
|
search_placeholder: Search creatives...
|
|
48
50
|
recommend_parent: Recommend Category
|
|
49
51
|
import_uploading: Uploading...
|
|
@@ -132,6 +134,12 @@ en:
|
|
|
132
134
|
metadata_tooltip: Edit metadata
|
|
133
135
|
metadata_title: Metadata
|
|
134
136
|
metadata_save: Save
|
|
137
|
+
toggle_markdown: Markdown
|
|
138
|
+
toggle_richtext: Rich Text
|
|
139
|
+
markdown_to_richtext_confirm: Switching to Rich Text will discard the Markdown
|
|
140
|
+
source. Continue?
|
|
141
|
+
richtext_to_markdown_confirm: Switching to Markdown will discard the current
|
|
142
|
+
rich text content. Continue?
|
|
135
143
|
share:
|
|
136
144
|
shared: Creative shared successfully.
|
|
137
145
|
permission_updated: Permission updated successfully.
|
|
@@ -147,8 +155,11 @@ en:
|
|
|
147
155
|
progress_recalculated: All parent progress recalculated.
|
|
148
156
|
errors:
|
|
149
157
|
no_permission: You do not have permission to perform this action.
|
|
158
|
+
metadata_must_be_object: Metadata must be an object.
|
|
150
159
|
inline_editor:
|
|
151
160
|
placeholder: Describe the creativeβ¦
|
|
161
|
+
markdown_placeholder: Write in Markdownβ¦
|
|
162
|
+
markdown_preview_placeholder: Preview
|
|
152
163
|
edit_title: Edit creative
|
|
153
164
|
edit:
|
|
154
165
|
inline_editor_only_html: Editing creatives now happens directly in the inline
|
|
@@ -40,6 +40,8 @@ ko:
|
|
|
40
40
|
no_creatives: ν¬λ¦¬μμ΄ν°λΈκ° μμ΅λλ€.
|
|
41
41
|
no_sub_creatives: νμ ν¬λ¦¬μμ΄ν°λΈκ° μμ΅λλ€.
|
|
42
42
|
no_search_results: κ²μ κ²°κ³Όκ° μμ΅λλ€.
|
|
43
|
+
link_loading: λΆλ¬μ€λ μ€β¦
|
|
44
|
+
link_expand: νΌμΉκΈ°
|
|
43
45
|
recommend_parent: μΉ΄ν
κ³ λ¦¬ μΆμ²
|
|
44
46
|
import_uploading: μ
λ‘λ μ€...
|
|
45
47
|
import_success: κ°μ Έμ€κΈ° μ±κ³΅! μλ‘κ³ μΉ¨ μ€...
|
|
@@ -120,6 +122,11 @@ ko:
|
|
|
120
122
|
metadata_tooltip: λ©νλ°μ΄ν° νΈμ§
|
|
121
123
|
metadata_title: λ©νλ°μ΄ν°
|
|
122
124
|
metadata_save: μ μ₯
|
|
125
|
+
toggle_markdown: λ§ν¬λ€μ΄
|
|
126
|
+
toggle_richtext: μμ νΈμ§
|
|
127
|
+
markdown_to_richtext_confirm: μμ νΈμ§μΌλ‘ μ ννλ©΄ λ§ν¬λ€μ΄ μλ³Έμ΄ μμ λ©λλ€.
|
|
128
|
+
κ³μνμκ² μ΅λκΉ?
|
|
129
|
+
richtext_to_markdown_confirm: λ§ν¬λ€μ΄μΌλ‘ μ ννλ©΄ νμ¬ μμ νΈμ§ λ΄μ©μ΄ μμ λ©λλ€. κ³μνμκ² μ΅λκΉ?
|
|
123
130
|
share:
|
|
124
131
|
shared: ν¬λ¦¬μμ΄ν°λΈκ° μ±κ³΅μ μΌλ‘ 곡μ λμμ΅λλ€.
|
|
125
132
|
permission_updated: κΆνμ΄ μ±κ³΅μ μΌλ‘ λ³κ²½λμμ΅λλ€.
|
|
@@ -134,8 +141,11 @@ ko:
|
|
|
134
141
|
progress_recalculated: μ§νλ₯ μ λ€μ κ³μ° νμ΅λλ€.
|
|
135
142
|
errors:
|
|
136
143
|
no_permission: μ΄ μμ
μ μνν κΆνμ΄ μμ΅λλ€.
|
|
144
|
+
metadata_must_be_object: λ©νλ°μ΄ν°λ κ°μ²΄μ¬μΌ ν©λλ€.
|
|
137
145
|
inline_editor:
|
|
138
146
|
placeholder: ν¬λ¦¬μμ΄ν°λΈλ₯Ό μ€λͺ
ν΄μ£ΌμΈμβ¦
|
|
147
|
+
markdown_placeholder: λ§ν¬λ€μ΄μΌλ‘ μμ±β¦
|
|
148
|
+
markdown_preview_placeholder: 미리보기
|
|
139
149
|
edit_title: ν¬λ¦¬μμ΄ν°λΈ μμ
|
|
140
150
|
edit:
|
|
141
151
|
inline_editor_only_html: ν¬λ¦¬μμ΄ν°λΈ μμ μ μΈλΌμΈ νΈμ§κΈ°μμ λ°λ‘ μ§ννμΈμ.
|