Skip to content

Commit

Permalink
Merge pull request #284 from jellyfin/YourAWizardHarry
Browse files Browse the repository at this point in the history
Startup Wizard - Addition of Startup Wizard
  • Loading branch information
heyhippari authored Jan 15, 2021
2 parents 3e40b04 + 8454395 commit ef41d6d
Show file tree
Hide file tree
Showing 8 changed files with 506 additions and 2 deletions.
97 changes: 97 additions & 0 deletions components/wizard/WizardAdminAccount.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<template>
<validation-observer v-slot="{ invalid }">
<v-form ref="form" v-model="validInputs">
<validation-provider v-slot="{ errors }" name="username" rules="required">
<v-text-field
v-model="admin.Name"
outlined
:label="$t('username')"
type="username"
:error-messages="errors"
required
></v-text-field>
</validation-provider>
<validation-provider
v-slot="{ errors }"
rules="bothPasswordsSame:@confirm"
>
<v-text-field
v-model="admin.Password"
outlined
:label="$t('password')"
:append-icon="showPassword ? 'mdi-eye-off' : 'mdi-eye'"
:type="showPassword ? 'text' : 'password'"
:error-messages="errors"
@click:append="() => (showPassword = !showPassword)"
></v-text-field>
</validation-provider>

<validation-provider v-slot="{ errors }" name="confirm" rules="">
<v-text-field
v-model="passwordCheck"
outlined
:label="$t('wizard.confirmPassword')"
:append-icon="showPassword ? 'mdi-eye-off' : 'mdi-eye'"
:type="showPassword ? 'text' : 'password'"
:error-messages="errors"
@click:append="() => (showPassword = !showPassword)"
></v-text-field>
</validation-provider>

<v-btn color="secondary" @click="$emit('previous-step', { step: 2 })">
{{ $t('previous') }}
</v-btn>
<v-btn
color="primary"
:disabled="invalid"
:loading="loading"
@click="createAdminAccount"
>
{{ $t('next') }}
</v-btn>
</v-form>
</validation-observer>
</template>

<script lang="ts">
import Vue from 'vue';
import { mapActions } from 'vuex';
export default Vue.extend({
data() {
return {
admin: {
Name: '',
Password: ''
},
passwordCheck: '',
showPassword: false,
loading: false
};
},
methods: {
...mapActions('snackbar', ['pushSnackbarMessage']),
async createAdminAccount(): Promise<void> {
this.loading = true;
try {
const token = `MediaBrowser Client="${this.$store.state.deviceProfile.clientName}", Device="${this.$store.state.deviceProfile.deviceName}", DeviceId="${this.$store.state.deviceProfile.deviceId}", Version="${this.$store.state.deviceProfile.clientVersion}"`;
this.$auth.ctx.app.$axios.setHeader('X-Emby-Authorization', token);
await this.$api.startup.updateStartupUser({
startupUserDto: this.admin
});
this.$emit('step-complete', { step: 2 });
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
this.pushSnackbarMessage({
message: this.$t('wizard.setAdminError'),
color: 'error'
});
}
this.loading = false;
}
}
});
</script>
81 changes: 81 additions & 0 deletions components/wizard/WizardLanguage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<template>
<div>
<v-select
v-model="UICulture"
:loading="loading"
outlined
:label="$t('wizard.preferedLanguage')"
required
item-text="Name"
item-value="Value"
:items="culturesList"
/>
<v-btn color="primary" @click="setLanguage">
{{ $t('next') }}
</v-btn>
</div>
</template>

