adjust mobile tables

This commit is contained in:
Alex Turchyn authored and Pete Matsyburka committed 2026-09-23 11:00:17 +03:00
1 parent 9e89cb92a9
commit e3e5c237d4
9 files changed
+205 -56

No files matched your search

+64
View File
@@ -170,3 +170,67 @@ markdown-editor [contenteditable] p {
native-action {
display: contents;
}
@media (max-width: 767px) {
.table-stack,
.table-stack tbody,
.table-stack tr,
.table-stack td {
display: block;
}
.table-stack,
div:has(> .table-stack) {
overflow: visible;
}
.table-stack thead {
display: none;
}
.table-stack tr {
@apply bg-base-200 rounded-2xl py-3 mb-3 border-0;
}
.table-stack td {
@apply px-4 py-1;
}
.table-stack td[data-label] {
@apply flow-root text-right;
overflow-wrap: anywhere;
}
.table-stack td[data-label]::before {
content: attr(data-label);
@apply float-left mr-4 text-sm leading-6 text-base-content/60;
}
.table-stack td:first-child {
@apply font-semibold;
}
.table-stack td:last-child {
@apply grid grid-cols-2 gap-2 pt-3;
}
.table-stack td:last-child:has(> .dropdown) {
grid-template-columns: repeat(2, minmax(0, 1fr)) auto;
}
.table-stack td:last-child:not(:has(*)) {
display: none;
}
.table-stack td:last-child > * {
margin-left: 0 !important;
}
.table-stack td:last-child > :last-child:nth-child(odd):not(.dropdown) {
@apply col-span-2;
}
.table-stack td:last-child .btn {
@apply btn-sm w-full;
}
}
@@ -1,20 +1,22 @@
<% unless turbo_native_ios? %>
<tr class="group">
<td class="flex items-center space-x-1">
<%= svg_icon('discount_check_filled', class: 'w-6 h-6 shrink-0 text-green-500') %>
<span class="flex items-center">
<span class="whitespace-nowrap"><%= t('docuseal_trusted_signature') %></span>
<div class="tooltip tooltip-top ml-1 shrink-0 hidden md:flex" data-tip="<%= t('sign_documents_with_trusted_certificate_provided_by_docu_seal_your_documents_and_data_are_never_shared_with_docu_seal_p_d_f_checksum_is_provided_to_generate_a_trusted_signature') %>">
<%= svg_icon('circle_question', class: 'w-4 h-4 stroke-1 shrink-0') %>
</div>
</span>
</td>
<td>
<div class="flex items-center space-x-1">
<%= svg_icon('discount_check_filled', class: 'w-6 h-6 shrink-0 text-green-500') %>
<span class="flex items-center">
<span class="whitespace-nowrap"><%= t('docuseal_trusted_signature') %></span>
<div class="tooltip tooltip-top ml-1 shrink-0 hidden md:flex" data-tip="<%= t('sign_documents_with_trusted_certificate_provided_by_docu_seal_your_documents_and_data_are_never_shared_with_docu_seal_p_d_f_checksum_is_provided_to_generate_a_trusted_signature') %>">
<%= svg_icon('circle_question', class: 'w-4 h-4 stroke-1 shrink-0') %>
</div>
</span>
</div>
</td>
<td data-label="<%= t('valid_to') %>">
<a href="<%= "#{Docuseal::CLOUD_URL}/sign_up?#{{ redir: "#{Docuseal::CONSOLE_URL}/on_premises" }.to_query}" %>" class="btn btn-neutral btn-sm text-white whitespace-nowrap">
<%= t('unlock_with_docuseal_pro') %>
</a>
</td>
<td>
<td data-label="<%= t('status') %>">
<div class="md:tooltip" data-tip="<%= t('unlock_with_docuseal_pro') %>">
<%= button_to settings_esign_path, method: :put, params: { name: Docuseal::AATL_CERT_NAME }, class: 'btn btn-outline btn-neutral btn-xs whitespace-nowrap', title: t('make_default'), disabled: true do %>
<%= t('make_default') %>
+5 -4
View File
@@ -32,7 +32,8 @@
<%= t('verify_signed_pdf') %>
</div>
<div class="text-xs">
<%= t('click_to_upload_or_drag_and_drop_files_html') %>
<span class="md:hidden"><%= t('click_to_upload') %></span>
<span class="hidden md:inline"><%= t('click_to_upload_or_drag_and_drop_files_html') %></span>
</div>
</div>
<input id="file" name="files[]" class="hidden" data-action="change:file-dropzone#onSelectFiles" data-target="file-dropzone.input" type="file" accept="application/pdf" multiple>
@@ -54,7 +55,7 @@
</div>
<%= render 'alert' %>
<div class="overflow-x-auto">
<table class="table w-full table-lg rounded-b-none overflow-hidden">
<table class="table table-stack w-full table-lg rounded-b-none overflow-hidden">
<thead class="bg-base-200">
<tr class="text-neutral uppercase">
<th>
@@ -77,10 +78,10 @@
<td>
<%= item['name'] %>
</td>
<td>
<td data-label="<%= t('valid_to') %>">
<%= l(item['pkcs'].certificate.not_after.to_date, format: :long, locale: current_account.locale) %>
</td>
<td>
<td data-label="<%= t('status') %>">
<% if item['status'] == 'default' %>
<span class="badge badge-lg badge-info badge-outline">
<%= t('default') %>
+17 -16
View File
@@ -2,16 +2,15 @@
<div class="flex-wrap space-y-4 md:flex md:flex-nowrap md:space-y-0 md:space-x-10">
<%= render 'shared/settings_nav' %>
<div class="md:flex-grow">
<div class="flex flex-col md:flex-row md:flex-wrap gap-2 md:justify-between md:items-end mb-4 min-h-12">
<h1 class="text-3xl md:text-4xl font-bold">
<div class="flex flex-row items-center justify-between gap-2 md:items-end mb-4 min-h-12">
<h1 class="text-3xl md:text-4xl font-bold truncate min-w-0">
<%= t('mcp_server') %>
</h1>
<div class="flex flex-col md:flex-row gap-y-2 gap-x-4 md:items-center">
<%= link_to new_settings_mcp_path, class: 'btn btn-primary btn-md gap-2 w-full md:w-fit', aria: { label: t('new_token') }, data: { turbo_frame: 'modal' } do %>
<%= svg_icon('plus', class: 'w-6 h-6') %>
<span><%= t('new_token') %></span>
<% end %>
</div>
<%= link_to new_settings_mcp_path, class: 'shrink-0 btn btn-primary btn-md gap-2', aria: { label: t('new_token') }, data: { turbo_frame: :modal, native_modal: :medium } do %>
<%= svg_icon('plus', class: 'w-6 h-6') %>
<span class="md:hidden"><%= t('new') %></span>
<span class="hidden md:inline"><%= t('new_token') %></span>
<% end %>
</div>
<% if @mcp_token.present? %>
<div class="space-y-4 mb-4">
@@ -48,7 +47,7 @@
</div>
<% end %>
<div class="overflow-x-auto">
<table class="table w-full table-lg rounded-b-none overflow-hidden">
<table class="table table-stack w-full table-lg rounded-b-none overflow-hidden">
<thead class="bg-base-200">
<tr class="text-neutral uppercase">
<th>
@@ -70,14 +69,16 @@
<td>
<%= mcp_token.name %>
</td>
<td>
<% if @mcp_token.present? && mcp_token.id == @mcp_token.id %>
<%= @mcp_token.token %>
<% else %>
<%= "#{mcp_token.token_prefix}#{'*' * 38}" %>
<% end %>
<td data-label="<%= t('token') %>">
<span class="font-mono truncate inline-block max-w-[220px] align-middle">
<% if @mcp_token.present? && mcp_token.id == @mcp_token.id %>
<%= @mcp_token.token %>
<% else %>
<%= "#{mcp_token.token_prefix}#{'*' * 38}" %>
<% end %>
</span>
</td>
<td>
<td data-label="<%= t('created_at') %>">
<%= l(mcp_token.created_at.in_time_zone(current_account.timezone), format: :short, locale: current_account.locale) %>
</td>
<td class="flex items-center space-x-2 justify-end">
+2 -1
View File
@@ -13,7 +13,8 @@
<%= t('upload_a_new_document') %>
</div>
<div class="text-sm">
<%= t('click_to_upload_or_drag_and_drop_html') %>
<span class="md:hidden"><%= t('click_to_upload') %></span>
<span class="hidden md:inline"><%= t('click_to_upload_or_drag_and_drop_html') %></span>
</div>
<% if Docuseal.multitenant? && !turbo_native_app? %>
<a class="flex absolute bottom-4 items-center text-sm mt-2 pointer-events-auto" href="<%= new_template_path(modal_tab: 'google_drive') %>" data-turbo-frame="modal" data-native-modal="medium">
+2 -1
View File
@@ -40,7 +40,8 @@
<%= t('upload_initials') %>
</div>
<div class="text-xs">
<%= t('click_to_upload_or_drag_and_drop_html') %>
<span class="md:hidden"><%= t('click_to_upload') %></span>
<span class="hidden md:inline"><%= t('click_to_upload_or_drag_and_drop_html') %></span>
</div>
</div>
<input id="file" name="file" class="hidden" data-action="change:file-dropzone#onSelectFiles" data-target="file-dropzone.input" type="file" accept="image/png,image/jpeg,image/jpg">
+2 -1
View File
@@ -40,7 +40,8 @@
<%= t('upload_signature') %>
</div>
<div class="text-xs">
<%= t('click_to_upload_or_drag_and_drop_html') %>
<span class="md:hidden"><%= t('click_to_upload') %></span>
<span class="hidden md:inline"><%= t('click_to_upload_or_drag_and_drop_html') %></span>
</div>
</div>
<input id="file" name="file" class="hidden" data-action="change:file-dropzone#onSelectFiles" data-target="file-dropzone.input" type="file" accept="image/png,image/jpeg,image/jpg">
+87 -23
View File
@@ -2,8 +2,8 @@
<div class="flex-wrap space-y-4 md:flex md:flex-nowrap md:space-y-0 md:space-x-10">
<%= render 'shared/settings_nav' %>
<div class="md:flex-grow">
<div class="flex flex-col md:flex-row md:flex-wrap gap-2 md:justify-between md:items-end mb-4 min-h-12">
<h1 class="text-3xl md:text-4xl font-bold">
<div class="flex flex-wrap items-center md:items-end gap-x-4 gap-y-2 mb-4 min-h-12">
<h1 class="text-3xl md:text-4xl font-bold truncate min-w-0 mr-auto md:order-1">
<% if params[:status] == 'archived' %>
<%= t('archived_users') %>
<% elsif params[:status] == 'integration' %>
@@ -12,30 +12,94 @@
<%= t('users') %>
<% end %>
</h1>
<div class="flex flex-col md:flex-row gap-y-2 gap-x-4 md:items-center">
<% if params[:status].blank? %>
<% if can?(:create, User.new(account: current_account)) %>
<%= render 'users/extra_buttons' %>
<% if content_for(:add_user_button) %>
<%= content_for(:add_user_button) %>
<% else %>
<%= link_to new_user_path, class: 'btn btn-primary btn-md gap-2 w-full md:w-fit', data: { turbo_frame: 'modal' } do %>
<%= svg_icon('plus', class: 'w-6 h-6') %>
<span><%= t('new_user') %></span>
<% end %>
<% end %>
<% else %>
<div class="md:tooltip" data-tip="<%= t('contact_your_administrator_to_add_new_users') %>">
<%= link_to '#', class: 'btn btn-primary btn-md gap-2 w-full md:w-fit btn-disabled', data: { turbo_frame: 'modal' } do %>
<%= svg_icon('plus', class: 'w-6 h-6') %>
<span><%= t('new_user') %></span>
<% end %>
</div>
<% if params[:status].blank? %>
<% if can?(:create, User.new(account: current_account)) %>
<%= link_to new_user_path, class: 'shrink-0 md:order-3 btn btn-primary btn-md gap-2', title: t('new_user'), data: { turbo_frame: 'modal' } do %>
<%= svg_icon('plus', class: 'w-6 h-6') %>
<span class="md:hidden"><%= t('new') %></span>
<span class="hidden md:inline"><%= t('new_user') %></span>
<% end %>
<% else %>
<div class="shrink-0 md:order-3 md:tooltip" data-tip="<%= t('contact_your_administrator_to_add_new_users') %>">
<%= link_to '#', class: 'btn btn-primary btn-md gap-2 btn-disabled', title: t('new_user'), data: { turbo_frame: 'modal' } do %>
<%= svg_icon('plus', class: 'w-6 h-6') %>
<span class="md:hidden"><%= t('new') %></span>
<span class="hidden md:inline"><%= t('new_user') %></span>
<% end %>
</div>
<% end %>
</div>
<% end %>
<% if params[:status].blank? && can?(:create, User.new(account: current_account)) %>
<div class="basis-full md:basis-auto md:order-2 flex flex-col md:flex-row gap-y-2 gap-x-4 md:items-center">
<%= render 'users/extra_buttons' %>
</div>
<% end %>
</div>
<div class="overflow-x-auto">
<div class="md:hidden divide-y divide-base-300">
<% @users.each do |user| %>
<% can_edit = params[:status].blank? && can?(:update, user) && user.archived_at.blank? %>
<% can_remove = params[:status] != 'archived' && can?(:destroy, user) && user != current_user %>
<% can_unarchive = params[:status] == 'archived' && can?(:create, user) && user != current_user && user.archived_at? %>
<div class="flex items-center gap-3 py-4">
<span class="flex items-center justify-center w-10 h-10 rounded-full bg-base-300 text-sm">
<%= user.initials.presence || user.email.first.upcase %>
</span>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2">
<span class="font-semibold truncate"><%= user.full_name.presence || user.email %></span>
<span class="badge badge-info badge-outline badge-sm whitespace-nowrap shrink-0"><%= t(user.role) %></span>
</div>
<% if user.try(:pending_reconfirmation?) %>
<div class="text-sm text-base-content/70 truncate"><%= user.unconfirmed_email %> (<%= t('unconfirmed') %>)</div>
<% elsif user.full_name.present? %>
<div class="text-sm text-base-content/70 truncate"><%= user.email %></div>
<% end %>
</div>
<% if can_edit || can_remove || can_unarchive %>
<native-menu class="<%= 'dropdown dropdown-end' unless turbo_native_app? %>">
<label tabindex="0" aria-label="<%= t('more') %>" class="btn btn-ghost btn-circle btn-sm">
<%= svg_icon('dots_vertical', class: 'w-5 h-5') %>
</label>
<ul tabindex="0" class="<%= turbo_native_app? ? 'hidden' : 'z-10 dropdown-content p-2 mt-2 shadow menu bg-base-100 rounded-box min-w-[160px]' %>">
<% if can_edit %>
<li>
<native-menu-action data-icon="pencil" data-label="<%= t('edit') %>">
<%= link_to edit_user_path(user), class: 'flex items-center gap-2', data: { turbo_frame: 'modal' } do %>
<%= svg_icon('pencil', class: 'w-5 h-5 flex-shrink-0') %>
<span><%= t('edit') %></span>
<% end %>
</native-menu-action>
</li>
<% end %>
<% if can_remove %>
<li>
<native-menu-action data-icon="trash" data-label="<%= t('remove') %>" data-destructive="true">
<button form="<%= dom_id(user, :remove) %>" class="flex items-center gap-2 w-full text-error" data-turbo-confirm="<%= t('are_you_sure_') %>">
<%= svg_icon('trash', class: 'w-5 h-5 flex-shrink-0') %>
<span><%= t('remove') %></span>
</button>
<%= button_to '', user_path(user), method: :delete, form: { id: dom_id(user, :remove) }, form_class: 'hidden' %>
</native-menu-action>
</li>
<% end %>
<% if can_unarchive %>
<li>
<native-menu-action data-icon="rotate" data-label="<%= t('unarchive') %>">
<button form="<%= dom_id(user, :unarchive) %>" class="flex items-center gap-2 w-full" data-turbo-confirm="<%= t('are_you_sure_') %>">
<%= svg_icon('rotate', class: 'w-5 h-5 flex-shrink-0') %>
<span><%= t('unarchive') %></span>
</button>
<%= button_to '', user_path(user), method: :put, params: { user: { archived_at: nil } }, form: { id: dom_id(user, :unarchive) }, form_class: 'hidden' %>
</native-menu-action>
</li>
<% end %>
</ul>
</native-menu>
<% end %>
</div>
<% end %>
</div>
<div class="hidden md:block overflow-x-auto">
<table class="table w-full table-lg rounded-b-none overflow-hidden">
<thead class="bg-base-200">
<tr class="text-neutral uppercase">