feat: customizable portal gradient theme + LTC repair form fixes
- Add portal gradient branding settings with 4 presets (Green/Teal, Blue/Purple, Sunset Orange, Dark Slate) and custom color picker - Live preview in settings, onchange updates colors reactively - Dynamic gradient applied across portal home, CSS, and card elements - Fix after photos visibility (conditional on resolved=yes) - Fix technician section gating on portal repair form - Move Create Sale Order button to form header for visibility - Fix portal home row width inconsistency (xpath target change) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -487,6 +487,80 @@ class ResConfigSettings(models.TransientModel):
|
||||
help='Minimum 4 characters. Share with facility staff to access the repair form.',
|
||||
)
|
||||
|
||||
# =========================================================================
|
||||
# PORTAL BRANDING
|
||||
# =========================================================================
|
||||
|
||||
fc_portal_gradient_preset = fields.Selection([
|
||||
('green_teal', 'Green to Teal (Default)'),
|
||||
('blue_purple', 'Blue to Purple'),
|
||||
('orange_red', 'Sunset Orange'),
|
||||
('dark_slate', 'Dark Slate'),
|
||||
('custom', 'Custom'),
|
||||
],
|
||||
string='Portal Gradient Theme',
|
||||
config_parameter='fusion_claims.portal_gradient_preset',
|
||||
default='green_teal',
|
||||
)
|
||||
fc_portal_gradient_start = fields.Char(
|
||||
string='Gradient Start Color',
|
||||
config_parameter='fusion_claims.portal_gradient_start',
|
||||
default='#5ba848',
|
||||
)
|
||||
fc_portal_gradient_mid = fields.Char(
|
||||
string='Gradient Mid Color',
|
||||
config_parameter='fusion_claims.portal_gradient_mid',
|
||||
default='#3a8fb7',
|
||||
)
|
||||
fc_portal_gradient_end = fields.Char(
|
||||
string='Gradient End Color',
|
||||
config_parameter='fusion_claims.portal_gradient_end',
|
||||
default='#2e7aad',
|
||||
)
|
||||
fc_portal_gradient_preview = fields.Html(
|
||||
string='Gradient Preview',
|
||||
compute='_compute_portal_gradient_preview',
|
||||
sanitize=False,
|
||||
)
|
||||
|
||||
@api.onchange('fc_portal_gradient_preset')
|
||||
def _onchange_portal_gradient_preset(self):
|
||||
preset = self.fc_portal_gradient_preset
|
||||
if preset and preset != 'custom' and preset in self.GRADIENT_PRESETS:
|
||||
start, mid, end = self.GRADIENT_PRESETS[preset]
|
||||
self.fc_portal_gradient_start = start
|
||||
self.fc_portal_gradient_mid = mid
|
||||
self.fc_portal_gradient_end = end
|
||||
|
||||
@api.depends(
|
||||
'fc_portal_gradient_preset',
|
||||
'fc_portal_gradient_start',
|
||||
'fc_portal_gradient_mid',
|
||||
'fc_portal_gradient_end',
|
||||
)
|
||||
def _compute_portal_gradient_preview(self):
|
||||
for rec in self:
|
||||
start = rec.fc_portal_gradient_start or '#5ba848'
|
||||
mid = rec.fc_portal_gradient_mid or '#3a8fb7'
|
||||
end = rec.fc_portal_gradient_end or '#2e7aad'
|
||||
gradient = 'linear-gradient(135deg, %s 0%%, %s 60%%, %s 100%%)' % (start, mid, end)
|
||||
rec.fc_portal_gradient_preview = (
|
||||
'<div style="background: %s; border-radius: 12px; padding: 24px; min-height: 80px;">'
|
||||
'<div style="display: flex; align-items: center; color: #fff;">'
|
||||
'<div style="flex: 1;">'
|
||||
'<h5 style="color: #fff; margin-bottom: 4px;">'
|
||||
'<i class="fa fa-hand-peace-o" style="margin-right: 8px;"></i>'
|
||||
'Welcome back, Preview User!</h5>'
|
||||
'<small style="color: rgba(255,255,255,0.9);">'
|
||||
'This is how your portal dashboard header will look.</small>'
|
||||
'</div>'
|
||||
'<div style="text-align: right;">'
|
||||
'<div style="background: rgba(255,255,255,0.2); border-radius: 8px; padding: 8px 12px;">'
|
||||
'<small style="display: block; color: rgba(255,255,255,0.8);">Preview</small>'
|
||||
'<strong style="color: #fff;">Live</strong>'
|
||||
'</div></div></div></div>'
|
||||
) % gradient
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super().get_values()
|
||||
@@ -603,6 +677,14 @@ class ResConfigSettings(models.TransientModel):
|
||||
elif not ICP.get_param('fusion_claims.odsp_default_office_id', ''):
|
||||
ICP.set_param('fusion_claims.odsp_default_office_id', '')
|
||||
|
||||
# Apply gradient preset colors to ICP so the portal reads them
|
||||
preset = self.fc_portal_gradient_preset
|
||||
if preset and preset != 'custom' and preset in self.GRADIENT_PRESETS:
|
||||
start, mid, end = self.GRADIENT_PRESETS[preset]
|
||||
ICP.set_param('fusion_claims.portal_gradient_start', start)
|
||||
ICP.set_param('fusion_claims.portal_gradient_mid', mid)
|
||||
ICP.set_param('fusion_claims.portal_gradient_end', end)
|
||||
|
||||
# =========================================================================
|
||||
# ACTION METHODS
|
||||
# =========================================================================
|
||||
@@ -618,3 +700,31 @@ class ResConfigSettings(models.TransientModel):
|
||||
'context': {},
|
||||
}
|
||||
|
||||
# -- Portal Gradient Presets -----------------------------------------------
|
||||
|
||||
GRADIENT_PRESETS = {
|
||||
'green_teal': ('#5ba848', '#3a8fb7', '#2e7aad'),
|
||||
'blue_purple': ('#4a90d9', '#7b68ee', '#6a5acd'),
|
||||
'orange_red': ('#f7971e', '#e44d26', '#c0392b'),
|
||||
'dark_slate': ('#2c3e50', '#4a6274', '#34495e'),
|
||||
}
|
||||
|
||||
def _apply_gradient_preset(self, preset_key):
|
||||
start, mid, end = self.GRADIENT_PRESETS[preset_key]
|
||||
self.fc_portal_gradient_preset = preset_key
|
||||
self.fc_portal_gradient_start = start
|
||||
self.fc_portal_gradient_mid = mid
|
||||
self.fc_portal_gradient_end = end
|
||||
|
||||
def action_set_gradient_green_teal(self):
|
||||
self._apply_gradient_preset('green_teal')
|
||||
|
||||
def action_set_gradient_blue_purple(self):
|
||||
self._apply_gradient_preset('blue_purple')
|
||||
|
||||
def action_set_gradient_orange_red(self):
|
||||
self._apply_gradient_preset('orange_red')
|
||||
|
||||
def action_set_gradient_dark_slate(self):
|
||||
self._apply_gradient_preset('dark_slate')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user