@morscherlab/mld-sdk 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/index.js +2 -0
- package/dist/composables/index.js.map +1 -1
- package/dist/composables/usePluginConfig.d.ts +12 -0
- package/dist/composables/usePluginConfig.js +77 -0
- package/dist/composables/usePluginConfig.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/styles.css +50 -39
- package/package.json +1 -1
- package/src/composables/index.ts +1 -0
- package/src/composables/usePluginConfig.ts +92 -0
- package/src/index.ts +3 -0
- package/src/styles/components/app-top-bar.css +9 -9
- package/src/styles/components/form-field.css +5 -3
- package/src/styles/components/number-input.css +4 -1
- package/src/styles/components/tabs.css +1 -1
- package/src/styles/variables.css +12 -11
|
@@ -16,4 +16,5 @@ export { useSequenceUtils, type SequenceType, type SequenceStats, } from './useS
|
|
|
16
16
|
export { parseTime, formatTime, generateTimeSlots, rangesOverlap, durationMinutes, formatDuration, isTimeInRange, findAvailableSlots, snapToSlot, addMinutes, compareTime, } from './useTimeUtils';
|
|
17
17
|
export { useScheduleDrag } from './useScheduleDrag';
|
|
18
18
|
export { useFormBuilder, evaluateCondition } from './useFormBuilder';
|
|
19
|
+
export { usePluginConfig, type UsePluginConfigReturn } from './usePluginConfig';
|
|
19
20
|
export { getFieldRegistryEntry, getTypeDefault, type RegistryEntry, } from './formBuilderRegistry';
|
|
@@ -16,6 +16,7 @@ import { useSequenceUtils } from "./useSequenceUtils.js";
|
|
|
16
16
|
import { addMinutes, compareTime, durationMinutes, findAvailableSlots, formatDuration, formatTime, generateTimeSlots, isTimeInRange, parseTime, rangesOverlap, snapToSlot } from "./useTimeUtils.js";
|
|
17
17
|
import { useScheduleDrag } from "./useScheduleDrag.js";
|
|
18
18
|
import { evaluateCondition, useFormBuilder } from "./useFormBuilder.js";
|
|
19
|
+
import { usePluginConfig } from "./usePluginConfig.js";
|
|
19
20
|
import { getFieldRegistryEntry, getTypeDefault } from "./formBuilderRegistry.js";
|
|
20
21
|
export {
|
|
21
22
|
ATOMIC_WEIGHTS,
|
|
@@ -44,6 +45,7 @@ export {
|
|
|
44
45
|
useFormBuilder,
|
|
45
46
|
usePasskey,
|
|
46
47
|
usePlatformContext,
|
|
48
|
+
usePluginConfig,
|
|
47
49
|
useProtocolTemplates,
|
|
48
50
|
useRackEditor,
|
|
49
51
|
useScheduleDrag,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Ref, ComputedRef } from 'vue';
|
|
2
|
+
export interface UsePluginConfigReturn {
|
|
3
|
+
config: Ref<Record<string, unknown>>;
|
|
4
|
+
isLoading: Ref<boolean>;
|
|
5
|
+
isSaving: Ref<boolean>;
|
|
6
|
+
error: Ref<string | null>;
|
|
7
|
+
isDirty: ComputedRef<boolean>;
|
|
8
|
+
load: () => Promise<void>;
|
|
9
|
+
save: () => Promise<boolean>;
|
|
10
|
+
reset: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function usePluginConfig(pluginName?: string): UsePluginConfigReturn;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { computed, ref, onMounted } from "vue";
|
|
2
|
+
import { useApi } from "./useApi.js";
|
|
3
|
+
import { usePlatformContext } from "./usePlatformContext.js";
|
|
4
|
+
function usePluginConfig(pluginName) {
|
|
5
|
+
const api = useApi();
|
|
6
|
+
const { plugin } = usePlatformContext();
|
|
7
|
+
const resolvedName = computed(() => {
|
|
8
|
+
var _a;
|
|
9
|
+
return pluginName ?? ((_a = plugin.value) == null ? void 0 : _a.name) ?? "";
|
|
10
|
+
});
|
|
11
|
+
const config = ref({});
|
|
12
|
+
const savedConfig = ref({});
|
|
13
|
+
const isLoading = ref(false);
|
|
14
|
+
const isSaving = ref(false);
|
|
15
|
+
const error = ref(null);
|
|
16
|
+
const isDirty = computed(() => {
|
|
17
|
+
return JSON.stringify(config.value) !== JSON.stringify(savedConfig.value);
|
|
18
|
+
});
|
|
19
|
+
async function load() {
|
|
20
|
+
const name = resolvedName.value;
|
|
21
|
+
if (!name) return;
|
|
22
|
+
isLoading.value = true;
|
|
23
|
+
error.value = null;
|
|
24
|
+
try {
|
|
25
|
+
const response = await api.get(
|
|
26
|
+
`/api/plugins/${encodeURIComponent(name)}/config`
|
|
27
|
+
);
|
|
28
|
+
config.value = { ...response.config };
|
|
29
|
+
savedConfig.value = { ...response.config };
|
|
30
|
+
} catch (e) {
|
|
31
|
+
error.value = e instanceof Error ? e.message : "Failed to load plugin config";
|
|
32
|
+
} finally {
|
|
33
|
+
isLoading.value = false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function save() {
|
|
37
|
+
const name = resolvedName.value;
|
|
38
|
+
if (!name) return false;
|
|
39
|
+
isSaving.value = true;
|
|
40
|
+
error.value = null;
|
|
41
|
+
try {
|
|
42
|
+
const response = await api.put(
|
|
43
|
+
`/api/plugins/${encodeURIComponent(name)}/config`,
|
|
44
|
+
{ config: config.value }
|
|
45
|
+
);
|
|
46
|
+
config.value = { ...response.config };
|
|
47
|
+
savedConfig.value = { ...response.config };
|
|
48
|
+
return true;
|
|
49
|
+
} catch (e) {
|
|
50
|
+
error.value = e instanceof Error ? e.message : "Failed to save plugin config";
|
|
51
|
+
return false;
|
|
52
|
+
} finally {
|
|
53
|
+
isSaving.value = false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function reset() {
|
|
57
|
+
config.value = { ...savedConfig.value };
|
|
58
|
+
error.value = null;
|
|
59
|
+
}
|
|
60
|
+
onMounted(() => {
|
|
61
|
+
load();
|
|
62
|
+
});
|
|
63
|
+
return {
|
|
64
|
+
config,
|
|
65
|
+
isLoading,
|
|
66
|
+
isSaving,
|
|
67
|
+
error,
|
|
68
|
+
isDirty,
|
|
69
|
+
load,
|
|
70
|
+
save,
|
|
71
|
+
reset
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
usePluginConfig
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=usePluginConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePluginConfig.js","sources":["../../src/composables/usePluginConfig.ts"],"sourcesContent":["import { ref, computed, onMounted, type Ref, type ComputedRef } from 'vue'\nimport { useApi } from './useApi'\nimport { usePlatformContext } from './usePlatformContext'\n\nexport interface UsePluginConfigReturn {\n config: Ref<Record<string, unknown>>\n isLoading: Ref<boolean>\n isSaving: Ref<boolean>\n error: Ref<string | null>\n isDirty: ComputedRef<boolean>\n load: () => Promise<void>\n save: () => Promise<boolean>\n reset: () => void\n}\n\nexport function usePluginConfig(pluginName?: string): UsePluginConfigReturn {\n const api = useApi()\n const { plugin } = usePlatformContext()\n\n const resolvedName = computed(() => pluginName ?? plugin.value?.name ?? '')\n\n const config = ref<Record<string, unknown>>({})\n const savedConfig = ref<Record<string, unknown>>({})\n const isLoading = ref(false)\n const isSaving = ref(false)\n const error = ref<string | null>(null)\n\n const isDirty = computed(() => {\n return JSON.stringify(config.value) !== JSON.stringify(savedConfig.value)\n })\n\n async function load(): Promise<void> {\n const name = resolvedName.value\n if (!name) return\n\n isLoading.value = true\n error.value = null\n try {\n const response = await api.get<{ plugin_name: string; config: Record<string, unknown> }>(\n `/api/plugins/${encodeURIComponent(name)}/config`,\n )\n config.value = { ...response.config }\n savedConfig.value = { ...response.config }\n } catch (e) {\n error.value = e instanceof Error ? e.message : 'Failed to load plugin config'\n } finally {\n isLoading.value = false\n }\n }\n\n async function save(): Promise<boolean> {\n const name = resolvedName.value\n if (!name) return false\n\n isSaving.value = true\n error.value = null\n try {\n const response = await api.put<{ plugin_name: string; config: Record<string, unknown> }>(\n `/api/plugins/${encodeURIComponent(name)}/config`,\n { config: config.value },\n )\n config.value = { ...response.config }\n savedConfig.value = { ...response.config }\n return true\n } catch (e) {\n error.value = e instanceof Error ? e.message : 'Failed to save plugin config'\n return false\n } finally {\n isSaving.value = false\n }\n }\n\n function reset(): void {\n config.value = { ...savedConfig.value }\n error.value = null\n }\n\n onMounted(() => {\n load()\n })\n\n return {\n config,\n isLoading,\n isSaving,\n error,\n isDirty,\n load,\n save,\n reset,\n }\n}\n"],"names":[],"mappings":";;;AAeO,SAAS,gBAAgB,YAA4C;AAC1E,QAAM,MAAM,OAAA;AACZ,QAAM,EAAE,OAAA,IAAW,mBAAA;AAEnB,QAAM,eAAe,SAAS,MAAA;;AAAM,2BAAc,YAAO,UAAP,mBAAc,SAAQ;AAAA,GAAE;AAE1E,QAAM,SAAS,IAA6B,EAAE;AAC9C,QAAM,cAAc,IAA6B,EAAE;AACnD,QAAM,YAAY,IAAI,KAAK;AAC3B,QAAM,WAAW,IAAI,KAAK;AAC1B,QAAM,QAAQ,IAAmB,IAAI;AAErC,QAAM,UAAU,SAAS,MAAM;AAC7B,WAAO,KAAK,UAAU,OAAO,KAAK,MAAM,KAAK,UAAU,YAAY,KAAK;AAAA,EAC1E,CAAC;AAED,iBAAe,OAAsB;AACnC,UAAM,OAAO,aAAa;AAC1B,QAAI,CAAC,KAAM;AAEX,cAAU,QAAQ;AAClB,UAAM,QAAQ;AACd,QAAI;AACF,YAAM,WAAW,MAAM,IAAI;AAAA,QACzB,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,MAAA;AAE1C,aAAO,QAAQ,EAAE,GAAG,SAAS,OAAA;AAC7B,kBAAY,QAAQ,EAAE,GAAG,SAAS,OAAA;AAAA,IACpC,SAAS,GAAG;AACV,YAAM,QAAQ,aAAa,QAAQ,EAAE,UAAU;AAAA,IACjD,UAAA;AACE,gBAAU,QAAQ;AAAA,IACpB;AAAA,EACF;AAEA,iBAAe,OAAyB;AACtC,UAAM,OAAO,aAAa;AAC1B,QAAI,CAAC,KAAM,QAAO;AAElB,aAAS,QAAQ;AACjB,UAAM,QAAQ;AACd,QAAI;AACF,YAAM,WAAW,MAAM,IAAI;AAAA,QACzB,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,QACxC,EAAE,QAAQ,OAAO,MAAA;AAAA,MAAM;AAEzB,aAAO,QAAQ,EAAE,GAAG,SAAS,OAAA;AAC7B,kBAAY,QAAQ,EAAE,GAAG,SAAS,OAAA;AAClC,aAAO;AAAA,IACT,SAAS,GAAG;AACV,YAAM,QAAQ,aAAa,QAAQ,EAAE,UAAU;AAC/C,aAAO;AAAA,IACT,UAAA;AACE,eAAS,QAAQ;AAAA,IACnB;AAAA,EACF;AAEA,WAAS,QAAc;AACrB,WAAO,QAAQ,EAAE,GAAG,YAAY,MAAA;AAChC,UAAM,QAAQ;AAAA,EAChB;AAEA,YAAU,MAAM;AACd,SAAA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { MLDSdk, default } from './install';
|
|
2
2
|
export { BaseButton, BaseInput, BaseTextarea, BaseSelect, BaseCheckbox, BaseToggle, BaseRadioGroup, BaseSlider, ColorSlider, BaseTabs, BaseModal, FormField, DatePicker, TimePicker, TagsInput, NumberInput, FileUploader, AlertBox, ToastNotification, IconButton, ThemeToggle, SettingsButton, CollapsibleCard, AppTopBar, AppSidebar, AppLayout, AppContainer, Skeleton, WellPlate, RackEditor, SampleLegend, PlateMapEditor, ExperimentTimeline, SampleSelector, GroupingModal, GroupAssigner, MoleculeInput, ConcentrationInput, DoseCalculator, ReagentList, SampleHierarchyTree, ProtocolStepEditor, SegmentedControl, MultiSelect, BasePill, DropdownButton, Calendar, DataFrame, LoadingSpinner, Divider, StatusIndicator, ProgressBar, Avatar, EmptyState, Breadcrumb, Tooltip, ConfirmDialog, ChartContainer, SettingsModal, ScientificNumber, ChemicalFormula, FormulaInput, SequenceInput, UnitInput, StepWizard, AuditTrail, BatchProgressList, DateTimePicker, TimeRangeInput, ScheduleCalendar, ResourceCard, } from './components';
|
|
3
|
-
export { useApi, useAuth, usePasskey, useTheme, useToast, usePlatformContext, useWellPlateEditor, useConcentrationUnits, useDoseCalculator, useProtocolTemplates, useRackEditor, useChemicalFormula, ATOMIC_WEIGHTS, useSequenceUtils, type ApiClientOptions, type UseWellPlateEditorOptions, type UseWellPlateEditorReturn, type UseRackEditorOptions, type UseRackEditorReturn, type ConcentrationValue, type ConcentrationUnit, type VolumeValue, type VolumeUnit, type StepTemplate, type FormulaParseResult, type FormulaPart, type SequenceType, type SequenceStats, parseTime, formatTime, generateTimeSlots, rangesOverlap, durationMinutes, formatDuration, isTimeInRange, findAvailableSlots, snapToSlot, addMinutes, compareTime, useScheduleDrag, } from './composables';
|
|
3
|
+
export { useApi, useAuth, usePasskey, useTheme, useToast, usePlatformContext, useWellPlateEditor, useConcentrationUnits, useDoseCalculator, useProtocolTemplates, useRackEditor, useChemicalFormula, ATOMIC_WEIGHTS, useSequenceUtils, type ApiClientOptions, type UseWellPlateEditorOptions, type UseWellPlateEditorReturn, type UseRackEditorOptions, type UseRackEditorReturn, type ConcentrationValue, type ConcentrationUnit, type VolumeValue, type VolumeUnit, type StepTemplate, type FormulaParseResult, type FormulaPart, type SequenceType, type SequenceStats, parseTime, formatTime, generateTimeSlots, rangesOverlap, durationMinutes, formatDuration, isTimeInRange, findAvailableSlots, snapToSlot, addMinutes, compareTime, useScheduleDrag, usePluginConfig, type UsePluginConfigReturn, } from './composables';
|
|
4
4
|
export { useAuthStore, useSettingsStore, colorPalettes, type SettingsState, } from './stores';
|
|
5
5
|
export type { ContainerDirection, ButtonVariant, ButtonSize, InputType, ModalSize, AlertType, Toast, TabItem, SelectOption, RadioOption, FormFieldProps, SidebarToolSection, CollapsibleState, TopBarVariant, TopBarPage, TopBarTab, TopBarTabOption, TopBarSettingsConfig, WellPlateFormat, WellState, WellPlateSelectionMode, Well, HeatmapColorScale, HeatmapConfig, SlotPosition, WellExtendedData, WellEditData, WellEditField, WellLegendItem, Rack, SampleType, PlateMap, PlateMapEditorState, ProtocolStepType, ProtocolStepStatus, ProtocolStep, SampleGroup, GroupItem, FileUploaderMode, SegmentedOption, SegmentedControlVariant, SegmentedControlSize, MultiSelectOption, MultiSelectSize, PillVariant, PillSize, CalendarSelectionMode, CalendarMarker, CalendarDayContext, SortDirection, SortState, DataFrameColumn, PaginationState, SpinnerSize, SpinnerVariant, DividerSpacing, StatusType, ProgressVariant, ProgressSize, AvatarSize, EmptyStateColor, EmptyStateSize, BreadcrumbItem, TooltipPosition, ConfirmVariant, SettingsTab, NumberNotation, TimePickerFormat, TimeRange, ScheduleView, ScheduleEventStatus, ScheduleEvent, ScheduleBlockedSlot, ScheduleSlotContext, ScheduleEventCreateContext, ScheduleEventUpdateContext, ResourceStatus, ResourceSpec, UnitOption, WizardStep, WizardStepState, AuditEntryType, AuditEntry, BatchItemStatus, BatchItem, BatchSummary, AuthConfig, UserInfo, LoginResponse, TokenVerifyResponse, RegisterRequest, UpdateProfileRequest, CredentialInfo, PluginInfo, PluginNavItem, PluginSettings, PluginSettingField, PlatformContext, PlatformEventType, PlatformEvent, ThemeMode, ColorPalette, TableDensity, } from './types';
|
package/dist/index.js
CHANGED
|
@@ -156,6 +156,7 @@ import { ATOMIC_WEIGHTS, useChemicalFormula } from "./composables/useChemicalFor
|
|
|
156
156
|
import { useSequenceUtils } from "./composables/useSequenceUtils.js";
|
|
157
157
|
import { addMinutes, compareTime, durationMinutes, findAvailableSlots, formatDuration, formatTime, generateTimeSlots, isTimeInRange, parseTime, rangesOverlap, snapToSlot } from "./composables/useTimeUtils.js";
|
|
158
158
|
import { useScheduleDrag } from "./composables/useScheduleDrag.js";
|
|
159
|
+
import { usePluginConfig } from "./composables/usePluginConfig.js";
|
|
159
160
|
import { useAuthStore } from "./stores/auth.js";
|
|
160
161
|
import { colorPalettes, useSettingsStore } from "./stores/settings.js";
|
|
161
162
|
export {
|
|
@@ -253,6 +254,7 @@ export {
|
|
|
253
254
|
useDoseCalculator,
|
|
254
255
|
usePasskey,
|
|
255
256
|
usePlatformContext,
|
|
257
|
+
usePluginConfig,
|
|
256
258
|
useProtocolTemplates,
|
|
257
259
|
useRackEditor,
|
|
258
260
|
useScheduleDrag,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/styles.css
CHANGED
|
@@ -28,8 +28,9 @@
|
|
|
28
28
|
--text-muted: #94A3B8;
|
|
29
29
|
|
|
30
30
|
/* Brand colors */
|
|
31
|
-
--color-primary: #
|
|
32
|
-
--color-primary-hover: #
|
|
31
|
+
--color-primary: #6366F1;
|
|
32
|
+
--color-primary-hover: #4F46E5;
|
|
33
|
+
--color-primary-soft: rgba(99, 102, 241, 0.12);
|
|
33
34
|
--color-cta: #F97316;
|
|
34
35
|
--color-cta-hover: #EA580C;
|
|
35
36
|
--color-purple: #8B5CF6;
|
|
@@ -289,7 +290,7 @@ code, pre {
|
|
|
289
290
|
}
|
|
290
291
|
.input-modern:focus {
|
|
291
292
|
border-color: var(--color-primary);
|
|
292
|
-
box-shadow: 0 0 0 3px rgba(
|
|
293
|
+
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
|
|
293
294
|
}
|
|
294
295
|
.input-modern::placeholder {
|
|
295
296
|
color: var(--text-muted);
|
|
@@ -318,7 +319,7 @@ code, pre {
|
|
|
318
319
|
}
|
|
319
320
|
.select-modern:focus {
|
|
320
321
|
border-color: var(--color-primary);
|
|
321
|
-
box-shadow: 0 0 0 3px rgba(
|
|
322
|
+
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
|
|
322
323
|
}
|
|
323
324
|
/* Label styles */
|
|
324
325
|
.label-modern {
|
|
@@ -493,7 +494,7 @@ code, pre {
|
|
|
493
494
|
border-color: var(--border-color);
|
|
494
495
|
}
|
|
495
496
|
.bg-mld-primary {
|
|
496
|
-
background-color:
|
|
497
|
+
background-color: var(--color-primary);
|
|
497
498
|
}
|
|
498
499
|
.text-mld-primary {
|
|
499
500
|
color: var(--color-primary);
|
|
@@ -502,10 +503,10 @@ code, pre {
|
|
|
502
503
|
border-color: var(--color-primary);
|
|
503
504
|
}
|
|
504
505
|
.bg-mld-primary\/5 {
|
|
505
|
-
background-color: rgba(
|
|
506
|
+
background-color: rgba(99, 102, 241, 0.05);
|
|
506
507
|
}
|
|
507
508
|
.hover\:border-mld-primary\/50:hover {
|
|
508
|
-
border-color: rgba(
|
|
509
|
+
border-color: rgba(99, 102, 241, 0.5);
|
|
509
510
|
}
|
|
510
511
|
/* Danger/error color utilities */
|
|
511
512
|
.text-mld-danger {
|
|
@@ -561,10 +562,10 @@ code, pre {
|
|
|
561
562
|
background-color: #DC2626;
|
|
562
563
|
}
|
|
563
564
|
.bg-mld-primary\/10 {
|
|
564
|
-
background-color: rgba(
|
|
565
|
+
background-color: rgba(99, 102, 241, 0.1);
|
|
565
566
|
}
|
|
566
567
|
.hover\:bg-mld-primary\/20:hover {
|
|
567
|
-
background-color: rgba(
|
|
568
|
+
background-color: rgba(99, 102, 241, 0.2);
|
|
568
569
|
}
|
|
569
570
|
.bg-mld-info {
|
|
570
571
|
background-color: var(--mld-info);
|
|
@@ -594,10 +595,10 @@ code, pre {
|
|
|
594
595
|
color: var(--color-primary);
|
|
595
596
|
}
|
|
596
597
|
.text-mld-primary\/80 {
|
|
597
|
-
color: rgba(
|
|
598
|
+
color: rgba(99, 102, 241, 0.8);
|
|
598
599
|
}
|
|
599
600
|
.hover\:text-mld-primary\/70:hover {
|
|
600
|
-
color: rgba(
|
|
601
|
+
color: rgba(99, 102, 241, 0.7);
|
|
601
602
|
}
|
|
602
603
|
/* ==========================================================================
|
|
603
604
|
Border Color Utilities (Tailwind v4 compatibility)
|
|
@@ -1248,7 +1249,7 @@ html.dark .focus\:ring-offset-2:focus {
|
|
|
1248
1249
|
.mld-topbar__logo-icon {
|
|
1249
1250
|
width: 2rem;
|
|
1250
1251
|
height: 2rem;
|
|
1251
|
-
background-color: var(--color-primary, #
|
|
1252
|
+
background-color: var(--color-primary, #6366F1);
|
|
1252
1253
|
border-radius: 0.5rem;
|
|
1253
1254
|
display: flex;
|
|
1254
1255
|
align-items: center;
|
|
@@ -1377,8 +1378,8 @@ html.dark .focus\:ring-offset-2:focus {
|
|
|
1377
1378
|
background: var(--mld-bg-hover, rgba(0, 0, 0, 0.05));
|
|
1378
1379
|
}
|
|
1379
1380
|
.mld-topbar-dropdown-item--active {
|
|
1380
|
-
background: var(--
|
|
1381
|
-
color: var(--
|
|
1381
|
+
background: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
1382
|
+
color: var(--color-primary, #6366F1);
|
|
1382
1383
|
}
|
|
1383
1384
|
.mld-topbar-dropdown-item--disabled {
|
|
1384
1385
|
opacity: 0.5;
|
|
@@ -1393,7 +1394,7 @@ html.dark .focus\:ring-offset-2:focus {
|
|
|
1393
1394
|
margin-top: 0.125rem;
|
|
1394
1395
|
}
|
|
1395
1396
|
.mld-topbar-dropdown-item--active .mld-topbar-dropdown-item__description {
|
|
1396
|
-
color: var(--
|
|
1397
|
+
color: var(--color-primary, #6366F1);
|
|
1397
1398
|
opacity: 0.8;
|
|
1398
1399
|
}
|
|
1399
1400
|
/* Tabs in center of topbar */
|
|
@@ -1425,8 +1426,8 @@ html.dark .focus\:ring-offset-2:focus {
|
|
|
1425
1426
|
color: var(--mld-text-primary, #111827);
|
|
1426
1427
|
}
|
|
1427
1428
|
.mld-topbar-tab--active {
|
|
1428
|
-
background: var(--
|
|
1429
|
-
color: var(--
|
|
1429
|
+
background: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
1430
|
+
color: var(--color-primary, #6366F1);
|
|
1430
1431
|
}
|
|
1431
1432
|
.mld-topbar-tab--disabled {
|
|
1432
1433
|
opacity: 0.5;
|
|
@@ -1481,13 +1482,13 @@ html.dark .focus\:ring-offset-2:focus {
|
|
|
1481
1482
|
border: none;
|
|
1482
1483
|
background: transparent;
|
|
1483
1484
|
border-radius: var(--mld-radius-sm, 0.25rem);
|
|
1484
|
-
color: #
|
|
1485
|
+
color: var(--color-primary, #6366F1);
|
|
1485
1486
|
cursor: pointer;
|
|
1486
1487
|
text-decoration: none;
|
|
1487
1488
|
transition: background-color 0.15s ease;
|
|
1488
1489
|
}
|
|
1489
1490
|
.mld-topbar__admin-btn:hover {
|
|
1490
|
-
background:
|
|
1491
|
+
background: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
1491
1492
|
}
|
|
1492
1493
|
.mld-topbar__admin-icon {
|
|
1493
1494
|
width: 1.25rem;
|
|
@@ -1518,7 +1519,7 @@ html.dark .focus\:ring-offset-2:focus {
|
|
|
1518
1519
|
font-size: 0.75rem;
|
|
1519
1520
|
font-weight: 500;
|
|
1520
1521
|
color: white;
|
|
1521
|
-
background: linear-gradient(135deg, #
|
|
1522
|
+
background: linear-gradient(135deg, var(--color-primary-hover, #4F46E5) 0%, var(--color-primary, #6366F1) 100%);
|
|
1522
1523
|
flex-shrink: 0;
|
|
1523
1524
|
}
|
|
1524
1525
|
.mld-topbar__profile-name {
|
|
@@ -3079,9 +3080,11 @@ html.dark .mld-checkbox__native:focus-visible + .mld-checkbox__box {
|
|
|
3079
3080
|
}
|
|
3080
3081
|
.mld-form-field__label {
|
|
3081
3082
|
display: block;
|
|
3082
|
-
font-size: 0.
|
|
3083
|
-
font-weight:
|
|
3084
|
-
|
|
3083
|
+
font-size: 0.6875rem;
|
|
3084
|
+
font-weight: 600;
|
|
3085
|
+
text-transform: uppercase;
|
|
3086
|
+
letter-spacing: 0.05em;
|
|
3087
|
+
color: var(--text-secondary);
|
|
3085
3088
|
}
|
|
3086
3089
|
.mld-form-field__required {
|
|
3087
3090
|
color: var(--mld-error);
|
|
@@ -3363,6 +3366,7 @@ html.dark .mld-checkbox__native:focus-visible + .mld-checkbox__box {
|
|
|
3363
3366
|
/* NumberInput Component Styles */
|
|
3364
3367
|
.mld-number-input {
|
|
3365
3368
|
display: inline-flex;
|
|
3369
|
+
max-width: 100%;
|
|
3366
3370
|
border-radius: 0.5rem;
|
|
3367
3371
|
border: 1px solid var(--border-color);
|
|
3368
3372
|
overflow: hidden;
|
|
@@ -3395,6 +3399,7 @@ html.dark .mld-checkbox__native:focus-visible + .mld-checkbox__box {
|
|
|
3395
3399
|
display: flex;
|
|
3396
3400
|
align-items: center;
|
|
3397
3401
|
justify-content: center;
|
|
3402
|
+
flex-shrink: 0;
|
|
3398
3403
|
background-color: var(--bg-tertiary);
|
|
3399
3404
|
color: var(--text-muted);
|
|
3400
3405
|
border: none;
|
|
@@ -3429,7 +3434,8 @@ html.dark .mld-checkbox__native:focus-visible + .mld-checkbox__box {
|
|
|
3429
3434
|
height: 1rem;
|
|
3430
3435
|
}
|
|
3431
3436
|
.mld-number-input__input {
|
|
3432
|
-
|
|
3437
|
+
flex: 1;
|
|
3438
|
+
min-width: 0;
|
|
3433
3439
|
text-align: center;
|
|
3434
3440
|
background-color: var(--bg-secondary);
|
|
3435
3441
|
color: var(--text-primary);
|
|
@@ -4466,7 +4472,7 @@ html.dark .mld-slider__track {
|
|
|
4466
4472
|
padding: 0.125rem 0.375rem;
|
|
4467
4473
|
font-size: 0.75rem;
|
|
4468
4474
|
border-radius: 9999px;
|
|
4469
|
-
background-color: rgba(
|
|
4475
|
+
background-color: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
4470
4476
|
color: var(--color-primary);
|
|
4471
4477
|
}
|
|
4472
4478
|
/* TagsInput Component Styles */
|
|
@@ -12876,7 +12882,7 @@ html.dark .mld-slider__track {
|
|
|
12876
12882
|
padding: 0.125rem 0.375rem;
|
|
12877
12883
|
font-size: 0.75rem;
|
|
12878
12884
|
border-radius: 9999px;
|
|
12879
|
-
background-color: rgba(
|
|
12885
|
+
background-color: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
12880
12886
|
color: var(--color-primary);
|
|
12881
12887
|
}
|
|
12882
12888
|
/* BaseModal Component Styles */
|
|
@@ -14158,9 +14164,11 @@ to { transform: rotate(360deg);
|
|
|
14158
14164
|
}
|
|
14159
14165
|
.mld-form-field__label {
|
|
14160
14166
|
display: block;
|
|
14161
|
-
font-size: 0.
|
|
14162
|
-
font-weight:
|
|
14163
|
-
|
|
14167
|
+
font-size: 0.6875rem;
|
|
14168
|
+
font-weight: 600;
|
|
14169
|
+
text-transform: uppercase;
|
|
14170
|
+
letter-spacing: 0.05em;
|
|
14171
|
+
color: var(--text-secondary);
|
|
14164
14172
|
}
|
|
14165
14173
|
.mld-form-field__required {
|
|
14166
14174
|
color: var(--mld-error);
|
|
@@ -14652,6 +14660,7 @@ to { transform: rotate(360deg);
|
|
|
14652
14660
|
/* NumberInput Component Styles */
|
|
14653
14661
|
.mld-number-input {
|
|
14654
14662
|
display: inline-flex;
|
|
14663
|
+
max-width: 100%;
|
|
14655
14664
|
border-radius: 0.5rem;
|
|
14656
14665
|
border: 1px solid var(--border-color);
|
|
14657
14666
|
overflow: hidden;
|
|
@@ -14684,6 +14693,7 @@ to { transform: rotate(360deg);
|
|
|
14684
14693
|
display: flex;
|
|
14685
14694
|
align-items: center;
|
|
14686
14695
|
justify-content: center;
|
|
14696
|
+
flex-shrink: 0;
|
|
14687
14697
|
background-color: var(--bg-tertiary);
|
|
14688
14698
|
color: var(--text-muted);
|
|
14689
14699
|
border: none;
|
|
@@ -14718,7 +14728,8 @@ to { transform: rotate(360deg);
|
|
|
14718
14728
|
height: 1rem;
|
|
14719
14729
|
}
|
|
14720
14730
|
.mld-number-input__input {
|
|
14721
|
-
|
|
14731
|
+
flex: 1;
|
|
14732
|
+
min-width: 0;
|
|
14722
14733
|
text-align: center;
|
|
14723
14734
|
background-color: var(--bg-secondary);
|
|
14724
14735
|
color: var(--text-primary);
|
|
@@ -15846,7 +15857,7 @@ html.dark .mld-settings-modal__option-btn--active {
|
|
|
15846
15857
|
.mld-topbar__logo-icon {
|
|
15847
15858
|
width: 2rem;
|
|
15848
15859
|
height: 2rem;
|
|
15849
|
-
background-color: var(--color-primary, #
|
|
15860
|
+
background-color: var(--color-primary, #6366F1);
|
|
15850
15861
|
border-radius: 0.5rem;
|
|
15851
15862
|
display: flex;
|
|
15852
15863
|
align-items: center;
|
|
@@ -15977,8 +15988,8 @@ html.dark .mld-settings-modal__option-btn--active {
|
|
|
15977
15988
|
background: var(--mld-bg-hover, rgba(0, 0, 0, 0.05));
|
|
15978
15989
|
}
|
|
15979
15990
|
.mld-topbar-dropdown-item--active {
|
|
15980
|
-
background: var(--
|
|
15981
|
-
color: var(--
|
|
15991
|
+
background: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
15992
|
+
color: var(--color-primary, #6366F1);
|
|
15982
15993
|
}
|
|
15983
15994
|
.mld-topbar-dropdown-item--disabled {
|
|
15984
15995
|
opacity: 0.5;
|
|
@@ -15993,7 +16004,7 @@ html.dark .mld-settings-modal__option-btn--active {
|
|
|
15993
16004
|
margin-top: 0.125rem;
|
|
15994
16005
|
}
|
|
15995
16006
|
.mld-topbar-dropdown-item--active .mld-topbar-dropdown-item__description {
|
|
15996
|
-
color: var(--
|
|
16007
|
+
color: var(--color-primary, #6366F1);
|
|
15997
16008
|
opacity: 0.8;
|
|
15998
16009
|
}
|
|
15999
16010
|
|
|
@@ -16026,8 +16037,8 @@ html.dark .mld-settings-modal__option-btn--active {
|
|
|
16026
16037
|
color: var(--mld-text-primary, #111827);
|
|
16027
16038
|
}
|
|
16028
16039
|
.mld-topbar-tab--active {
|
|
16029
|
-
background: var(--
|
|
16030
|
-
color: var(--
|
|
16040
|
+
background: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
16041
|
+
color: var(--color-primary, #6366F1);
|
|
16031
16042
|
}
|
|
16032
16043
|
.mld-topbar-tab--disabled {
|
|
16033
16044
|
opacity: 0.5;
|
|
@@ -16084,13 +16095,13 @@ html.dark .mld-settings-modal__option-btn--active {
|
|
|
16084
16095
|
border: none;
|
|
16085
16096
|
background: transparent;
|
|
16086
16097
|
border-radius: var(--mld-radius-sm, 0.25rem);
|
|
16087
|
-
color: #
|
|
16098
|
+
color: var(--color-primary, #6366F1);
|
|
16088
16099
|
cursor: pointer;
|
|
16089
16100
|
text-decoration: none;
|
|
16090
16101
|
transition: background-color 0.15s ease;
|
|
16091
16102
|
}
|
|
16092
16103
|
.mld-topbar__admin-btn:hover {
|
|
16093
|
-
background:
|
|
16104
|
+
background: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
16094
16105
|
}
|
|
16095
16106
|
.mld-topbar__admin-icon {
|
|
16096
16107
|
width: 1.25rem;
|
|
@@ -16122,7 +16133,7 @@ html.dark .mld-settings-modal__option-btn--active {
|
|
|
16122
16133
|
font-size: 0.75rem;
|
|
16123
16134
|
font-weight: 500;
|
|
16124
16135
|
color: white;
|
|
16125
|
-
background: linear-gradient(135deg, #
|
|
16136
|
+
background: linear-gradient(135deg, var(--color-primary-hover, #4F46E5) 0%, var(--color-primary, #6366F1) 100%);
|
|
16126
16137
|
flex-shrink: 0;
|
|
16127
16138
|
}
|
|
16128
16139
|
.mld-topbar__profile-name {
|
package/package.json
CHANGED
package/src/composables/index.ts
CHANGED
|
@@ -86,6 +86,7 @@ export {
|
|
|
86
86
|
} from './useTimeUtils'
|
|
87
87
|
export { useScheduleDrag } from './useScheduleDrag'
|
|
88
88
|
export { useFormBuilder, evaluateCondition } from './useFormBuilder'
|
|
89
|
+
export { usePluginConfig, type UsePluginConfigReturn } from './usePluginConfig'
|
|
89
90
|
export {
|
|
90
91
|
getFieldRegistryEntry,
|
|
91
92
|
getTypeDefault,
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ref, computed, onMounted, type Ref, type ComputedRef } from 'vue'
|
|
2
|
+
import { useApi } from './useApi'
|
|
3
|
+
import { usePlatformContext } from './usePlatformContext'
|
|
4
|
+
|
|
5
|
+
export interface UsePluginConfigReturn {
|
|
6
|
+
config: Ref<Record<string, unknown>>
|
|
7
|
+
isLoading: Ref<boolean>
|
|
8
|
+
isSaving: Ref<boolean>
|
|
9
|
+
error: Ref<string | null>
|
|
10
|
+
isDirty: ComputedRef<boolean>
|
|
11
|
+
load: () => Promise<void>
|
|
12
|
+
save: () => Promise<boolean>
|
|
13
|
+
reset: () => void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function usePluginConfig(pluginName?: string): UsePluginConfigReturn {
|
|
17
|
+
const api = useApi()
|
|
18
|
+
const { plugin } = usePlatformContext()
|
|
19
|
+
|
|
20
|
+
const resolvedName = computed(() => pluginName ?? plugin.value?.name ?? '')
|
|
21
|
+
|
|
22
|
+
const config = ref<Record<string, unknown>>({})
|
|
23
|
+
const savedConfig = ref<Record<string, unknown>>({})
|
|
24
|
+
const isLoading = ref(false)
|
|
25
|
+
const isSaving = ref(false)
|
|
26
|
+
const error = ref<string | null>(null)
|
|
27
|
+
|
|
28
|
+
const isDirty = computed(() => {
|
|
29
|
+
return JSON.stringify(config.value) !== JSON.stringify(savedConfig.value)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
async function load(): Promise<void> {
|
|
33
|
+
const name = resolvedName.value
|
|
34
|
+
if (!name) return
|
|
35
|
+
|
|
36
|
+
isLoading.value = true
|
|
37
|
+
error.value = null
|
|
38
|
+
try {
|
|
39
|
+
const response = await api.get<{ plugin_name: string; config: Record<string, unknown> }>(
|
|
40
|
+
`/api/plugins/${encodeURIComponent(name)}/config`,
|
|
41
|
+
)
|
|
42
|
+
config.value = { ...response.config }
|
|
43
|
+
savedConfig.value = { ...response.config }
|
|
44
|
+
} catch (e) {
|
|
45
|
+
error.value = e instanceof Error ? e.message : 'Failed to load plugin config'
|
|
46
|
+
} finally {
|
|
47
|
+
isLoading.value = false
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function save(): Promise<boolean> {
|
|
52
|
+
const name = resolvedName.value
|
|
53
|
+
if (!name) return false
|
|
54
|
+
|
|
55
|
+
isSaving.value = true
|
|
56
|
+
error.value = null
|
|
57
|
+
try {
|
|
58
|
+
const response = await api.put<{ plugin_name: string; config: Record<string, unknown> }>(
|
|
59
|
+
`/api/plugins/${encodeURIComponent(name)}/config`,
|
|
60
|
+
{ config: config.value },
|
|
61
|
+
)
|
|
62
|
+
config.value = { ...response.config }
|
|
63
|
+
savedConfig.value = { ...response.config }
|
|
64
|
+
return true
|
|
65
|
+
} catch (e) {
|
|
66
|
+
error.value = e instanceof Error ? e.message : 'Failed to save plugin config'
|
|
67
|
+
return false
|
|
68
|
+
} finally {
|
|
69
|
+
isSaving.value = false
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function reset(): void {
|
|
74
|
+
config.value = { ...savedConfig.value }
|
|
75
|
+
error.value = null
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
onMounted(() => {
|
|
79
|
+
load()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
config,
|
|
84
|
+
isLoading,
|
|
85
|
+
isSaving,
|
|
86
|
+
error,
|
|
87
|
+
isDirty,
|
|
88
|
+
load,
|
|
89
|
+
save,
|
|
90
|
+
reset,
|
|
91
|
+
}
|
|
92
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
.mld-topbar__logo-icon {
|
|
50
50
|
width: 2rem;
|
|
51
51
|
height: 2rem;
|
|
52
|
-
background-color: var(--color-primary, #
|
|
52
|
+
background-color: var(--color-primary, #6366F1);
|
|
53
53
|
border-radius: 0.5rem;
|
|
54
54
|
display: flex;
|
|
55
55
|
align-items: center;
|
|
@@ -199,8 +199,8 @@
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
.mld-topbar-dropdown-item--active {
|
|
202
|
-
background: var(--
|
|
203
|
-
color: var(--
|
|
202
|
+
background: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
203
|
+
color: var(--color-primary, #6366F1);
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
.mld-topbar-dropdown-item--disabled {
|
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
.mld-topbar-dropdown-item--active .mld-topbar-dropdown-item__description {
|
|
222
|
-
color: var(--
|
|
222
|
+
color: var(--color-primary, #6366F1);
|
|
223
223
|
opacity: 0.8;
|
|
224
224
|
}
|
|
225
225
|
|
|
@@ -256,8 +256,8 @@
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
.mld-topbar-tab--active {
|
|
259
|
-
background: var(--
|
|
260
|
-
color: var(--
|
|
259
|
+
background: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
260
|
+
color: var(--color-primary, #6366F1);
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
.mld-topbar-tab--disabled {
|
|
@@ -320,14 +320,14 @@
|
|
|
320
320
|
border: none;
|
|
321
321
|
background: transparent;
|
|
322
322
|
border-radius: var(--mld-radius-sm, 0.25rem);
|
|
323
|
-
color: #
|
|
323
|
+
color: var(--color-primary, #6366F1);
|
|
324
324
|
cursor: pointer;
|
|
325
325
|
text-decoration: none;
|
|
326
326
|
transition: background-color 0.15s ease;
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
.mld-topbar__admin-btn:hover {
|
|
330
|
-
background:
|
|
330
|
+
background: var(--color-primary-soft, rgba(99, 102, 241, 0.12));
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
.mld-topbar__admin-icon {
|
|
@@ -362,7 +362,7 @@
|
|
|
362
362
|
font-size: 0.75rem;
|
|
363
363
|
font-weight: 500;
|
|
364
364
|
color: white;
|
|
365
|
-
background: linear-gradient(135deg, #
|
|
365
|
+
background: linear-gradient(135deg, var(--color-primary-hover, #4F46E5) 0%, var(--color-primary, #6366F1) 100%);
|
|
366
366
|
flex-shrink: 0;
|
|
367
367
|
}
|
|
368
368
|
|
|
@@ -8,9 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
.mld-form-field__label {
|
|
10
10
|
display: block;
|
|
11
|
-
font-size: 0.
|
|
12
|
-
font-weight:
|
|
13
|
-
|
|
11
|
+
font-size: 0.6875rem;
|
|
12
|
+
font-weight: 600;
|
|
13
|
+
text-transform: uppercase;
|
|
14
|
+
letter-spacing: 0.05em;
|
|
15
|
+
color: var(--text-secondary);
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
.mld-form-field__required {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
.mld-number-input {
|
|
4
4
|
display: inline-flex;
|
|
5
|
+
max-width: 100%;
|
|
5
6
|
border-radius: 0.5rem;
|
|
6
7
|
border: 1px solid var(--border-color);
|
|
7
8
|
overflow: hidden;
|
|
@@ -42,6 +43,7 @@
|
|
|
42
43
|
display: flex;
|
|
43
44
|
align-items: center;
|
|
44
45
|
justify-content: center;
|
|
46
|
+
flex-shrink: 0;
|
|
45
47
|
background-color: var(--bg-tertiary);
|
|
46
48
|
color: var(--text-muted);
|
|
47
49
|
border: none;
|
|
@@ -85,7 +87,8 @@
|
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
.mld-number-input__input {
|
|
88
|
-
|
|
90
|
+
flex: 1;
|
|
91
|
+
min-width: 0;
|
|
89
92
|
text-align: center;
|
|
90
93
|
background-color: var(--bg-secondary);
|
|
91
94
|
color: var(--text-primary);
|
package/src/styles/variables.css
CHANGED
|
@@ -24,8 +24,9 @@
|
|
|
24
24
|
--text-muted: #94A3B8;
|
|
25
25
|
|
|
26
26
|
/* Brand colors */
|
|
27
|
-
--color-primary: #
|
|
28
|
-
--color-primary-hover: #
|
|
27
|
+
--color-primary: #6366F1;
|
|
28
|
+
--color-primary-hover: #4F46E5;
|
|
29
|
+
--color-primary-soft: rgba(99, 102, 241, 0.12);
|
|
29
30
|
--color-cta: #F97316;
|
|
30
31
|
--color-cta-hover: #EA580C;
|
|
31
32
|
--color-purple: #8B5CF6;
|
|
@@ -308,7 +309,7 @@ code, pre {
|
|
|
308
309
|
|
|
309
310
|
.input-modern:focus {
|
|
310
311
|
border-color: var(--color-primary);
|
|
311
|
-
box-shadow: 0 0 0 3px rgba(
|
|
312
|
+
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
|
|
312
313
|
}
|
|
313
314
|
|
|
314
315
|
.input-modern::placeholder {
|
|
@@ -341,7 +342,7 @@ code, pre {
|
|
|
341
342
|
|
|
342
343
|
.select-modern:focus {
|
|
343
344
|
border-color: var(--color-primary);
|
|
344
|
-
box-shadow: 0 0 0 3px rgba(
|
|
345
|
+
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
|
|
345
346
|
}
|
|
346
347
|
|
|
347
348
|
/* Label styles */
|
|
@@ -549,7 +550,7 @@ code, pre {
|
|
|
549
550
|
}
|
|
550
551
|
|
|
551
552
|
.bg-mld-primary {
|
|
552
|
-
background-color:
|
|
553
|
+
background-color: var(--color-primary);
|
|
553
554
|
}
|
|
554
555
|
|
|
555
556
|
.text-mld-primary {
|
|
@@ -561,11 +562,11 @@ code, pre {
|
|
|
561
562
|
}
|
|
562
563
|
|
|
563
564
|
.bg-mld-primary\/5 {
|
|
564
|
-
background-color: rgba(
|
|
565
|
+
background-color: rgba(99, 102, 241, 0.05);
|
|
565
566
|
}
|
|
566
567
|
|
|
567
568
|
.hover\:border-mld-primary\/50:hover {
|
|
568
|
-
border-color: rgba(
|
|
569
|
+
border-color: rgba(99, 102, 241, 0.5);
|
|
569
570
|
}
|
|
570
571
|
|
|
571
572
|
/* Danger/error color utilities */
|
|
@@ -638,11 +639,11 @@ code, pre {
|
|
|
638
639
|
}
|
|
639
640
|
|
|
640
641
|
.bg-mld-primary\/10 {
|
|
641
|
-
background-color: rgba(
|
|
642
|
+
background-color: rgba(99, 102, 241, 0.1);
|
|
642
643
|
}
|
|
643
644
|
|
|
644
645
|
.hover\:bg-mld-primary\/20:hover {
|
|
645
|
-
background-color: rgba(
|
|
646
|
+
background-color: rgba(99, 102, 241, 0.2);
|
|
646
647
|
}
|
|
647
648
|
|
|
648
649
|
.bg-mld-info {
|
|
@@ -681,11 +682,11 @@ code, pre {
|
|
|
681
682
|
}
|
|
682
683
|
|
|
683
684
|
.text-mld-primary\/80 {
|
|
684
|
-
color: rgba(
|
|
685
|
+
color: rgba(99, 102, 241, 0.8);
|
|
685
686
|
}
|
|
686
687
|
|
|
687
688
|
.hover\:text-mld-primary\/70:hover {
|
|
688
|
-
color: rgba(
|
|
689
|
+
color: rgba(99, 102, 241, 0.7);
|
|
689
690
|
}
|
|
690
691
|
|
|
691
692
|
/* ==========================================================================
|