Files
Cli-Proxy-API-Management-Ce…/src/features/plugins/PluginsPage.module.scss
T

643 lines
13 KiB
SCSS

@use '../../styles/variables' as *;
@use '../../styles/mixins' as *;
// ─── Page Container ─────────────────────────────────────
.page {
display: flex;
flex-direction: column;
gap: $spacing-lg;
width: 100%;
}
// ─── Header ─────────────────────────────────────────────
.pageHeader {
display: flex;
flex-direction: column;
gap: $spacing-sm;
}
.title {
margin: 0;
color: var(--text-primary);
font-size: 28px;
font-weight: 700;
line-height: 1.2;
}
.description {
margin: 0;
color: var(--text-secondary);
font-size: 14px;
line-height: 1.5;
}
// ─── Alert Boxes ────────────────────────────────────────
.errorBox,
.warningBox {
padding: $spacing-md;
border-radius: $radius-md;
font-size: 14px;
line-height: 1.5;
}
.errorBox {
border: 1px solid var(--danger-color);
background: rgba($error-color, 0.1);
color: var(--danger-color);
}
.warningBox {
border: 1px solid color-mix(in srgb, var(--warning-color, #c65746) 42%, var(--border-color));
background: color-mix(in srgb, var(--warning-color, #c65746) 9%, var(--bg-secondary));
color: var(--text-primary);
}
// ─── Status Bar ─────────────────────────────────────────
.statusBar {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 14px;
border-radius: 10px;
border: 1px solid color-mix(in srgb, var(--border-color) 60%, transparent);
background: color-mix(in srgb, var(--bg-secondary) 60%, transparent);
flex-wrap: wrap;
}
.statusPill {
display: inline-flex;
min-width: 0;
max-width: 100%;
align-items: center;
gap: 6px;
padding: 5px 12px;
border-radius: $radius-full;
border: 1px solid color-mix(in srgb, var(--border-color) 50%, transparent);
background: color-mix(in srgb, var(--bg-primary) 56%, transparent);
font-size: 12px;
font-weight: 600;
white-space: nowrap;
}
.statusDot {
width: 7px;
height: 7px;
border-radius: 50%;
flex-shrink: 0;
}
.statusDotOn {
background: $success-color;
box-shadow: 0 0 6px rgba($success-color, 0.5);
}
.statusDotOff {
background: var(--text-tertiary);
}
.statusLabel {
color: var(--text-secondary);
}
.statusValue {
color: var(--text-primary);
font-weight: 700;
}
.statusPathValue {
display: block;
min-width: 0;
max-width: min(360px, 58vw);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.statusDivider {
width: 1px;
height: 20px;
background: color-mix(in srgb, var(--border-color) 60%, transparent);
flex-shrink: 0;
@include mobile {
display: none;
}
}
// ─── Toolbar ────────────────────────────────────────────
.toolbar {
display: flex;
align-items: center;
gap: $spacing-sm;
:global(.form-group) {
flex: 1;
max-width: 480px;
margin: 0;
}
:global(.input) {
padding-right: 36px;
}
:global(.btn > span) {
display: inline-flex;
align-items: center;
gap: 8px;
}
@include mobile {
flex-direction: column;
align-items: stretch;
:global(.form-group) {
max-width: none;
}
}
}
// ─── Plugin List ────────────────────────────────────────
.pluginList {
display: flex;
flex-direction: column;
gap: 1px;
border: 1px solid color-mix(in srgb, var(--border-color) 70%, transparent);
border-radius: $radius-lg;
overflow: hidden;
background: color-mix(in srgb, var(--border-color) 30%, transparent);
}
// ─── Plugin Row ─────────────────────────────────────────
.pluginRow {
display: grid;
grid-template-columns: 40px 1fr auto;
align-items: center;
gap: $spacing-md;
padding: $spacing-md $spacing-lg;
background: var(--bg-primary);
transition: background-color $transition-fast;
&:hover {
background: var(--bg-hover);
}
@include mobile {
grid-template-columns: 36px 1fr;
grid-template-rows: auto auto;
gap: $spacing-sm;
padding: $spacing-md;
}
}
.logoBox {
display: inline-flex;
width: 40px;
height: 40px;
align-items: center;
justify-content: center;
overflow: hidden;
border-radius: 10px;
border: 1px solid color-mix(in srgb, var(--border-color) 50%, transparent);
background: color-mix(in srgb, var(--bg-tertiary) 60%, transparent);
color: var(--text-secondary);
flex-shrink: 0;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
@include mobile {
width: 36px;
height: 36px;
border-radius: 8px;
}
}
.pluginInfo {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.pluginName {
display: flex;
align-items: center;
gap: $spacing-sm;
min-width: 0;
h2 {
min-width: 0;
margin: 0;
color: var(--text-primary);
font-size: 15px;
font-weight: 650;
line-height: 1.3;
@include text-ellipsis;
}
}
.pluginId {
color: var(--text-tertiary);
font-family: $font-mono;
font-size: 12px;
@include text-ellipsis;
}
.pluginMeta {
display: flex;
align-items: center;
gap: $spacing-sm;
flex-wrap: wrap;
margin-top: 2px;
}
.metaItem {
display: inline-flex;
min-width: 0;
max-width: 100%;
align-items: center;
gap: 4px;
color: var(--text-tertiary);
font-size: 12px;
white-space: nowrap;
strong {
color: var(--text-secondary);
font-weight: 600;
}
}
.metaPath {
display: block;
overflow: hidden;
text-overflow: ellipsis;
}
.metaDot {
width: 3px;
height: 3px;
border-radius: 50%;
background: color-mix(in srgb, var(--text-tertiary) 50%, transparent);
flex-shrink: 0;
}
// ─── Badges ─────────────────────────────────────────────
.badgeRow {
display: flex;
flex-wrap: wrap;
gap: 5px;
}
.badge,
.badgeSuccess,
.badgeWarning,
.badgeMuted {
display: inline-flex;
min-height: 22px;
align-items: center;
border-radius: 6px;
padding: 2px 8px;
font-size: 11px;
font-weight: 600;
line-height: 1.25;
}
.badge {
background: color-mix(in srgb, var(--bg-secondary) 82%, transparent);
border: 1px solid color-mix(in srgb, var(--border-color) 50%, transparent);
color: var(--text-secondary);
}
.badgeSuccess {
background: rgba($success-color, 0.1);
border: 1px solid rgba($success-color, 0.2);
color: var(--success-color);
}
.badgeWarning {
background: rgba($warning-color, 0.1);
border: 1px solid rgba($warning-color, 0.2);
color: var(--warning-color);
}
.badgeMuted {
background: color-mix(in srgb, var(--bg-secondary) 82%, transparent);
border: 1px solid color-mix(in srgb, var(--border-color) 40%, transparent);
color: var(--text-tertiary);
}
// ─── Row Actions ────────────────────────────────────────
.rowActions {
display: flex;
min-width: 0;
max-width: min(560px, 48vw);
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
gap: $spacing-sm;
flex-shrink: 0;
:global(.btn > span) {
display: inline-flex;
align-items: center;
gap: 6px;
}
@include mobile {
grid-column: 1 / -1;
justify-content: flex-start;
max-width: none;
}
}
.iconLink {
display: inline-flex;
min-height: 30px;
align-items: center;
justify-content: center;
border: 1px solid var(--border-color);
border-radius: $radius-md;
background: var(--bg-primary);
color: var(--text-primary);
font-size: 12px;
font-weight: 600;
text-decoration: none;
transition:
border-color $transition-fast,
background-color $transition-fast,
color $transition-fast;
&:hover {
border-color: var(--primary-color);
background: var(--bg-hover);
color: var(--primary-color);
}
}
.iconLink {
width: 30px;
flex: 0 0 auto;
}
// ─── Skeleton ───────────────────────────────────────────
.skeletonRow {
display: flex;
align-items: center;
gap: $spacing-md;
padding: $spacing-md $spacing-lg;
background: var(--bg-primary);
}
.skeletonAvatar {
width: 40px;
height: 40px;
border-radius: 10px;
background: linear-gradient(
90deg,
color-mix(in srgb, var(--bg-secondary) 86%, transparent) 25%,
color-mix(in srgb, var(--bg-hover) 70%, transparent) 37%,
color-mix(in srgb, var(--bg-secondary) 86%, transparent) 63%
);
background-size: 400% 100%;
animation: skeletonPulse 1.35s ease-in-out infinite;
flex-shrink: 0;
}
.skeletonText {
display: flex;
flex-direction: column;
gap: 8px;
flex: 1;
}
.skeletonLine {
height: 14px;
border-radius: 4px;
background: linear-gradient(
90deg,
color-mix(in srgb, var(--bg-secondary) 86%, transparent) 25%,
color-mix(in srgb, var(--bg-hover) 70%, transparent) 37%,
color-mix(in srgb, var(--bg-secondary) 86%, transparent) 63%
);
background-size: 400% 100%;
animation: skeletonPulse 1.35s ease-in-out infinite;
&:first-child {
width: 45%;
}
&:last-child {
width: 70%;
height: 10px;
}
}
// ─── Sheet Config Form ──────────────────────────────────
.sheetFooter {
display: flex;
justify-content: flex-end;
gap: $spacing-sm;
}
.configForm {
display: flex;
flex-direction: column;
gap: $spacing-lg;
}
.formSection {
display: flex;
flex-direction: column;
gap: $spacing-md;
h3 {
margin: 0;
color: var(--text-primary);
font-size: 16px;
font-weight: 700;
}
:global(.form-group) {
margin: 0;
}
}
.fieldRow {
display: flex;
align-items: center;
justify-content: space-between;
gap: $spacing-md;
min-height: 52px;
padding: $spacing-md;
border: 1px solid var(--border-color);
border-radius: $radius-md;
background: color-mix(in srgb, var(--bg-secondary) 72%, transparent);
}
.fieldText {
min-width: 0;
}
.fieldLabel {
color: var(--text-primary);
font-size: 14px;
font-weight: 650;
overflow-wrap: anywhere;
}
.fieldDescription,
.fieldHint {
margin-top: 4px;
color: var(--text-tertiary);
font-size: 12px;
line-height: 1.45;
overflow-wrap: anywhere;
}
.formField {
display: flex;
flex-direction: column;
gap: 6px;
label {
color: var(--text-primary);
font-size: 14px;
font-weight: 600;
overflow-wrap: anywhere;
}
}
.textarea {
min-height: 148px;
resize: vertical;
border: 1px solid var(--border-color);
border-radius: $radius-md;
padding: 10px 12px;
background: var(--bg-primary);
color: var(--text-primary);
font-family: $font-mono;
font-size: 13px;
line-height: 1.5;
&:focus {
border-color: var(--primary-color);
outline: none;
box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 18%, transparent);
}
}
.arrayEditor {
display: flex;
flex-direction: column;
gap: $spacing-sm;
}
.arrayItemRow {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: $spacing-sm;
}
.arrayInput {
width: 100%;
min-width: 0;
height: 38px;
border: 1px solid var(--border-color);
border-radius: $radius-md;
padding: 0 12px;
background: var(--bg-primary);
color: var(--text-primary);
font-size: 14px;
line-height: 38px;
box-sizing: border-box;
&:focus {
border-color: var(--primary-color);
outline: none;
box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 18%, transparent);
}
}
.arrayActions {
display: inline-flex;
flex: 0 0 auto;
gap: 4px;
}
.iconButton:global(.btn.btn-sm) {
width: 34px;
height: 34px;
min-width: 34px;
padding: 0;
> span {
display: inline-flex;
align-items: center;
justify-content: center;
}
}
.fieldError {
padding: 8px 10px;
border-radius: $radius-sm;
background: rgba($error-color, 0.1);
color: var(--danger-color);
font-size: 12px;
line-height: 1.4;
}
.emptyConfig {
padding: $spacing-md;
border: 1px dashed var(--border-color);
border-radius: $radius-md;
background: color-mix(in srgb, var(--bg-secondary) 70%, transparent);
color: var(--text-secondary);
font-size: 14px;
}
// ─── Animation ──────────────────────────────────────────
@keyframes skeletonPulse {
0% {
background-position: 100% 0;
}
100% {
background-position: 0 0;
}
}
// ─── Mobile Overrides ───────────────────────────────────
@include mobile {
.page {
gap: $spacing-md;
}
.sheetFooter {
flex-direction: column-reverse;
:global(.btn) {
width: 100%;
}
}
.arrayItemRow {
grid-template-columns: minmax(0, 1fr) auto;
}
}