From 594333a1833ca7773e7ac509cad570970bb30ab6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Feb 2026 16:12:58 -0800 Subject: [PATCH 001/113] chore(deps): bump rack from 3.2.3 to 3.2.5 (#13569) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [rack](https://github.com/rack/rack) from 3.2.3 to 3.2.5.
Changelog

Sourced from rack's changelog.

Changelog

All notable changes to this project will be documented in this file. For info on how to format all future additions to this file please reference Keep A Changelog.

Unreleased

Security

SPEC Changes

Added

Changed

Fixed

[3.2.4] - 2025-11-03

Fixed

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=rack&package-manager=bundler&previous-version=3.2.3&new-version=3.2.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/chatwoot/chatwoot/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index cc1f9e253..717ec2a02 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -677,7 +677,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (3.2.3) + rack (3.2.5) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-contrib (2.5.0) From 2ab117e8eb0341748cbfbc6f5a0008ecbee91d0f Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Wed, 18 Feb 2026 22:10:06 -0800 Subject: [PATCH 002/113] feat(cloud-billing): cancel subscriptions at period end on deletion mark (#13580) ## How to reproduce In Chatwoot Cloud, mark an account for deletion from account settings while the account has an active Stripe subscription. Before this change, deletion marking did not explicitly mark subscriptions to stop renewing at period end. ## What changed This PR adds `Enterprise::Billing::CancelCloudSubscriptionsService` and calls it from the delete action path in `Enterprise::Api::V1::AccountsController`. The service lists only active Stripe subscriptions for the customer and sets `cancel_at_period_end: true` when needed. The account deletion schedule remains unchanged (existing static 7-day behavior), and Stripe deleted-event fallback behavior remains unchanged. ## How this was tested Added and updated specs: - `spec/enterprise/services/enterprise/billing/cancel_cloud_subscriptions_service_spec.rb` - `spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb` Executed: - `bundle exec rspec spec/enterprise/services/enterprise/billing/cancel_cloud_subscriptions_service_spec.rb` - `bundle exec rspec spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb:363` --- .../enterprise/api/v1/accounts_controller.rb | 8 +++ .../cancel_cloud_subscriptions_service.rb | 24 +++++++++ .../api/v1/accounts_controller_spec.rb | 24 ++++++++- ...cancel_cloud_subscriptions_service_spec.rb | 51 +++++++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 enterprise/app/services/enterprise/billing/cancel_cloud_subscriptions_service.rb create mode 100644 spec/enterprise/services/enterprise/billing/cancel_cloud_subscriptions_service_spec.rb diff --git a/enterprise/app/controllers/enterprise/api/v1/accounts_controller.rb b/enterprise/app/controllers/enterprise/api/v1/accounts_controller.rb index 0f829b973..d176db597 100644 --- a/enterprise/app/controllers/enterprise/api/v1/accounts_controller.rb +++ b/enterprise/app/controllers/enterprise/api/v1/accounts_controller.rb @@ -102,6 +102,8 @@ class Enterprise::Api::V1::AccountsController < Api::BaseController reason = 'manual_deletion' if @account.mark_for_deletion(reason) + cancel_cloud_subscriptions_for_deletion + render json: { message: 'Account marked for deletion' }, status: :ok else render json: { message: @account.errors.full_messages.join(', ') }, status: :unprocessable_entity @@ -125,6 +127,12 @@ class Enterprise::Api::V1::AccountsController < Api::BaseController render_redirect_url(session.url) end + def cancel_cloud_subscriptions_for_deletion + Enterprise::Billing::CancelCloudSubscriptionsService.new(account: @account).perform + rescue Stripe::StripeError => e + Rails.logger.warn("Failed to cancel cloud subscriptions for account #{@account.id}: #{e.class} - #{e.message}") + end + def render_redirect_url(redirect_url) render json: { redirect_url: redirect_url } end diff --git a/enterprise/app/services/enterprise/billing/cancel_cloud_subscriptions_service.rb b/enterprise/app/services/enterprise/billing/cancel_cloud_subscriptions_service.rb new file mode 100644 index 000000000..53032c8ca --- /dev/null +++ b/enterprise/app/services/enterprise/billing/cancel_cloud_subscriptions_service.rb @@ -0,0 +1,24 @@ +class Enterprise::Billing::CancelCloudSubscriptionsService + pattr_initialize [:account!] + + def perform + return if stripe_customer_id.blank? + return unless ChatwootApp.chatwoot_cloud? + + subscriptions.each do |subscription| + next if subscription.cancel_at_period_end + + Stripe::Subscription.update(subscription.id, cancel_at_period_end: true) + end + end + + private + + def subscriptions + Stripe::Subscription.list(customer: stripe_customer_id, status: 'active', limit: 100).data + end + + def stripe_customer_id + account.custom_attributes['stripe_customer_id'] + end +end diff --git a/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb b/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb index e79cbd237..9089b089a 100644 --- a/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb +++ b/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb @@ -357,10 +357,32 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do context 'when it is an admin' do before do # Create the installation config for cloud environment - InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_create(value: 'cloud') + InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_initialize.update!(value: 'cloud') end it 'marks the account for deletion when action is delete' do + cancellation_service = instance_double(Enterprise::Billing::CancelCloudSubscriptionsService, perform: true) + allow(Enterprise::Billing::CancelCloudSubscriptionsService).to receive(:new).with(account: account) + .and_return(cancellation_service) + + post "/enterprise/api/v1/accounts/#{account.id}/toggle_deletion", + headers: admin.create_new_auth_token, + params: { action_type: 'delete' }, + as: :json + + expect(response).to have_http_status(:ok) + expect(account.reload.custom_attributes['marked_for_deletion_at']).to be_present + expect(account.custom_attributes['marked_for_deletion_reason']).to eq('manual_deletion') + expect(Enterprise::Billing::CancelCloudSubscriptionsService).to have_received(:new).with(account: account) + expect(cancellation_service).to have_received(:perform) + end + + it 'returns success even if stripe cancellation fails' do + cancellation_service = instance_double(Enterprise::Billing::CancelCloudSubscriptionsService) + allow(Enterprise::Billing::CancelCloudSubscriptionsService).to receive(:new).with(account: account) + .and_return(cancellation_service) + allow(cancellation_service).to receive(:perform).and_raise(Stripe::APIError.new('stripe unavailable')) + post "/enterprise/api/v1/accounts/#{account.id}/toggle_deletion", headers: admin.create_new_auth_token, params: { action_type: 'delete' }, diff --git a/spec/enterprise/services/enterprise/billing/cancel_cloud_subscriptions_service_spec.rb b/spec/enterprise/services/enterprise/billing/cancel_cloud_subscriptions_service_spec.rb new file mode 100644 index 000000000..f9eab281b --- /dev/null +++ b/spec/enterprise/services/enterprise/billing/cancel_cloud_subscriptions_service_spec.rb @@ -0,0 +1,51 @@ +require 'rails_helper' + +RSpec.describe Enterprise::Billing::CancelCloudSubscriptionsService do + subject(:service) { described_class.new(account: account) } + + let(:account) { create(:account, custom_attributes: custom_attributes) } + let(:custom_attributes) { { 'stripe_customer_id' => 'cus_123' } } + + describe '#perform' do + context 'when deployment is not cloud' do + it 'does not call stripe subscriptions api' do + allow(ChatwootApp).to receive(:chatwoot_cloud?).and_return(false) + allow(Stripe::Subscription).to receive(:list) + + service.perform + + expect(Stripe::Subscription).not_to have_received(:list) + end + end + + context 'when stripe customer id is missing' do + let(:custom_attributes) { {} } + + it 'does not call stripe subscriptions api' do + allow(ChatwootApp).to receive(:chatwoot_cloud?).and_return(true) + allow(Stripe::Subscription).to receive(:list) + + service.perform + + expect(Stripe::Subscription).not_to have_received(:list) + end + end + + context 'when account is cloud with active subscriptions' do + let(:subscription_response) { Struct.new(:data).new([sub_1, sub_2]) } + let(:sub_1) { instance_double(Stripe::Subscription, id: 'sub_1', cancel_at_period_end: false) } + let(:sub_2) { instance_double(Stripe::Subscription, id: 'sub_2', cancel_at_period_end: true) } + + it 'marks only active subscriptions that are not yet set to cancel at period end' do + allow(ChatwootApp).to receive(:chatwoot_cloud?).and_return(true) + allow(Stripe::Subscription).to receive(:list).and_return(subscription_response) + allow(Stripe::Subscription).to receive(:update) + + service.perform + + expect(Stripe::Subscription).to have_received(:list).with(customer: 'cus_123', status: 'active', limit: 100) + expect(Stripe::Subscription).to have_received(:update).with('sub_1', cancel_at_period_end: true).once + end + end + end +end From c9619eaed2c03509491525385e1771dca673d294 Mon Sep 17 00:00:00 2001 From: Aakash Bakhle <48802744+aakashb95@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:55:15 +0530 Subject: [PATCH 003/113] chore: ignore .claude directory in gitignore (#13584) # Pull Request Template adds .claude to gitignore Co-authored-by: Tanmay Deep Sharma <32020192+tds-1@users.noreply.github.com> --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dbdd35bcd..017c5c224 100644 --- a/.gitignore +++ b/.gitignore @@ -95,6 +95,7 @@ yarn-debug.log* .claude/settings.local.json .cursor .codex/ +.claude/ CLAUDE.local.md # Histoire deployment From 7b2b3ac37d5e6bae7c37c0c7c8cf94cd8ef4d3b0 Mon Sep 17 00:00:00 2001 From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Date: Thu, 19 Feb 2026 15:04:40 +0530 Subject: [PATCH 004/113] feat(V5): Update settings pages UI (#13396) # Pull Request Template ## Description This PR updates settings page UI ## Type of change - [x] New feature (non-breaking change which adds functionality) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --- .../dashboard/assets/scss/_base.scss | 2 +- .../dashboard/assets/scss/_woot.scss | 80 ++ .../AgentCapacityPolicyCard.vue | 4 +- .../AssignmentCard/AssignmentCard.vue | 6 +- .../AssignmentPolicyCard.vue | 32 +- .../components/ExclusionRules.vue | 2 +- .../AssignmentPolicy/components/RadioCard.vue | 60 +- .../Campaigns/CampaignLayout.vue | 10 +- .../dashboard/components-next/CardLayout.vue | 2 +- .../CompaniesHeader/CompanyHeader.vue | 6 +- .../Companies/CompaniesListLayout.vue | 7 +- .../Contacts/ContactLabels/ContactLabels.vue | 4 +- .../Contacts/ContactsHeader/ContactHeader.vue | 4 +- .../ContactsActiveFiltersPreview.vue | 2 +- .../Contacts/ContactsListLayout.vue | 7 +- .../AttributeListItem.vue | 91 +- .../ConversationRequiredAttributeItem.vue | 8 +- .../ConversationRequiredAttributes.vue | 4 +- .../CustomAttributes/AttributeBadge.vue | 16 +- .../components-next/EmptyStateLayout.vue | 2 +- .../HelpCenter/HelpCenterLayout.vue | 11 +- .../Pages/LocalePage/AddLocaleDialog.vue | 1 + .../specs/composeConversationHelper.spec.js | 2 +- .../Settings/SettingsAccordion.vue | 31 + .../Settings/SettingsFieldSection.vue | 37 + .../Settings/SettingsToggleSection.vue | 45 + .../components-next/avatar/Avatar.vue | 22 +- .../components-next/captain/PageLayout.vue | 11 +- .../captain/pageComponents/Paywall.vue | 2 +- .../combobox/ComboBoxDropdown.vue | 4 +- .../FeatureSpotlightPopover.vue | 2 +- .../components-next/icon/provider.js | 4 +- .../icon/specs/provider.spec.js | 4 +- .../dashboard/components-next/input/Input.vue | 4 +- .../{Label => label}/AddLabel.vue | 0 .../dashboard/components-next/label/Label.vue | 71 ++ .../{Label => label}/LabelItem.vue | 0 .../{Label => label}/story/AddLabel.story.vue | 0 .../{Label => label}/story/Label.story.vue | 0 .../{Label => label}/story/fixtures.js | 0 .../pagination/PaginationFooter.vue | 12 +- .../components-next/select/Select.vue | 97 ++ .../components-next/sidebar/ChannelLeaf.vue | 4 +- .../components-next/sidebar/Sidebar.vue | 33 +- .../sidebar/SidebarGroupLeaf.vue | 6 +- .../components-next/switch/Switch.vue | 16 +- .../components-next/table/BaseTable.story.vue | 175 +++ .../components-next/table/BaseTable.vue | 60 + .../components-next/table/BaseTableCell.vue | 22 + .../components-next/table/BaseTableRow.vue | 14 + .../dashboard/components-next/table/index.js | 3 + .../year-in-review/ShareModal.vue | 2 +- .../dashboard/components/FormSection.vue | 31 - .../components/widgets/InboxName.vue | 9 +- .../components/widgets/LoadingState.vue | 2 +- .../components/widgets/SettingIntroBanner.vue | 2 +- .../components/widgets/forms/Input.vue | 6 +- app/javascript/dashboard/helper/inbox.js | 22 +- .../dashboard/helper/specs/inbox.spec.js | 8 +- .../dashboard/i18n/locale/en/agentBots.json | 6 +- .../dashboard/i18n/locale/en/agentMgmt.json | 3 + .../i18n/locale/en/attributesMgmt.json | 3 + .../dashboard/i18n/locale/en/automation.json | 9 +- .../dashboard/i18n/locale/en/cannedMgmt.json | 3 + .../dashboard/i18n/locale/en/customRole.json | 3 + .../dashboard/i18n/locale/en/inboxMgmt.json | 21 +- .../i18n/locale/en/integrationApps.json | 4 + .../i18n/locale/en/integrations.json | 18 +- .../dashboard/i18n/locale/en/labelsMgmt.json | 6 +- .../dashboard/i18n/locale/en/macros.json | 6 +- .../dashboard/i18n/locale/en/mfa.json | 2 +- .../dashboard/i18n/locale/en/sla.json | 13 +- .../i18n/locale/en/teamsSettings.json | 7 +- .../widget-preview/components/Widget.vue | 489 +++++--- .../pages/CampaignsPageRouteView.vue | 2 +- .../companies/pages/CompaniesIndex.vue | 2 +- .../contacts/pages/ContactsIndex.vue | 2 +- .../inbox/components/InboxListHeader.vue | 12 +- .../routes/dashboard/notifications/routes.js | 7 +- .../dashboard/settings/SettingsHeader.vue | 4 +- .../dashboard/settings/SettingsLayout.vue | 2 +- .../settings/SettingsSubPageHeader.vue | 6 +- .../dashboard/settings/SettingsWrapper.vue | 12 +- .../routes/dashboard/settings/Wrapper.vue | 37 +- .../dashboard/settings/account/Index.vue | 3 +- .../account/components/AutoResolve.vue | 4 +- .../account/components/SectionLayout.vue | 17 +- .../dashboard/settings/agentBots/Index.vue | 154 ++- .../dashboard/settings/agents/Index.vue | 202 +-- .../settings/assignmentPolicy/Index.vue | 2 +- .../pages/AgentAssignmentCreatePage.vue | 4 +- .../pages/AgentAssignmentEditPage.vue | 7 +- .../pages/AgentAssignmentIndexPage.vue | 4 +- .../pages/AgentCapacityCreatePage.vue | 4 +- .../pages/AgentCapacityEditPage.vue | 7 +- .../pages/AgentCapacityIndexPage.vue | 4 +- .../components/AgentAssignmentPolicyForm.vue | 11 +- .../dashboard/settings/attributes/Index.vue | 50 +- .../dashboard/settings/auditlogs/Index.vue | 121 +- .../settings/automation/AutomationRuleRow.vue | 98 +- .../dashboard/settings/automation/Index.vue | 45 +- .../dashboard/settings/canned/Index.vue | 211 ++-- .../components/BaseSettingsHeader.vue | 113 +- .../settings/conversationWorkflow/index.vue | 2 +- .../dashboard/settings/customRoles/Index.vue | 57 +- .../component/CustomRolePaywall.vue | 2 +- .../component/CustomRoleTableBody.vue | 85 +- .../dashboard/settings/inbox/ChannelList.vue | 2 +- .../dashboard/settings/inbox/ImapSettings.vue | 134 +- .../settings/inbox/InboxChannels.vue | 2 +- .../routes/dashboard/settings/inbox/Index.vue | 152 +-- .../inbox/PreChatForm/PreChatFields.vue | 117 +- .../settings/inbox/PreChatForm/Settings.vue | 264 ++-- .../dashboard/settings/inbox/Settings.vue | 1078 ++++++++++------- .../dashboard/settings/inbox/SmtpSettings.vue | 176 +-- .../settings/inbox/WidgetBuilder.vue | 443 ------- .../inbox/channels/google/Reauthorize.vue | 5 +- .../inbox/channels/instagram/Reauthorize.vue | 5 +- .../inbox/channels/microsoft/Reauthorize.vue | 5 +- .../inbox/channels/tiktok/Reauthorize.vue | 5 +- .../inbox/channels/whatsapp/Reauthorize.vue | 2 +- .../inbox/components/AccountHealth.vue | 24 +- .../inbox/components/BotConfiguration.vue | 93 +- .../settings/inbox/components/BusinessDay.vue | 161 ++- .../components/SenderNameExamplePreview.vue | 176 ++- .../inbox/components/WeeklyAvailability.vue | 173 +-- .../settings/inbox/facebook/Reauthorize.vue | 2 +- .../dashboard/settings/inbox/inbox.routes.js | 4 +- .../inbox/settingsPage/CollaboratorsPage.vue | 309 ++--- .../inbox/settingsPage/ConfigurationPage.vue | 265 ++-- .../settingsPage/CustomerSatisfactionPage.vue | 329 +++-- .../DashboardApps/DashboardAppsRow.vue | 81 +- .../integrations/DashboardApps/Index.vue | 107 +- .../dashboard/settings/integrations/Index.vue | 25 +- .../settings/integrations/Integration.vue | 6 +- .../integrations/IntegrationHooks.vue | 55 +- .../settings/integrations/IntegrationItem.vue | 30 +- .../settings/integrations/Linear.vue | 22 +- .../integrations/MultipleIntegrationHooks.vue | 211 ++-- .../settings/integrations/Notion.vue | 22 +- .../settings/integrations/Shopify.vue | 124 +- .../integrations/SingleIntegrationHooks.vue | 6 +- .../dashboard/settings/integrations/Slack.vue | 67 +- .../Slack/SelectChannelWarning.vue | 6 +- .../Slack/SlackIntegrationHelpText.vue | 9 +- .../settings/integrations/Webhooks/Index.vue | 47 +- .../integrations/Webhooks/WebhookRow.vue | 83 +- .../integrations/integrations.routes.js | 24 +- .../dashboard/settings/labels/Index.vue | 133 +- .../dashboard/settings/macros/Index.vue | 49 +- .../dashboard/settings/macros/MacroEditor.vue | 2 +- .../dashboard/settings/macros/MacroForm.vue | 6 +- .../settings/macros/MacroProperties.vue | 63 +- .../settings/macros/MacrosTableRow.vue | 105 +- .../settings/profile/AudioAlertCondition.vue | 6 +- .../dashboard/settings/profile/HotKeyCard.vue | 8 +- .../dashboard/settings/profile/Index.vue | 118 +- .../settings/profile/MfaSettings.vue | 21 +- .../settings/profile/MfaSettingsCard.vue | 4 +- .../profile/NotificationPreferences.vue | 18 +- .../settings/profile/profile.routes.js | 4 +- .../reports/components/ReportHeader.vue | 13 +- .../reports/components/ReportsWrapper.vue | 2 +- .../dashboard/settings/security/Index.vue | 5 +- .../security/components/SamlPaywall.vue | 2 +- .../security/components/SamlSettings.vue | 1 + .../routes/dashboard/settings/sla/Index.vue | 212 +++- .../{components => }/SLAPaywallEnterprise.vue | 5 +- .../sla/components/BaseEmptyState.vue | 33 - .../sla/components/SLABusinessHoursLabel.vue | 32 - .../settings/sla/components/SLAEmptyState.vue | 21 - .../settings/sla/components/SLAHeader.vue | 30 - .../settings/sla/components/SLAListItem.vue | 71 -- .../sla/components/SLAListItemLoading.vue | 41 - .../sla/components/SLAResponseTime.vue | 37 - .../settings/teams/AgentSelector.vue | 253 ++-- .../dashboard/settings/teams/Create/Index.vue | 4 +- .../settings/teams/Edit/EditAgents.vue | 6 +- .../dashboard/settings/teams/Edit/Index.vue | 4 +- .../routes/dashboard/settings/teams/Index.vue | 166 ++- .../shared/components/GreetingsEditor.vue | 8 +- theme/icons.js | 140 ++- 182 files changed, 5187 insertions(+), 4297 deletions(-) create mode 100644 app/javascript/dashboard/components-next/Settings/SettingsAccordion.vue create mode 100644 app/javascript/dashboard/components-next/Settings/SettingsFieldSection.vue create mode 100644 app/javascript/dashboard/components-next/Settings/SettingsToggleSection.vue rename app/javascript/dashboard/components-next/{Label => label}/AddLabel.vue (100%) create mode 100644 app/javascript/dashboard/components-next/label/Label.vue rename app/javascript/dashboard/components-next/{Label => label}/LabelItem.vue (100%) rename app/javascript/dashboard/components-next/{Label => label}/story/AddLabel.story.vue (100%) rename app/javascript/dashboard/components-next/{Label => label}/story/Label.story.vue (100%) rename app/javascript/dashboard/components-next/{Label => label}/story/fixtures.js (100%) create mode 100644 app/javascript/dashboard/components-next/select/Select.vue create mode 100644 app/javascript/dashboard/components-next/table/BaseTable.story.vue create mode 100644 app/javascript/dashboard/components-next/table/BaseTable.vue create mode 100644 app/javascript/dashboard/components-next/table/BaseTableCell.vue create mode 100644 app/javascript/dashboard/components-next/table/BaseTableRow.vue create mode 100644 app/javascript/dashboard/components-next/table/index.js delete mode 100644 app/javascript/dashboard/components/FormSection.vue delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/inbox/WidgetBuilder.vue rename app/javascript/dashboard/routes/dashboard/settings/sla/{components => }/SLAPaywallEnterprise.vue (87%) delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/sla/components/BaseEmptyState.vue delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/sla/components/SLABusinessHoursLabel.vue delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/sla/components/SLAEmptyState.vue delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/sla/components/SLAHeader.vue delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/sla/components/SLAListItem.vue delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/sla/components/SLAListItemLoading.vue delete mode 100644 app/javascript/dashboard/routes/dashboard/settings/sla/components/SLAResponseTime.vue diff --git a/app/javascript/dashboard/assets/scss/_base.scss b/app/javascript/dashboard/assets/scss/_base.scss index 14ae2a9d4..d3d3f6726 100644 --- a/app/javascript/dashboard/assets/scss/_base.scss +++ b/app/javascript/dashboard/assets/scss/_base.scss @@ -66,7 +66,7 @@ textarea { // Field base styles (Input, TextArea, Select) @layer components { .field-base { - @apply block box-border w-full transition-colors duration-[0.25s] ease-[ease-in-out] focus:outline-n-brand dark:focus:outline-n-brand appearance-none mx-0 mt-0 mb-4 py-2 px-3 rounded-lg text-base font-normal bg-n-alpha-black2 placeholder:text-n-slate-10 dark:placeholder:text-n-slate-10 text-n-slate-12 border-none outline outline-1 outline-n-weak dark:outline-n-weak hover:outline-n-slate-6 dark:hover:outline-n-slate-6; + @apply block box-border w-full transition-colors duration-[0.25s] ease-[ease-in-out] focus:outline-n-brand dark:focus:outline-n-brand appearance-none mx-0 mt-0 mb-4 py-2 px-3 rounded-lg text-sm font-normal bg-n-alpha-black2 placeholder:text-n-slate-10 dark:placeholder:text-n-slate-10 text-n-slate-12 border-none outline outline-1 outline-n-weak dark:outline-n-weak hover:outline-n-slate-6 dark:hover:outline-n-slate-6; } .field-disabled { diff --git a/app/javascript/dashboard/assets/scss/_woot.scss b/app/javascript/dashboard/assets/scss/_woot.scss index 40ca7b436..81a4569b5 100644 --- a/app/javascript/dashboard/assets/scss/_woot.scss +++ b/app/javascript/dashboard/assets/scss/_woot.scss @@ -66,4 +66,84 @@ body { -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ } + + /** + * ============================================================================ + * TYPOGRAPHY UTILITIES + * ============================================================================ + * + * | Class | Use Case | + * |--------------------|----------------------------------------------------| + * | .text-body-main |

, , general body text | + * | .text-body-para |

for paragraphs, larger text blocks | + * | .text-heading-1 |

, page titles, panel headers | + * | .text-heading-2 |

, section headings, card titles | + * | .text-heading-3 |

, card headings, breadcrumbs, subsections | + * | .text-label |