hook up new autosave on content#edit fields

This commit is contained in:
drusepth 2023-01-16 15:24:09 -08:00
parent 1b671a6225
commit d7adaeddc4
8 changed files with 91 additions and 43 deletions

View File

@ -2,11 +2,14 @@ $(document).ready(function() {
$('.autosave-closest-form-on-change').change(function () {
var content_form = $(this).closest('form');
// Submit content_form with ajax
if (content_form) {
M.toast({ html: 'Saving changes...' });
// M.toast({ html: 'Saving changes...' });
console.log('saving changes');
content_form.submit();
} else {
M.toast({ html: "There was an error saving your changes. Please back up any changes and refresh the page." });
console.log('error saving changes');
// M.toast({ html: "There was an error saving your changes. Please back up any changes and refresh the page." });
}
// TODO: it'd be really nice to capture the response of the form submit but I don't

View File

@ -501,11 +501,6 @@ class ContentController < ApplicationController
attribute_value.save!
UpdateTextAttributeReferencesJob.perform_later(attribute_value.id)
respond_to do |format|
format.html { redirect_back(fallback_location: root_path, notice: "#{@attribute_field.label} updated!") }
format.json { render json: attribute_value, status: :success }
end
end
def tags_field_update

View File

@ -29,7 +29,8 @@
<%=
text_area_tag "field[value]",
value,
class: "js-can-mention-pages materialize-textarea" \
class: "max-w-3xl shadow-sm block w-full focus:ring-notebook-blue focus:border-notebook-blue sm:text-sm border-0 border-l-4 border-gray-200 rounded-md" \
+ "js-can-mention-pages" \
+ "#{' autocomplete js-autocomplete-' + field[:id].to_s if should_autocomplete}" \
+ "#{' autosave-closest-form-on-change' if should_autosave}",
placeholder: placeholder

View File

@ -5,7 +5,7 @@
<%= f.label field[:id], field[:label] %>
</div>
<% if page.new_record? || (page.persisted? && page.universe && page.universe.user == current_user) || page.universe_id.nil? # || page.universe_id.zero? %>
<% if raw_model.new_record? || (raw_model.persisted? && raw_model.universe && raw_model.universe.user == current_user) || raw_model.universe_id.nil? # || raw_model.universe_id.zero? %>
<%# todo not like this %>
<%
valid_universes = []
@ -17,7 +17,7 @@
else
# Premium content
if current_user.on_premium_plan? \
|| PermissionService.user_has_active_promotion_for_this_content_type(user: current_user, content_type: page.class.name) \
|| PermissionService.user_has_active_promotion_for_this_content_type(user: current_user, content_type: raw_model.class.name) \
|| page.user == current_user
valid_universes += current_user.universes
@ -43,7 +43,7 @@
select_tag "field[value]",
options_for_select(
@universe_dropdown_options.compact,
page.try(:universe_id) || @universe_scope.try(:id)
raw_model.try(:universe_id) || @universe_scope.try(:id)
),
include_blank: current_user.on_premium_plan? || Rails.application.config.content_types[:free].map(&:name).include?(raw_model.class.name),
class: 'autosave-closest-form-on-change'
@ -56,7 +56,7 @@
<% end %>
<% else %>
<br />
<%= link_to(page.universe.name, page.universe) if page.universe %>
<%= link_to(raw_model.universe.name, raw_model.universe) if raw_model.universe %>
<% end %>
</div>
</div>

View File

@ -1,5 +1,16 @@
<%
page_description = "#{@content.name}, #{@content.description} — a fictional #{@content.class.name.downcase} on Notebook.ai"
page_description ||= @content.description
page_description ||= "#{@content.name} is a fictional #{@content.class.name.downcase} on Notebook.ai"
set_meta_tags title: @content.name,
description: page_description.truncate(160),
image_src: @content.first_public_image,
og: { type: 'website' },
twitter: { card: 'photo', image: @content.first_public_image }
%>
<div
x-data="{}"
x-data="{ showEditMode: false }"
>
<nav class="bg-white h-16 border-b border-gray-200 flex sticky top-14 z-40" aria-label="Breadcrumb">
<ol role="list" class="flex-1 mx-auto px-4 flex space-x-4 sm:px-6 lg:px-8">
@ -33,11 +44,12 @@
<div class="flex flex-row pt-3">
<div class="mr-3">
<button type="button" data-action="dropdown#toggle click@window->dropdown#hide" class="w-full bg-notebook-blue border border-notebook-blue rounded-md shadow-sm px-4 py-2 inline-flex justify-center text-sm font-medium text-gray-200 hover:bg-blue-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" id="page-index-button" aria-expanded="false" aria-haspopup="true">
<svg xmlns="http://www.w3.org/2000/svg" class="mr-3 h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />
</svg>
Edit mode
<button type="button" class="w-full bg-notebook-blue border border-notebook-blue rounded-md shadow-sm px-4 py-2 inline-flex justify-center text-sm font-medium text-gray-200 hover:bg-blue-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" id="page-index-button" aria-expanded="false" aria-haspopup="true"
data-action="dropdown#toggle click@window->dropdown#hide"
@click="showEditMode = !showEditMode"
>
<i class="material-icons text-2xl mr-3 -mt-1.5" x-text="showEditMode ? 'visibility' : 'edit'"></i>
<span x-text="showEditMode ? 'Read Mode' : 'Edit Mode'"></span>
</button>
</div>
<div data-controller="dropdown" class="mr-3">
@ -221,17 +233,6 @@
<div class="mt-128 pt-128">spacer</div>
<%
page_description = "#{@content.name}, #{@content.description} — a fictional #{@content.class.name.downcase} on Notebook.ai"
page_description ||= "#{@content.name} is a fictional #{@content.class.name.downcase} on Notebook.ai"
set_meta_tags title: @content.name,
description: page_description,
image_src: @content.first_public_image,
og: { type: 'website' },
twitter: { card: 'photo', image: @content.first_public_image }
%>
<%= content_for :full_width_page_header do %>
<%= render partial: 'content/display/image_card_header' %>

View File

@ -1,29 +1,39 @@
<form class="space-y-8 divide-y divide-gray-200 px-6">
<div class="divide-y divide-gray-200">
<div class="space-y-8 divide-y divide-gray-200 px-6">
<div class="divide-y divide-gray-200 space-y-20 mb-20">
<% content.data[:categories].each do |category| %>
<div class="mb-20">
<div
x-show="showEditMode || (<%= category[:fields].map { |field| "#{field[:value].inspect} != ''" }.join(' || ') %>)"
>
<div class="pt-4 flex flex-row space-x-32">
<h3 class="text-lg leading-6 font-medium text-gray-900">
<h3 class="text-lg leading-6 font-medium text-gray-900 flex-1">
<i class="material-icons float-left <%= content.class_text_color %> mr-2"><%= category[:icon] %></i>
<%= category[:label] %>
</h3>
<div class="flex-1 bg-gray-200 rounded-full h-4 relative top-1.5">
<div class="<%= content.class_color %> text-xs text-white font-medium text-center p-0.5 leading-none rounded-full line-clamp-1" style="width: <%= category[:percent_complete] %>%">
<%= category[:percent_complete] %>% complete
<% if category[:percent_complete].present? %>
<div class="flex-1 bg-gray-200 rounded-full h-4 relative top-1.5"
x-show="showEditMode"
>
<div class="<%= content.class_color %> text-xs text-white font-medium text-center p-0.5 leading-none rounded-full line-clamp-1" style="width: <%= category[:percent_complete] %>%">
<%= category[:percent_complete] %>% complete
</div>
</div>
</div>
<% end %>
</div>
<div class="mt-6 sm:mt-5 space-y-6 sm:space-y-5">
<% category[:fields].each do |field| %>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 pt-4">
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 pt-4"
x-data="{ value: '<%= escape_javascript field[:value] %>' }"
x-show="showEditMode || value != ''"
>
<div class="pl-8">
<label for="<%= field[:name] %>" class="block text-sm font-medium text-gray-700">
<%= field[:label] %>
</label>
</div>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="mt-1 sm:mt-0 sm:col-span-2"
x-show="!showEditMode"
>
<%=
case field[:type]
when 'name'
@ -39,10 +49,38 @@
end
%>
</div>
<div class="-mt-1 col-span-2 col-start-2"
x-show="showEditMode"
>
<%= form_for content.raw_model, url: FieldTypeService.form_path(field), remote: true, authenticity_token: true do |f| %>
<%= hidden_field_tag "entity[entity_id]", content.id %>
<%= hidden_field_tag "entity[entity_type]", content.class_name %>
<%=
case field[:type]
when 'name', 'text_area', 'textarea'
render partial: 'content/form/rich_text_input', locals: {
f: f,
content: content,
field: field,
show_label: false,
autocomplete: AutocompleteService.for_field_label(content_model: content.class, label: field[:label]),
autosave: true
}
when 'universe'
render partial: 'content/form/field_types/universe', locals: {
f: f,
field: field,
page: content,
raw_model: content.raw_model
}
end
%>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
</form>
</div>

View File

@ -1,3 +1,3 @@
<h1>
<%= field[:value] %>
<%= ContentFormatterService.show(text: field[:value], viewing_user: current_user) %>
</h1>

View File

@ -1 +1,11 @@
<%= field[:value] %>
<%#
todo do we want markdown support, simple_format, tags, mentions, etc?
%>
<div class="space-y-4">
<%=
simple_format ContentFormatterService.show(text: field[:value], viewing_user: current_user),
{},
wrapper_tag: 'div'
%>
</div>