<script lang="ts">
import Vue from 'vue';
import { mapActions } from 'vuex';
import {
LocalizationOption,
StartupConfigurationDto
} from '@jellyfin/client-axios';
export default Vue.extend({
auth: false,
data() {
return {
UICulture: 'en-GB',
culturesList: [] as LocalizationOption[],
initialConfig: {} as StartupConfigurationDto,
loading: false
};
},
async created() {
this.loading = true;
try {
this.initialConfig = (
await this.$api.startup.getStartupConfiguration()
).data;
this.UICulture = this.initialConfig?.UICulture || 'en-GB';
this.culturesList = (
await this.$api.localization.getLocalizationOptions()
).data;
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
this.loading = false;
},
methods: {
...mapActions('snackbar', ['pushSnackbarMessage']),
async setLanguage(): Promise<void> {
this.loading = true;
try {
this.$i18n.setLocale(this.UICulture);
await this.$api.startup.updateInitialConfiguration({
startupConfigurationDto: {
...this.initialConfig,
UICulture: this.UICulture
}
});
this.$emit('step-complete', { step: 1 });
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
this.pushSnackbarMessage({
message: this.$t('wizard.setLanguageError'),
color: 'error'
});
}
this.loading = false;
}
}
});
</script>
87 changes: 87 additions & 0 deletions components/wizard/WizardMetadata.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<template>
<div>
<v-select
v-model="metadataLanguage"
outlined
:label="$t('metadataLanguage')"
required
item-text="DisplayName"
item-value="TwoLetterISOLanguageName"
:items="cultureOptions"
/>
<v-select
v-model="metadataCountry"
outlined
:label="$t('metadataCountry')"
required
item-text="DisplayName"
item-value="TwoLetterISORegionName"
:items="countryOptions"
/>
<v-btn color="secondary" @click="$emit('previous-step', { step: 2 })">
{{ $t('previous') }}
</v-btn>
<v-btn :loading="loading" color="primary" @click="setMetadata">{{
$t('next')
}}</v-btn>
</div>
</template>

<script lang="ts">
import {
CountryInfo,
CultureDto,
StartupConfigurationDto
} from '@jellyfin/client-axios';
import Vue from 'vue';
import { mapActions } from 'vuex';
export default Vue.extend({
data() {
return {
metadataLanguage: '',
metadataCountry: '',
initialConfig: {} as StartupConfigurationDto,
cultureOptions: [] as CultureDto[],
countryOptions: [] as CountryInfo[],
loading: false
};
},
async created() {
this.initialConfig = (
await this.$api.startup.getStartupConfiguration()
).data;
this.metadataLanguage = this.initialConfig?.MetadataCountryCode || '';
this.metadataCountry = this.initialConfig?.PreferredMetadataLanguage || '';
this.cultureOptions = (await this.$api.localization.getCultures()).data;
this.countryOptions = (await this.$api.localization.getCountries()).data;
},
methods: {
...mapActions('snackbar', ['pushSnackbarMessage']),
async setMetadata(): Promise<void> {
this.loading = true;
try {
await this.$api.startup.updateInitialConfiguration({
startupConfigurationDto: {
...this.initialConfig,
MetadataCountryCode: this.metadataLanguage,
PreferredMetadataLanguage: this.metadataCountry
}
});
this.$emit('step-complete', { step: 3 });
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
this.pushSnackbarMessage({
message: this.$t('wizard.setMetadataError'),
color: 'error'
});
}
this.loading = false;
}
}
});
</script>
54 changes: 54 additions & 0 deletions components/wizard/WizardRemoteAccess.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<template>
<div>
<v-checkbox
v-model="allowRemoteAccess"
:label="$t('wizard.allowRemoteAccess')"
/>
<v-checkbox v-model="enableUPNP" :label="$t('enableUPNP')" />
<v-btn color="secondary" @click="$emit('previous-step')">
{{ $t('previous') }}
</v-btn>
<v-btn :loading="loading" color="primary" @click="setRemoteAccess">
{{ $t('finish') }}
</v-btn>
</div>
</template>

<script lang="ts">
import Vue from 'vue';
import { mapActions } from 'vuex';
export default Vue.extend({
data() {
return {
allowRemoteAccess: false,
enableUPNP: false,
loading: false
};
},
methods: {
...mapActions('snackbar', ['pushSnackbarMessage']),
async setRemoteAccess(): Promise<void> {
this.loading = true;
try {
await this.$api.startup.setRemoteAccess({
startupRemoteAccessDto: {
EnableRemoteAccess: this.allowRemoteAccess,
EnableAutomaticPortMapping: this.enableUPNP
}
});
this.$emit('step-complete', { step: 4 });
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
this.pushSnackbarMessage({
message: this.$t('wizard.setRemoteError'),
color: 'error'
});
}
this.loading = false;
}
}
});
</script>
22 changes: 21 additions & 1 deletion locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,33 @@
"usernameRequired": "Username is required",
"validation": {
"mustBeUrl": "This field must be a valid URL",
"required": "This field is required"
"required": "This field is required",
"bothPasswordsSame": "Both passwords must be the save"
},
"version": "Version",
"video": "Video",
"videoTypes": "Video Types",
"viewDetails": "View details",
"vueClientVersion": "Vue client version",
"wizard": {
"confirmPassword": "Confirm password",
"setupWizard": "Setup wizard",
"setAdminError": "Unable to create an admin account.",
"setLanguageError": "Unable to set client language.",
"setMetadataError": "Unable to set metadata languages.",
"setRemoteError": "Unable to set remote access settings.",
"languageSuccessfullySet": "Language successfully set.",
"userSuccessfullySet": "User successfully set.",
"metadataLanguagesSet": "Metadata languages set.",
"remoteAccessSet": "Remote access set.",
"completeError": "Unable to complete startup wizard.",
"preferredMetadataLanguage": "Preferred metadata language",
"preferedLanguage": "Prefered language",
"languageLocale": "Language and locale",
"administratorAccount": "Administrator account",
"allowRemoteAccess": "Allow remote access to the server",
"remoteAccess": "Remote Access"
},
"writer": "Writer",
"writing": "Writing",
"year": "Year",
Expand Down
Loading

0 comments on commit ef41d6d

Please sign in to comment.