From 17100c110a26b62d4f83f428d98a746b047ed881 Mon Sep 17 00:00:00 2001 From: jasonzli-DEV Date: Thu, 17 Sep 2026 21:10:56 -0400 Subject: [PATCH 1/3] redesign Designify editor --- app/Filament/Pages/Designify.php | 131 +++-- app/Filament/Widgets/PreviewWidget.php | 12 - resources/css/filament/admin/designify.css | 462 ++++++++++++++++++ resources/css/filament/admin/theme.css | 1 + resources/lang/en/admin/settings.php | 20 + resources/scripts/components/App.tsx | 115 ++++- .../scripts/reviactyl/ui/ThemeEngine.tsx | 50 +- resources/views/errors/403.blade.php | 21 +- resources/views/errors/404.blade.php | 21 +- resources/views/errors/500.blade.php | 21 +- .../views/errors/designify-preview.blade.php | 50 ++ .../views/filament/pages/designify.blade.php | 228 ++++++++- .../filament/widgets/preview-widget.blade.php | 85 ---- tests/Unit/Filament/Pages/DesignifyTest.php | 34 ++ 14 files changed, 1052 insertions(+), 199 deletions(-) delete mode 100644 app/Filament/Widgets/PreviewWidget.php create mode 100644 resources/css/filament/admin/designify.css create mode 100644 resources/views/errors/designify-preview.blade.php delete mode 100644 resources/views/filament/widgets/preview-widget.blade.php create mode 100644 tests/Unit/Filament/Pages/DesignifyTest.php diff --git a/app/Filament/Pages/Designify.php b/app/Filament/Pages/Designify.php index 76f1eebcc..4fca87a07 100644 --- a/app/Filament/Pages/Designify.php +++ b/app/Filament/Pages/Designify.php @@ -5,7 +5,6 @@ use App\Contracts\Repository\SettingsRepositoryInterface; use App\Filament\Components\Alert; use App\Filament\Components\ImageInput; -use App\Filament\Widgets\PreviewWidget; use App\Traits\Helpers\AvailableLanguages; use Filament\Actions\Action; use Filament\Forms\Components\ColorPicker; @@ -19,13 +18,13 @@ use Filament\Notifications\Notification; use Filament\Pages\Concerns\InteractsWithHeaderActions; use Filament\Pages\Page; -use Filament\Schemas\Components\Group; use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; use Filament\Schemas\Contracts\HasSchemas; use Illuminate\Contracts\Config\Repository as ConfigRepository; use Illuminate\Contracts\Console\Kernel; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; use Illuminate\Support\HtmlString; use Illuminate\Support\Str; @@ -258,8 +257,10 @@ protected function getFormSchema(): array return [ Tabs::make('settings-tabs') ->disabled(fn (): bool => config('panel.load_environment_only')) + ->live(debounce: 300) ->persistTabInQueryString() ->vertical() + ->extraAttributes(['class' => 'designify-settings-tabs']) ->tabs([ Tab::make('general') ->label(trans('admin/settings.designify.general')) @@ -321,8 +322,10 @@ private function environmentNotice(): array private function generalSettings(): array { return [ - Group::make() - ->columns(2) + Section::make(trans('admin/settings.designify.section-footer')) + ->description(trans('admin/settings.designify.section-footer-description')) + ->icon('tabler-copyright') + ->columns(1) ->schema([ Toggle::make('designify:customCopyright') ->label(trans('admin/settings.designify.custom-copyright')) @@ -336,8 +339,10 @@ private function generalSettings(): array ->columnSpan(1), ]), - Group::make() - ->columns(2) + Section::make(trans('admin/settings.designify.section-maintenance')) + ->description(trans('admin/settings.designify.section-maintenance-description')) + ->icon('tabler-tool') + ->columns(1) ->schema([ Toggle::make('designify:isUnderMaintenance') ->label(trans('admin/settings.designify.maintenance-mode')) @@ -351,8 +356,10 @@ private function generalSettings(): array ->columnSpan(1), ]), - Group::make() - ->columns(2) + Section::make(trans('admin/settings.designify.section-behavior')) + ->description(trans('admin/settings.designify.section-behavior-description')) + ->icon('tabler-adjustments-horizontal') + ->columns(1) ->schema([ Toggle::make('designify:alwaysShowKillButton') ->label(trans('admin/settings.designify.always-show-kill-button')) @@ -376,8 +383,10 @@ private function generalSettings(): array ->columnSpan(1), ]), - Group::make() - ->columns(3) + Section::make(trans('admin/settings.designify.section-destinations')) + ->description(trans('admin/settings.designify.section-destinations-description')) + ->icon('tabler-external-link') + ->columns(1) ->schema([ TextInput::make('designify:statusCardLink') ->label(trans('admin/settings.designify.status-card-link')) @@ -401,7 +410,7 @@ private function colorSettings(): array { return [ Section::make(trans('admin/settings.designify.basic-colors')) - ->columns(4) + ->columns(2) ->icon('tabler-palette') ->schema([ ColorPicker::make('designify:colorPrimary')->label(trans('admin/settings.designify.primary')), @@ -411,7 +420,7 @@ private function colorSettings(): array ]), Section::make(trans('admin/settings.designify.system-colors')) - ->columns(5) + ->columns(2) ->icon('tabler-color-swatch') ->schema([ ColorPicker::make('designify:color50')->label('50'), @@ -440,7 +449,7 @@ private function colorSettings(): array private function themeSection(int $index): Section { return Section::make(trans('admin/settings.designify.theme-section', ['index' => $index])) - ->columns(5) + ->columns(2) ->schema([ TextInput::make("designify:theme{$index}:name") ->label(trans('admin/settings.designify.theme-name')) @@ -468,8 +477,10 @@ private function themeSection(int $index): Section private function lookAndFeelSettings(): array { return [ - Group::make() - ->columns(4) + Section::make(trans('admin/settings.designify.section-navigation')) + ->description(trans('admin/settings.designify.section-navigation-description')) + ->icon('tabler-layout-sidebar') + ->columns(1) ->schema([ Toggle::make('designify:themeSelector') ->label(trans('admin/settings.designify.theme-selector')) @@ -485,10 +496,12 @@ private function lookAndFeelSettings(): array ->label(trans('admin/settings.designify.panel-background')) ->helperText(trans('admin/settings.designify.panel-background-helper')) ->maxLength(255) - ->columnSpan(2), + ->columnSpanFull(), ]), - Group::make() - ->columns(4) + Section::make(trans('admin/settings.designify.section-surface')) + ->description(trans('admin/settings.designify.section-surface-description')) + ->icon('tabler-brush') + ->columns(1) ->schema([ Toggle::make('designify:allocationBlur') ->label(trans('admin/settings.designify.allocation-blur')) @@ -514,7 +527,7 @@ private function lookAndFeelSettings(): array ]) ->searchable() ->native(false) - ->columnSpan(2), + ->columnSpanFull(), ]), ]; } @@ -522,7 +535,9 @@ private function lookAndFeelSettings(): array private function layoutSettings(): array { return [ - Group::make() + Section::make(trans('admin/settings.designify.section-layout')) + ->description(trans('admin/settings.designify.section-layout-description')) + ->icon('tabler-layout-dashboard') ->columns(1) ->schema([ ToggleButtons::make('designify:cardType') @@ -537,7 +552,7 @@ private function layoutSettings(): array 'row' => trans('admin/settings.designify.row'), ]) ->required() - ->columnSpan(2), + ->columnSpanFull(), ToggleButtons::make('designify:layoutType') ->label(trans('admin/settings.designify.navbar-sidebar-layout')) ->inline() @@ -554,7 +569,7 @@ private function layoutSettings(): array 'accent' => trans('admin/settings.designify.accent'), ]) ->required() - ->columnSpan(2), + ->columnSpanFull(), ]), ]; } @@ -562,7 +577,9 @@ private function layoutSettings(): array private function alertSettings(): array { return [ - Group::make() + Section::make(trans('admin/settings.designify.section-alerts')) + ->description(trans('admin/settings.designify.section-alerts-description')) + ->icon('tabler-bell') ->schema([ Repeater::make('designify:alerts') ->label(trans('admin/settings.designify.alert-messages')) @@ -597,8 +614,10 @@ private function alertSettings(): array private function siteSettings(): array { return [ - Group::make() - ->columns(2) + Section::make(trans('admin/settings.designify.section-identity')) + ->description(trans('admin/settings.designify.section-identity-description')) + ->icon('tabler-world-www') + ->columns(1) ->schema([ TextInput::make('designify:site_title') ->label(trans('admin/settings.designify.site-title')) @@ -636,7 +655,7 @@ private function errorSettings(): array { return [ Section::make(trans('admin/settings.designify.error-404')) - ->columns(2) + ->columns(1) ->iconColor('warning') ->icon('tabler-device-imac-exclamation') ->schema([ @@ -652,11 +671,15 @@ private function errorSettings(): array ->label(trans('admin/settings.designify.message')) ->rows(3) ->required() - ->columnSpan(2), + ->columnSpanFull(), + ImageInput::make('designify:errors:404:image') + ->label(trans('admin/settings.designify.site-image')), + ColorPicker::make('designify:errors:404:color') + ->label(trans('admin/settings.designify.site-color')), ]), Section::make(trans('admin/settings.designify.error-403')) - ->columns(2) + ->columns(1) ->icon('tabler-device-imac-exclamation') ->iconColor('primary') ->schema([ @@ -672,13 +695,17 @@ private function errorSettings(): array ->label(trans('admin/settings.designify.message')) ->rows(3) ->required() - ->columnSpan(2), + ->columnSpanFull(), + ImageInput::make('designify:errors:403:image') + ->label(trans('admin/settings.designify.site-image')), + ColorPicker::make('designify:errors:403:color') + ->label(trans('admin/settings.designify.site-color')), ]), Section::make(trans('admin/settings.designify.error-500')) ->iconColor('danger') ->icon('tabler-device-imac-exclamation') - ->columns(2) + ->columns(1) ->schema([ TextInput::make('designify:errors:500:title') ->label(trans('admin/settings.designify.title')) @@ -692,7 +719,11 @@ private function errorSettings(): array ->label(trans('admin/settings.designify.message')) ->rows(3) ->required() - ->columnSpan(2), + ->columnSpanFull(), + ImageInput::make('designify:errors:500:image') + ->label(trans('admin/settings.designify.site-image')), + ColorPicker::make('designify:errors:500:color') + ->label(trans('admin/settings.designify.site-color')), ]), ]; } @@ -700,7 +731,9 @@ private function errorSettings(): array private function sidebarSettings(): array { return [ - Group::make() + Section::make(trans('admin/settings.designify.section-sidebar-links')) + ->description(trans('admin/settings.designify.section-sidebar-links-description')) + ->icon('tabler-link-plus') ->schema([ Repeater::make('designify:sidebarButtons') ->label(trans('admin/settings.designify.sidebar-links')) @@ -720,7 +753,7 @@ private function sidebarSettings(): array ->label(trans('admin/settings.designify.open-in-new-tab')) ->inline(false), ]) - ->columns(3) + ->columns(1) ->addActionLabel(trans('admin/settings.designify.add-link')) ->columnSpanFull(), ]), @@ -732,6 +765,26 @@ protected function getFormStatePath(): ?string return 'data'; } + public function updatedData(): void + { + $this->dispatch('designify-preview-updated', settings: $this->getPreviewSettings()); + } + + public function getPreviewSettings(): array + { + $preview = []; + + foreach ($this->data ?? [] as $key => $value) { + if (! is_string($key) || ! str_starts_with($key, 'designify:')) { + continue; + } + + Arr::set($preview, str_replace(':', '.', Str::after($key, 'designify:')), $value); + } + + return $preview; + } + public function save(): void { if (config('panel.load_environment_only')) { @@ -766,6 +819,7 @@ public function save(): void ->send(); $this->dispatch('$refresh'); + $this->dispatch('designify-saved', settings: $this->getPreviewSettings()); $this->js("window.dispatchEvent(new CustomEvent('reload-iframe'))"); } @@ -791,9 +845,11 @@ public function resetToDefaults(): void $this->dispatch('$refresh'); + $this->dispatch('designify-reset'); + // We have to reload the window after resetting designify settings. // Please open PR if there's another way without running js code. - $this->js('window.location.reload()'); + $this->js('window.__designifySkipBeforeUnload = true; window.location.reload()'); } protected function getHeaderActions(): array @@ -817,11 +873,4 @@ protected function getHeaderActions(): array ->action(fn () => $this->resetToDefaults()), ]; } - - protected function getFooterWidgets(): array - { - return [ - PreviewWidget::class, - ]; - } } diff --git a/app/Filament/Widgets/PreviewWidget.php b/app/Filament/Widgets/PreviewWidget.php deleted file mode 100644 index 9964f7e40..000000000 --- a/app/Filament/Widgets/PreviewWidget.php +++ /dev/null @@ -1,12 +0,0 @@ - div, +.designify-editor__controls-form > .fi-sc > .fi-grid-col, +.designify-editor__controls-form > .fi-sc > .fi-grid-col > .fi-sc-component, +.designify-editor__controls-form .fi-sc-tabs { + height: 100%; + min-height: 0; +} + +.designify-editor__controls-form, +.designify-editor__controls-form > .fi-sc, +.designify-editor__controls-form > .fi-sc > .fi-grid-col, +.designify-editor__controls-form > .fi-sc > .fi-grid-col > .fi-sc-component { + overflow: hidden; +} + +.designify-editor__controls-form .fi-sc-tabs-tab { + min-height: 0; + overflow-y: auto; + overscroll-behavior: contain; +} + +.designify-editor__controls-form .fi-sc-tabs { + display: grid; + grid-template-columns: var(--designify-nav-width) minmax(0, 1fr); + grid-template-rows: minmax(0, 1fr); + gap: 0; + max-height: 100%; + overflow: hidden; + border: 0; + border-radius: 0; + background: transparent; + box-shadow: none; +} + +.designify-editor__controls-form .fi-sc-tabs > .fi-tabs { + width: auto; + min-width: 0; + overflow-y: auto; + padding: 0.75rem 0.625rem; + border-right: 1px solid var(--designify-border); + border-radius: 0; + background: var(--designify-surface-subtle); + box-shadow: none; +} + +.designify-editor__controls-form .fi-tabs-item { + width: 100%; + min-height: 2.5rem; + justify-content: flex-start; + border-radius: 0.5rem; + color: var(--designify-muted); +} + +.designify-editor__controls-form .fi-tabs-item:hover { + background: color-mix(in srgb, var(--gray-500) 10%, transparent); + color: var(--designify-text); +} + +.designify-editor__controls-form .fi-tabs-item.fi-active { + background: color-mix(in srgb, var(--primary-600) 11%, transparent); + color: var(--primary-700); +} + +.dark .designify-editor__controls-form .fi-tabs-item.fi-active { + color: var(--primary-400); +} + +.designify-editor__controls-form .fi-sc-tabs > .fi-sc-tabs-tab.fi-active { + min-width: 0; + margin: 0; + overflow-y: auto; + padding: 0; + scrollbar-gutter: stable; +} + +.designify-editor__controls-form .fi-sc-tabs-tab > .fi-sc { + gap: 0; +} + +.designify-editor__controls-form .fi-section { + border: 0; + border-bottom: 1px solid var(--designify-border); + border-radius: 0; + background: transparent; + box-shadow: none; +} + +.designify-editor__controls-form .fi-section-header { + padding: 1.25rem 1.25rem 0.75rem; +} + +.designify-editor__controls-form .fi-section-content-ctn { + border-top: 0; +} + +.designify-editor__controls-form .fi-section-content { + padding: 0 1.25rem 1.25rem; +} + +.designify-editor__controls-form .fi-section-description { + color: var(--designify-muted); + line-height: 1.45; +} + +.designify-editor__controls-form .fi-fo-repeater-item { + box-shadow: none; +} + +.designify-editor__preview { + display: grid; + grid-template-rows: 3.5rem minmax(0, 1fr); + overflow: hidden; + background: var(--designify-canvas); +} + +.designify-editor__preview-bar { + display: flex; + align-items: center; + min-width: 0; + padding: 0.625rem 0.875rem; + border-bottom: 1px solid var(--designify-border); + background: var(--designify-surface); +} + +.designify-editor__preview-tools { + min-width: 0; + justify-content: space-between; + flex: 1; + gap: 0.75rem; +} + +.designify-editor__device-switcher, +.designify-editor__page-switcher, +.designify-editor__mobile-switcher { + gap: 0.125rem; + padding: 0.1875rem; + border: 1px solid var(--designify-border); + border-radius: 0.5rem; + background: var(--designify-surface-subtle); +} + +.designify-editor__tool-button { + display: inline-flex; + min-height: 2rem; + align-items: center; + justify-content: center; + gap: 0.4rem; + padding: 0.375rem 0.625rem; + border-radius: 0.375rem; + color: var(--designify-muted); + font-size: 0.75rem; + font-weight: 550; + transition: + background-color 180ms cubic-bezier(0.22, 1, 0.36, 1), + color 180ms cubic-bezier(0.22, 1, 0.36, 1), + box-shadow 180ms cubic-bezier(0.22, 1, 0.36, 1); +} + +.designify-editor__tool-button:hover:not(:disabled) { + background: color-mix(in srgb, var(--gray-500) 12%, transparent); + color: var(--designify-text); +} + +.designify-editor__tool-button:disabled { + cursor: not-allowed; + opacity: 0.45; +} + +.designify-editor__tool-button[aria-pressed='true'] { + background: var(--designify-surface); + color: var(--designify-text); + box-shadow: 0 1px 2px color-mix(in srgb, var(--gray-950) 12%, transparent); +} + +.dark .designify-editor__tool-button[aria-pressed='true'] { + background: var(--gray-800); +} + +.designify-editor__tool-button svg { + width: 1rem; + height: 1rem; +} + +.designify-editor__canvas { + display: grid; + min-width: 0; + min-height: 0; + place-items: center; + overflow: auto; + padding: 1.5rem; + background-color: var(--designify-canvas); + background-image: + linear-gradient(var(--designify-border) 1px, transparent 1px), + linear-gradient(90deg, var(--designify-border) 1px, transparent 1px); + background-size: 2rem 2rem; +} + +.designify-editor__frame-shell { + width: 100%; + height: 100%; + max-height: 100%; + overflow: hidden; + border: 1px solid var(--designify-border-strong); + border-radius: 0.75rem; + background: var(--gray-950); + box-shadow: 0 1rem 3rem color-mix(in srgb, var(--gray-950) 18%, transparent); + transition: + width 220ms cubic-bezier(0.22, 1, 0.36, 1), + height 220ms cubic-bezier(0.22, 1, 0.36, 1), + border-radius 220ms cubic-bezier(0.22, 1, 0.36, 1); +} + +.designify-editor__frame-shell[data-viewport='tablet'] { + width: min(48rem, 100%); +} + +.designify-editor__frame-shell[data-viewport='mobile'] { + width: min(24rem, 100%); + border-radius: 1.25rem; +} + +.designify-editor__frame { + width: 100%; + height: 100%; + border: 0; + background: var(--gray-950); +} + +.designify-editor__mobile-switcher { + display: none; +} + +@media (max-width: 70rem) { + .designify-editor__workspace { + display: block; + position: relative; + } + + .designify-editor__panel { + position: absolute; + inset: 0; + } + + .designify-editor__controls { + border-right: 0; + } + + .designify-editor__mobile-switcher { + display: flex; + } + + .designify-editor__save-state { + display: none; + } +} + +@media (max-width: 42rem) { + .designify-editor__header { + padding-inline: 0.625rem; + } + + .designify-editor__brand-copy, + .designify-editor__actions > [data-secondary-action='true'] { + display: none; + } + + .designify-editor__controls-form .fi-sc-tabs { + grid-template-columns: 1fr; + grid-template-rows: auto minmax(0, 1fr); + } + + .designify-editor__controls-form .fi-sc-tabs > .fi-tabs { + flex-direction: row; + width: 100%; + overflow-x: auto; + overflow-y: hidden; + border-right: 0; + border-bottom: 1px solid var(--designify-border); + } + + .designify-editor__controls-form .fi-tabs-item { + width: auto; + flex: 0 0 auto; + } + + .designify-editor__preview-bar { + overflow-x: auto; + } + + .designify-editor__device-switcher .designify-editor__tool-button span, + .designify-editor__page-switcher .designify-editor__tool-button span { + display: none; + } + + .designify-editor__canvas { + padding: 0.75rem; + } +} + +@media (prefers-reduced-motion: reduce) { + .designify-editor__back, + .designify-editor__tool-button, + .designify-editor__frame-shell { + transition-duration: 0.01ms; + } +} diff --git a/resources/css/filament/admin/theme.css b/resources/css/filament/admin/theme.css index 506739a6e..8f9010264 100644 --- a/resources/css/filament/admin/theme.css +++ b/resources/css/filament/admin/theme.css @@ -1,4 +1,5 @@ @import '../../../../vendor/filament/filament/resources/css/theme.css'; +@import './designify.css'; @source '../../../../app/Filament/**/*'; @source '../../../../resources/views/filament/**/*'; diff --git a/resources/lang/en/admin/settings.php b/resources/lang/en/admin/settings.php index 794c1a2cf..24831f9bf 100644 --- a/resources/lang/en/admin/settings.php +++ b/resources/lang/en/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'Open in New Tab', 'add-link' => 'Add Link', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Reset to Defaults', 'reset-designify' => 'Reset Designify?', 'reset-description' => 'This will remove all saved Designify overrides and restore the default configuration.', diff --git a/resources/scripts/components/App.tsx b/resources/scripts/components/App.tsx index 7678c6b1c..74eb47471 100644 --- a/resources/scripts/components/App.tsx +++ b/resources/scripts/components/App.tsx @@ -1,4 +1,4 @@ -import { lazy } from 'react'; +import { lazy, useEffect } from 'react'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; import { StoreProvider } from 'easy-peasy'; import { store } from '@/state'; @@ -10,7 +10,7 @@ import AuthenticatedRoute from '@/reviactyl/elements/AuthenticatedRoute'; import { ServerContext } from '@/state/server'; import '@/assets/tailwind.css'; import Spinner from '@/reviactyl/elements/Spinner'; -import { ThemeLoader } from '@/reviactyl/ui/ThemeEngine'; +import { refreshSelectedTheme, ThemeLoader } from '@/reviactyl/ui/ThemeEngine'; import { Invert } from '@/reviactyl/ui/SmartInvert'; import { LocaleLoader } from '@/reviactyl/ui/LanguageSwitcher'; import { SubuserPreviewProvider } from '@/context/SubuserPreviewContext'; @@ -41,6 +41,109 @@ interface ExtendedWindow extends Window { }; } +const previewColorKeys = [ + 'colorPrimary', + 'colorSuccess', + 'colorDanger', + 'colorSecondary', + 'color50', + 'color100', + 'color200', + 'color300', + 'color400', + 'color500', + 'color600', + 'color700', + 'color800', + 'color900', + 'color950', +] as const; + +const toRgbChannels = (hex: string): string | null => { + const match = hex.match(/^#([\da-f]{3}|[\da-f]{6})$/i); + if (!match) return null; + + const matchedHex = match[1]; + if (!matchedHex) return null; + + const value = matchedHex.length === 3 ? matchedHex.replace(/(.)/g, '$1$1') : matchedHex; + const number = Number.parseInt(value, 16); + + return `${(number >> 16) & 255} ${(number >> 8) & 255} ${number & 255}`; +}; + +const DesignifyPreviewBridge = () => { + useEffect(() => { + if (window.self === window.top) return; + + const handlePreviewUpdate = (event: MessageEvent) => { + if (event.origin !== window.location.origin || event.source !== window.parent) return; + if (event.data?.type !== 'reviactyl:designify-preview' || !event.data.settings) return; + + const settings = event.data.settings as DesignifySettings & Record; + const existingSettings = (window.PanelConfiguration ?? {}) as DesignifySettings & Record; + const nextSettings = { ...existingSettings, ...settings } as DesignifySettings & Record; + + for (let index = 1; index <= 7; index += 1) { + const key = `theme${index}`; + const existingTheme = existingSettings[key]; + const incomingTheme = settings[key]; + if (typeof incomingTheme === 'object' && incomingTheme !== null && !Array.isArray(incomingTheme)) { + nextSettings[key] = { + ...(typeof existingTheme === 'object' && existingTheme !== null && !Array.isArray(existingTheme) + ? existingTheme + : {}), + ...incomingTheme, + }; + } + } + + window.PanelConfiguration = nextSettings; + store.getActions().designify.setDesignify(nextSettings); + + const root = document.documentElement; + previewColorKeys.forEach((key) => { + const value = settings[key]; + const channels = typeof value === 'string' ? toRgbChannels(value) : null; + const property = `--color-${key.replace('color', '').toLowerCase()}`; + if (channels) { + root.style.setProperty(property, channels); + } else { + root.style.removeProperty(property); + } + }); + + if (settings.background === 'none') { + root.style.setProperty('--background', 'none'); + } else if (typeof settings.background === 'string' && settings.background.length > 0) { + root.style.setProperty('--background', `url(${JSON.stringify(settings.background)})`); + } else { + root.style.removeProperty('--background'); + } + if (typeof settings.radius === 'string' && CSS.supports('border-radius', settings.radius)) { + root.style.setProperty('--radius', settings.radius); + } else { + root.style.removeProperty('--radius'); + } + if (typeof settings.fontFamily === 'string' && settings.fontFamily.length > 0) { + root.style.setProperty('--font-family', `"${settings.fontFamily.replaceAll('+', ' ')}", sans-serif`); + } else { + root.style.removeProperty('--font-family'); + } + + refreshSelectedTheme(); + window.dispatchEvent(new Event('reviactyl:designify-config-updated')); + }; + + window.addEventListener('message', handlePreviewUpdate); + window.parent.postMessage({ type: 'reviactyl:designify-preview-ready' }, window.location.origin); + + return () => window.removeEventListener('message', handlePreviewUpdate); + }, []); + + return null; +}; + /** * Renders the application shell, global providers, and route tree. * @@ -78,16 +181,12 @@ function App() { return ( +
- + diff --git a/resources/scripts/reviactyl/ui/ThemeEngine.tsx b/resources/scripts/reviactyl/ui/ThemeEngine.tsx index cc1460591..2297762c8 100644 --- a/resources/scripts/reviactyl/ui/ThemeEngine.tsx +++ b/resources/scripts/reviactyl/ui/ThemeEngine.tsx @@ -85,6 +85,13 @@ const applyTheme = (colors: ThemeData) => { }); }; +export const refreshSelectedTheme = () => { + const themeName = getCookie('theme'); + if (themeName && paletteKeys.includes(themeName as PaletteKey)) { + applyTheme(getThemeFromConfig(themeName as PaletteKey)); + } +}; + const clearTheme = () => { if (typeof document === 'undefined') return; const root = document.documentElement; @@ -103,20 +110,29 @@ const ThemeSelector = () => { useEffect(() => { if (typeof window === 'undefined') return; - const loadedThemes: Record = {} as any; - for (const key of paletteKeys) { - loadedThemes[key] = getThemeFromConfig(key); - } - setThemes(loadedThemes); - - const saved = getCookie('theme'); - if (saved && paletteKeys.includes(saved as PaletteKey)) { - applyTheme(loadedThemes[saved as PaletteKey]); - setSelected(saved as PaletteKey); - } else { - clearTheme(); - setSelected('default'); - } + const loadThemes = (preserveBaseColors = false) => { + const loadedThemes: Record = {} as any; + for (const key of paletteKeys) { + loadedThemes[key] = getThemeFromConfig(key); + } + setThemes(loadedThemes); + + const saved = getCookie('theme'); + if (saved && paletteKeys.includes(saved as PaletteKey)) { + applyTheme(loadedThemes[saved as PaletteKey]); + setSelected(saved as PaletteKey); + } else { + if (!preserveBaseColors) clearTheme(); + setSelected('default'); + } + }; + + const handleConfigUpdate = () => loadThemes(true); + + loadThemes(); + window.addEventListener('reviactyl:designify-config-updated', handleConfigUpdate); + + return () => window.removeEventListener('reviactyl:designify-config-updated', handleConfigUpdate); }, []); const handleThemeChange = (theme: 'default' | PaletteKey) => { @@ -174,11 +190,7 @@ export const ThemeLoader = () => { useEffect(() => { if (typeof window === 'undefined') return; - const themeName = getCookie('theme'); - if (themeName && paletteKeys.includes(themeName as PaletteKey)) { - const theme = getThemeFromConfig(themeName as PaletteKey); - applyTheme(theme); - } + refreshSelectedTheme(); }, []); return null; diff --git a/resources/views/errors/403.blade.php b/resources/views/errors/403.blade.php index a950004c0..7134ec878 100644 --- a/resources/views/errors/403.blade.php +++ b/resources/views/errors/403.blade.php @@ -8,33 +8,32 @@
- @if(config('designify.errors.403.image')) - 403 - @else -
403
- @endif + 403 +
403
-

+

{{ config('designify.errors.403.title') ?? 'Access Forbidden' }}

-

+

{{ config('designify.errors.403.message') ?? 'You do not have permission to access this resource. Please contact the administrator if you believe this is an error.' }}

+ @include('errors.designify-preview', ['status' => 403]) diff --git a/resources/views/errors/404.blade.php b/resources/views/errors/404.blade.php index 03c79e2d8..338bb7f88 100644 --- a/resources/views/errors/404.blade.php +++ b/resources/views/errors/404.blade.php @@ -8,33 +8,32 @@
- @if(config('designify.errors.404.image')) - 404 - @else -
404
- @endif + 404 +
404
-

+

{{ config('designify.errors.404.title') ?? 'Page Not Found' }}

-

+

{{ config('designify.errors.404.message') ?? 'The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.' }}

+ @include('errors.designify-preview', ['status' => 404]) diff --git a/resources/views/errors/500.blade.php b/resources/views/errors/500.blade.php index ce3279172..8c5997561 100644 --- a/resources/views/errors/500.blade.php +++ b/resources/views/errors/500.blade.php @@ -8,33 +8,32 @@
- @if(config('designify.errors.500.image')) - 500 - @else -
500
- @endif + 500 +
500
-

+

{{ config('designify.errors.500.title') ?? 'Internal Server Error' }}

-

+

{{ config('designify.errors.500.message') ?? 'We encountered an error while processing your request. Please try again later or contact support if the problem persists.' }}

+ @include('errors.designify-preview', ['status' => 500]) diff --git a/resources/views/errors/designify-preview.blade.php b/resources/views/errors/designify-preview.blade.php new file mode 100644 index 000000000..f98c94f3b --- /dev/null +++ b/resources/views/errors/designify-preview.blade.php @@ -0,0 +1,50 @@ +@if (request()->is('preview/*')) + +@endif diff --git a/resources/views/filament/pages/designify.blade.php b/resources/views/filament/pages/designify.blade.php index 6d969da60..b793264fc 100644 --- a/resources/views/filament/pages/designify.blade.php +++ b/resources/views/filament/pages/designify.blade.php @@ -1,3 +1,229 @@ - {{ $this->form }} +
+
+
+ + + +
+

Designify

+
+
+ +
+ + +
+ +
+ + + + + + Reset + + + Save changes + Saving… + +
+
+ +
+ + +
+
+
+
+ + @foreach ([403, 404, 500] as $status) + + @endforeach + + +
+ +
+ + + +
+
+
+ +
+
+ +
+
+ +
+
+
diff --git a/resources/views/filament/widgets/preview-widget.blade.php b/resources/views/filament/widgets/preview-widget.blade.php deleted file mode 100644 index a64acdc65..000000000 --- a/resources/views/filament/widgets/preview-widget.blade.php +++ /dev/null @@ -1,85 +0,0 @@ - - -
-
- - - Home - - - - - 404 - - - - - 403 - - - - - 500 - - -
-
- -
-
-
-
diff --git a/tests/Unit/Filament/Pages/DesignifyTest.php b/tests/Unit/Filament/Pages/DesignifyTest.php new file mode 100644 index 000000000..87d93781e --- /dev/null +++ b/tests/Unit/Filament/Pages/DesignifyTest.php @@ -0,0 +1,34 @@ +data = [ + 'designify:colorPrimary' => '#2563eb', + 'designify:theme1:name' => 'Ocean', + 'designify:theme1:colorPrimary' => '#0ea5e9', + 'designify:errors:404:title' => 'Lost in space', + 'designify:alerts' => [['type' => 'info', 'message' => 'Hello']], + 'unrelated' => 'ignored', + ]; + + $this->assertSame([ + 'colorPrimary' => '#2563eb', + 'theme1' => [ + 'name' => 'Ocean', + 'colorPrimary' => '#0ea5e9', + ], + 'errors' => [ + '404' => ['title' => 'Lost in space'], + ], + 'alerts' => [['type' => 'info', 'message' => 'Hello']], + ], $page->getPreviewSettings()); + } +} From c6c5aa031092685f1d6921adc0adb33af59f7f65 Mon Sep 17 00:00:00 2001 From: jasonzli-DEV Date: Thu, 17 Sep 2026 21:12:12 -0400 Subject: [PATCH 2/3] add translation files --- resources/lang/ar/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/bn/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/de/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/es/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/fr/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/hi/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/id/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/kn/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/pt/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/ru/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/sv/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/tr/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/vi/admin/settings.php | 20 ++++++++++++++++++++ resources/lang/zh/admin/settings.php | 20 ++++++++++++++++++++ 14 files changed, 280 insertions(+) diff --git a/resources/lang/ar/admin/settings.php b/resources/lang/ar/admin/settings.php index 3cf16c183..5bafd2e86 100644 --- a/resources/lang/ar/admin/settings.php +++ b/resources/lang/ar/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'عنوان URL', 'open-in-new-tab' => 'افتح في علامة تبويب جديدة', 'add-link' => 'إضافة رابط', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'إعادة التعيين إلى الإعدادات الافتراضية', 'reset-designify' => 'إعادة تعيين التصميم؟', 'reset-description' => 'سيؤدي هذا إلى إزالة جميع تجاوزات Designify المحفوظة واستعادة التكوين الافتراضي.', diff --git a/resources/lang/bn/admin/settings.php b/resources/lang/bn/admin/settings.php index 4d06eb258..d17edfa4f 100644 --- a/resources/lang/bn/admin/settings.php +++ b/resources/lang/bn/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'নতুন ট্যাবে খুলুন', 'add-link' => 'লিংক যোগ করুন', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'ডিফল্টে রিসেট করুন', 'reset-designify' => 'Designify রিসেট করবেন?', 'reset-description' => 'এটি সমস্ত সংরক্ষিত Designify override মুছে দিয়ে ডিফল্ট কনফিগারেশন পুনরুদ্ধার করবে।', diff --git a/resources/lang/de/admin/settings.php b/resources/lang/de/admin/settings.php index 7eafcb746..baca56f36 100644 --- a/resources/lang/de/admin/settings.php +++ b/resources/lang/de/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'In neuem Tab öffnen', 'add-link' => 'Link hinzufügen', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Auf Standardeinstellungen zurücksetzen', 'reset-designify' => 'Designify zurücksetzen?', 'reset-description' => 'Dadurch werden alle gespeicherten Designify-Überschreibungen entfernt und die Standardkonfiguration wiederhergestellt.', diff --git a/resources/lang/es/admin/settings.php b/resources/lang/es/admin/settings.php index a0eeed4bd..262e31387 100644 --- a/resources/lang/es/admin/settings.php +++ b/resources/lang/es/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'Abrir en nueva pestaña', 'add-link' => 'Agregar enlace', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Restablecer los valores predeterminados', 'reset-designify' => '¿Reiniciar Designify?', 'reset-description' => 'Esto eliminará todas las anulaciones de Designify guardadas y restaurará la configuración predeterminada.', diff --git a/resources/lang/fr/admin/settings.php b/resources/lang/fr/admin/settings.php index 2aaea2c84..ad2f54cc4 100644 --- a/resources/lang/fr/admin/settings.php +++ b/resources/lang/fr/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'Ouvrir dans un nouvel onglet', 'add-link' => 'Ajouter un lien', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Réinitialiser aux valeurs par défaut', 'reset-designify' => 'Réinitialiser Designify ?', 'reset-description' => 'Cela supprimera tous les remplacements Designify enregistrés et restaurera la configuration par défaut.', diff --git a/resources/lang/hi/admin/settings.php b/resources/lang/hi/admin/settings.php index 371e4088f..2b2859ddf 100644 --- a/resources/lang/hi/admin/settings.php +++ b/resources/lang/hi/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'यूआरएल', 'open-in-new-tab' => 'वेब टेब में खोलें', 'add-link' => 'लिंक जोड़ें', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'डिफ़ॉल्ट पर पुनः सेट करें', 'reset-designify' => 'डिज़ाइन रीसेट करें?', 'reset-description' => 'यह सभी सहेजे गए डिज़ाइन ओवरराइड को हटा देगा और डिफ़ॉल्ट कॉन्फ़िगरेशन को पुनर्स्थापित करेगा।', diff --git a/resources/lang/id/admin/settings.php b/resources/lang/id/admin/settings.php index 89ca6ba73..dba7fe46a 100644 --- a/resources/lang/id/admin/settings.php +++ b/resources/lang/id/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'Buka di Tab Baru', 'add-link' => 'Tambahkan Tautan', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Atur Ulang ke Default', 'reset-designify' => 'Setel Ulang Desain?', 'reset-description' => 'Ini akan menghapus semua penggantian Designify yang disimpan dan memulihkan konfigurasi default.', diff --git a/resources/lang/kn/admin/settings.php b/resources/lang/kn/admin/settings.php index cbc9ef4bf..8f730529f 100644 --- a/resources/lang/kn/admin/settings.php +++ b/resources/lang/kn/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'ಹೊಸ ಟ್ಯಾಬ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ', 'add-link' => 'ಲಿಂಕ್ ಸೇರಿಸಿ', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'ಡೀಫಾಲ್ಟ್‌ಗಳಿಗೆ ಮರುಹೊಂದಿಸಿ', 'reset-designify' => 'ವಿನ್ಯಾಸವನ್ನು ಮರುಹೊಂದಿಸುವುದೇ?', 'reset-description' => 'ಇದು ಎಲ್ಲಾ ಉಳಿಸಿದ Designify ಅತಿಕ್ರಮಣಗಳನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ ಮತ್ತು ಡೀಫಾಲ್ಟ್ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಮರುಸ್ಥಾಪಿಸುತ್ತದೆ.', diff --git a/resources/lang/pt/admin/settings.php b/resources/lang/pt/admin/settings.php index e2f1c83d3..b424884f1 100644 --- a/resources/lang/pt/admin/settings.php +++ b/resources/lang/pt/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'Abrir em nova guia', 'add-link' => 'Adicionar link', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Redefinir para os padrões', 'reset-designify' => 'Redefinir Designify?', 'reset-description' => 'Isso removerá todas as substituições salvas do Designify e restaurará a configuração padrão.', diff --git a/resources/lang/ru/admin/settings.php b/resources/lang/ru/admin/settings.php index b3ffe6809..c894c248d 100644 --- a/resources/lang/ru/admin/settings.php +++ b/resources/lang/ru/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'Открывать в новой вкладке', 'add-link' => 'Добавить ссылку', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Сбросить настройки', 'reset-designify' => 'Сбросить Designify?', 'reset-description' => 'Это удалит все сохранённые переопределения Designify и восстановит конфигурацию по умолчанию.', diff --git a/resources/lang/sv/admin/settings.php b/resources/lang/sv/admin/settings.php index 48364a031..73214a2b1 100644 --- a/resources/lang/sv/admin/settings.php +++ b/resources/lang/sv/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'Öppna i Ny flik', 'add-link' => 'Lägg till länk', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Återställ till standardinställningar', 'reset-designify' => 'Återställa Designify?', 'reset-description' => 'Detta kommer att ta bort alla sparade Designify-åsidosättningar och återställa standardkonfigurationen.', diff --git a/resources/lang/tr/admin/settings.php b/resources/lang/tr/admin/settings.php index d5e91459d..86e9e5392 100644 --- a/resources/lang/tr/admin/settings.php +++ b/resources/lang/tr/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL\'si', 'open-in-new-tab' => 'Yeni Sekmede Aç', 'add-link' => 'Bağlantı Ekle', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Varsayılanlara Sıfırla', 'reset-designify' => 'Designify sıfırlansın mı?', 'reset-description' => 'Bu, kayıtlı tüm Designify geçersiz kılmalarını kaldıracak ve varsayılan yapılandırmayı geri yükleyecektir.', diff --git a/resources/lang/vi/admin/settings.php b/resources/lang/vi/admin/settings.php index 930e80056..4a3649c2e 100644 --- a/resources/lang/vi/admin/settings.php +++ b/resources/lang/vi/admin/settings.php @@ -158,6 +158,26 @@ 'url' => 'URL', 'open-in-new-tab' => 'Mở trong tab mới', 'add-link' => 'Thêm liên kết', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => 'Đặt lại về mặc định', 'reset-designify' => 'Đặt lại Chỉ định?', 'reset-description' => 'Thao tác này sẽ xóa tất cả các phần ghi đè Designify đã lưu và khôi phục cấu hình mặc định.', diff --git a/resources/lang/zh/admin/settings.php b/resources/lang/zh/admin/settings.php index 74663d6c2..337fae0e3 100644 --- a/resources/lang/zh/admin/settings.php +++ b/resources/lang/zh/admin/settings.php @@ -158,6 +158,26 @@ 'url' => '网址', 'open-in-new-tab' => '在新选项卡中打开', 'add-link' => '添加链接', + 'section-footer' => 'Footer', + 'section-footer-description' => 'Set the ownership message shown at the bottom of the panel.', + 'section-maintenance' => 'Maintenance Notice', + 'section-maintenance-description' => 'Prepare the message users see while the panel is unavailable.', + 'section-behavior' => 'Panel Behavior', + 'section-behavior-description' => 'Choose defaults that affect how users interact with the panel.', + 'section-destinations' => 'Dashboard Destinations', + 'section-destinations-description' => 'Connect dashboard cards to your status, support, and billing pages.', + 'section-navigation' => 'Navigation', + 'section-navigation-description' => 'Choose which navigation tools are available to users.', + 'section-surface' => 'Surface and Type', + 'section-surface-description' => 'Set the background, corner radius, and interface typeface.', + 'section-layout' => 'Interface Layout', + 'section-layout-description' => 'Choose the server card and navigation structures shown in the panel.', + 'section-alerts' => 'Panel Alerts', + 'section-alerts-description' => 'Create the messages users see at the top of their dashboard.', + 'section-identity' => 'Public Identity', + 'section-identity-description' => 'Define the title, description, imagery, and color used when the panel is shared.', + 'section-sidebar-links' => 'Custom Links', + 'section-sidebar-links-description' => 'Add destinations to the panel sidebar without changing application code.', 'reset-to-defaults' => '重置为默认值', 'reset-designify' => '重置设计?', 'reset-description' => '这将删除所有保存的 Designify 覆盖并恢复默认配置。', From 00668956ff236ee9e1ab3424fa5e38cbc5e53f33 Mon Sep 17 00:00:00 2001 From: jasonzli-DEV Date: Mon, 21 Sep 2026 09:28:44 -0400 Subject: [PATCH 3/3] fix error page preview resets --- resources/views/filament/pages/designify.blade.php | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/views/filament/pages/designify.blade.php b/resources/views/filament/pages/designify.blade.php index 928b9879d..4e138e40d 100644 --- a/resources/views/filament/pages/designify.blade.php +++ b/resources/views/filament/pages/designify.blade.php @@ -214,6 +214,7 @@ class="designify-editor__tool-button"