Files
api/web/components/Activation/WelcomeModal.ce.vue
Eli Bosley 3b00fec5fd chore: Remove legacy store modules and add new API key and reporting services (#1536)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added developer CLI tools for toggling GraphQL sandbox and modal
testing utilities.
* Introduced a "Show Activation Modal" developer component for UI
testing.
  * Added system initial setup detection and related GraphQL queries.
* Enhanced login and welcome pages with dynamic server info and initial
setup state.
  * Improved SSO button with internationalization and error handling.
* Added internal CLI admin API key management service and internal
GraphQL client service.
* Introduced comprehensive API report generation service for system and
service status.
* Added CLI commands and GraphQL mutations/queries for plugin and SSO
user management.
* Added new modal target components and improved teleport target
detection.

* **Enhancements**
* Refined modal dialog targeting and teleportation for flexible UI
placement.
* Updated modal components and stores for improved activation/welcome
modal control.
  * Improved plugin and SSO user management via CLI through GraphQL API.
* Refactored partner logo components to use props instead of store
dependencies.
  * Enhanced styling and accessibility for buttons and modals.
* Streamlined Tailwind CSS integration with shared styles and updated
theme variables.
* Improved GraphQL module configuration to avoid directive conflicts in
tests.
  * Adjusted Vite config for better dependency handling in test mode.
  * Improved error handling and logging in CLI commands and services.
* Reordered imports and refined component class bindings for UI
consistency.

* **Bug Fixes**
* Resolved issues with duplicate script tags and component registration
in the web UI.
* Fixed modal close button visibility and activation modal state
handling.
* Added error handling and logging improvements across CLI commands and
services.
  * Fixed newline issues in last-download-time fixture files.

* **Chores**
* Added and updated numerous tests for CLI commands, services, and UI
components.
* Updated translation files and localization resources for new UI
messages.
* Adjusted environment, configuration, and dependency files for improved
development and test workflows.
  * Cleaned up unused imports and mocks in tests.
  * Reorganized exports and barrel files in shared and UI modules.
  * Added integration and dependency resolution tests for core modules.

* **Removals & Refactoring**
* Removed legacy Redux state management, configuration, and UPnP logic
from the backend.
* Eliminated deprecated GraphQL subscriptions and client code related to
registration and mothership.
* Removed direct store manipulation and replaced with service-based
approaches in CLI commands.
  * Deleted unused or redundant test files and configuration listeners.
* Refactored SSO user service to consolidate add/remove operations into
a single update method.
* Simplified API key services with new methods for automatic key
management.
* Replaced direct plugin and SSO user service calls with GraphQL client
interactions in CLI commands.
* Removed complex theme fallback and dark mode CSS rules, replacing with
streamlined static theme variables.
* Cleaned up Tailwind CSS configuration and removed deprecated local
styles.
* Removed multiple internal utility files and replaced with simplified
or centralized implementations.
* Removed deprecated local configuration and synchronization files and
listeners.
  * Removed UPnP helper functions and job management classes.
* Refactored server resolver to dynamically construct local server data
internally.
* Removed CORS handler and replaced with simplified or externalized
logic.
* Removed store synchronization and registration event pubsub handling.
* Removed GraphQL client creation utilities for internal API
communication.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-25 15:07:37 -04:00

119 lines
3.2 KiB
Vue

<script setup lang="ts">
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { storeToRefs } from 'pinia';
import { BrandButton, Dialog } from '@unraid/ui';
import ActivationPartnerLogo from '~/components/Activation/ActivationPartnerLogo.vue';
import ActivationSteps from '~/components/Activation/ActivationSteps.vue';
import { useWelcomeModalDataStore } from '~/components/Activation/store/welcomeModalData';
import { useThemeStore } from '~/store/theme';
// Disable attribute inheritance to prevent modelValue from showing on root element
defineOptions({
inheritAttrs: false,
});
const { t } = useI18n();
const { partnerInfo, loading, isInitialSetup } = storeToRefs(useWelcomeModalDataStore());
const { setTheme } = useThemeStore();
(async () => {
try {
await setTheme();
} catch (error) {
console.error('Error setting theme:', error);
}
})();
const title = computed<string>(() =>
partnerInfo.value?.partnerName
? t(`Welcome to your new {0} system, powered by Unraid!`, [partnerInfo.value?.partnerName])
: t('Welcome to Unraid!')
);
const description = computed<string>(() =>
t(
`First, you'll create your device's login credentials, then you'll activate your Unraid license—your device's operating system (OS).`
)
);
const isLoginPage = computed(() => window.location.pathname.includes('login'));
// Initialize showModal based on conditions
const showModal = ref(isLoginPage.value || isInitialSetup.value);
// Template ref for the teleport container
const modalContainer = ref<HTMLElement>();
const dropdownHide = () => {
showModal.value = false;
};
const showWelcomeModal = () => {
showModal.value = true;
};
defineExpose({
showWelcomeModal,
});
</script>
<template>
<div>
<div ref="modalContainer" />
<Dialog
:to="modalContainer"
:model-value="showModal"
:show-footer="false"
:show-close-button="isLoginPage"
size="full"
class="bg-background"
@update:model-value="(value) => (showModal = value)"
>
<div
class="flex flex-col items-center justify-start"
:style="{
'--text-xs': '0.75rem',
'--text-sm': '0.875rem',
'--text-base': '1rem',
'--text-lg': '1.125rem',
'--text-xl': '1.25rem',
'--text-2xl': '1.5rem',
'--text-3xl': '1.875rem',
'--text-4xl': '2.25rem',
'--text-5xl': '3rem',
'--text-6xl': '3.75rem',
'--text-7xl': '4.5rem',
'--text-8xl': '6rem',
'--text-9xl': '8rem',
'--spacing': '0.25rem',
}"
>
<div v-if="partnerInfo?.hasPartnerLogo">
<ActivationPartnerLogo :partner-info="partnerInfo" />
</div>
<h1 class="text-center text-xl sm:text-2xl font-semibold mt-4">{{ title }}</h1>
<div class="sm:max-w-xl mx-auto my-12 text-center">
<p class="text-lg sm:text-xl opacity-75 text-center">{{ description }}</p>
</div>
<div class="flex flex-col">
<div class="mx-auto mb-10">
<BrandButton :text="t('Create a password')" :disabled="loading" @click="dropdownHide" />
</div>
<ActivationSteps :active-step="1" class="mt-6" />
</div>
</div>
</Dialog>
</div>
</template>