Skip to content

Commit 948063c

Browse files
Resul AvanResul Avan
authored andcommitted
following privacy initial
1 parent 6914432 commit 948063c

File tree

12 files changed

+309
-84
lines changed

12 files changed

+309
-84
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<template>
2+
<div class="box">
3+
4+
<ValidationObserver v-slot="{ passes }" tag="form">
5+
6+
<PrivacyDropdown v-model="updatedUser.privacy"
7+
:label="$t('privacy.account.field')"
8+
privacy-for="account"
9+
rules="required"
10+
label-position="on-border"
11+
vid="privacy"
12+
class="has-margin-10"/>
13+
14+
<PrivacyDropdown v-model="updatedUser.followersPrivacy"
15+
:label="$t('privacy.followers.field')"
16+
privacy-for="followers"
17+
rules="required"
18+
label-position="on-border"
19+
vid="privacy"
20+
class="has-margin-10"/>
21+
22+
<PrivacyDropdown v-model="updatedUser.followingPrivacy"
23+
:label="$t('privacy.following.field')"
24+
privacy-for="following"
25+
rules="required"
26+
label-position="on-border"
27+
vid="privacy"
28+
class="has-margin-10"/>
29+
30+
<div class="buttons">
31+
<b-button type="is-primary" icon-pack="fas"
32+
icon-left="user-edit"
33+
@click="passes(submit)">
34+
{{ $t('form.profileUpdate.submit')}}
35+
</b-button>
36+
</div>
37+
38+
</ValidationObserver>
39+
</div>
40+
</template>
41+
42+
<script lang="ts">
43+
import { Component, Prop, Vue, Watch } from 'nuxt-property-decorator';
44+
import { ValidationObserver } from "vee-validate";
45+
import { StateNamespace, User } from '~/types';
46+
import InputWithValidation from "~/components/ui/input/InputWithValidation.vue";
47+
import InputNoValidation from '~/components/ui/input/InputNoValidation.vue';
48+
import FieldWithValue from '~/components/ui/FieldWithValue.vue';
49+
import { slugify } from '~/service/global-service';
50+
import { getDangerNotificationMessage, showSuccessToaster } from '~/service/notification-service';
51+
import { handleError } from '~/service/error-service';
52+
import PrivacyDropdown from '~/components/ui/dropdown/PrivacyDropdown.vue';
53+
import { reloadUserFromDatabase } from '~/service/rx-service';
54+
55+
@Component({
56+
components: { PrivacyDropdown, FieldWithValue, InputNoValidation, ValidationObserver, InputWithValidation }
57+
})
58+
export default class ProfilePrivacyForm extends Vue {
59+
60+
@Prop({ required: true }) user !: User
61+
updatedUser = { ...this.user }
62+
63+
@StateNamespace.profile.Action updateUser !: (user: User) => Promise<User>;
64+
@StateNamespace.loading.Action saveLoading !: (loading: boolean) => Promise<void>
65+
66+
@Watch('updatedUser.username', { deep: true })
67+
onUsernameChange(username: string, oldUsername: string) {
68+
this.updatedUser.username = slugify(username)
69+
}
70+
71+
submit() {
72+
this.saveLoading(true)
73+
.then(async () => {
74+
return await this.updateUser(this.updatedUser)
75+
})
76+
.then(async (savedUser: User) => {
77+
if (!savedUser) {
78+
return
79+
}
80+
reloadUserFromDatabase.next()
81+
showSuccessToaster(this.$t('notification.profile.updated'))
82+
})
83+
.catch((error: Error) =>
84+
handleError(this.$store.dispatch, error, getDangerNotificationMessage(this.$i18n.t('notification.profile.updateFailed')))
85+
)
86+
.finally(() => this.saveLoading(false))
87+
}
88+
}
89+
</script>

src/components/form/ProfileUpdateForm.vue

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,6 @@
1919
class="has-margin-bottom-15"
2020
/>
2121

22-
<PrivacyDropdown v-model="updatedUser.privacy"
23-
:label="$t('common.field.privacy')"
24-
rules="required"
25-
label-position="on-border"
26-
vid="privacy"
27-
class="has-margin-5"/>
28-
2922
<InputWithValidation
3023
v-model="updatedUser.username"
3124
:label="$t('common.field.username')"
@@ -82,22 +75,21 @@
8275
import { Component, Prop, Vue, Watch } from 'nuxt-property-decorator';
8376
import { ValidationObserver } from "vee-validate";
8477
import { StateNamespace, User } from '~/types';
85-
import InputWithValidation from "~/components/ui/input/InputWithValidation.vue";
86-
import InputNoValidation from '~/components/ui/input/InputNoValidation.vue';
87-
import FieldWithValue from '~/components/ui/FieldWithValue.vue';
8878
import { slugify } from '~/service/global-service';
8979
import { getDangerNotificationMessage, showSuccessToaster } from '~/service/notification-service';
9080
import { handleError } from '~/service/error-service';
91-
import PrivacyDropdown from '~/components/ui/dropdown/PrivacyDropdown.vue';
9281
import { reloadUserFromDatabase } from '~/service/rx-service';
82+
import InputWithValidation from "~/components/ui/input/InputWithValidation.vue";
83+
import InputNoValidation from '~/components/ui/input/InputNoValidation.vue';
84+
import FieldWithValue from '~/components/ui/FieldWithValue.vue';
9385
9486
@Component({
95-
components: { PrivacyDropdown, FieldWithValue, InputNoValidation, ValidationObserver, InputWithValidation }
87+
components: { FieldWithValue, InputNoValidation, ValidationObserver, InputWithValidation }
9688
})
9789
export default class ProfileUpdateForm extends Vue {
9890
9991
@Prop({ required: true }) user !: User
100-
updatedUser = this.user
92+
updatedUser = { ...this.user }
10193
10294
@StateNamespace.profile.Action updateUser !: (user: User) => Promise<User>;
10395
@StateNamespace.loading.Action saveLoading !: (loading: boolean) => Promise<void>

src/components/profile/header/ProfileFollow.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,11 @@
170170
}
171171
172172
showFollowers() {
173-
showProfileModule.next(ModuleType.ProfileFollowers)
173+
showProfileModule.next(ModuleType.FOLLOWERS)
174174
}
175175
176176
showFollowings() {
177-
showProfileModule.next(ModuleType.ProfileFollowings)
177+
showProfileModule.next(ModuleType.FOLLOWINGS)
178178
}
179179
180180
}

src/components/profile/header/ProfilePrivacy.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
:icon="userPrivacyConfig.icon"
66
size="is-small">
77
</b-icon>
8-
{{$t(`privacy.${userPrivacyConfig.privacyType}.title`)}}
8+
{{$t(`privacy.account.${userPrivacyConfig.privacyType}.title`)}}
99
</b-tag>
10-
<b-tag type="is-light">{{$t(`privacy.${userPrivacyConfig.privacyType}.subtitle`)}}
11-
<b-tooltip :label="$t(`privacy.${userPrivacyConfig.privacyType}.description`)" position="is-left" multilined>
10+
<b-tag type="is-light">{{$t(`privacy.account.${userPrivacyConfig.privacyType}.subtitle`)}}
11+
<b-tooltip :label="$t(`privacy.account.${userPrivacyConfig.privacyType}.description`)" position="is-left" multilined>
1212
<b-icon
1313
icon="information"
1414
size="is-small">

src/components/profile/module/ProfileModule.vue

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
<div class="column is-half">
66
<b-tabs type="is-toggle-rounded" size="is-small" v-model="moduleType" expanded>
77
<b-tab-item v-for="(moduleConfig, key) in computedModuleConfigs" :key="key"
8-
:label="$t(`module.${moduleConfig.moduleType}`)"
8+
:label="$t(`module.${moduleConfig.type}`)"
99
:icon="moduleConfig.icon"
10-
:value="moduleConfig.moduleType">
10+
:value="moduleConfig.type">
1111
</b-tab-item>
1212
</b-tabs>
1313
</div>
1414
</div>
1515

1616
<div class="columns">
1717
<div class="column">
18-
<component :is="moduleConfig.module" v-bind="componentProperties"/>
18+
<component v-if="moduleConfig" :is="moduleConfig.component" v-bind="componentProperties"/>
1919
</div>
2020
</div>
2121

@@ -24,7 +24,7 @@
2424

2525
<script lang="ts">
2626
import { Component } from 'nuxt-property-decorator';
27-
import { ModuleConfig, ModuleType } from '~/types';
27+
import { ModuleTabConfig, ModuleType } from '~/types';
2828
import BaseModule from '~/mixin/BaseModule';
2929
import ProfileAboutMe from '~/components/profile/module/ProfileAboutMe.vue';
3030
import LinkedAccounts from '~/components/profile/module/LinkedAccounts.vue';
@@ -38,43 +38,37 @@
3838
})
3939
export default class ProfileModule extends BaseModule {
4040
41-
moduleType = ModuleType.ProfileAboutMe
41+
moduleType = ModuleType.ABOUT_ME
4242
43-
componentProperties = {
44-
isMyProfile: this.isMyProfile,
45-
authUser: this.authUser,
46-
user: this.user
47-
}
48-
49-
moduleConfigs: ModuleConfig<any>[] = [
43+
moduleConfigs: ModuleTabConfig[] = [
5044
{
51-
moduleType: ModuleType.ProfileAboutMe,
45+
type: ModuleType.ABOUT_ME,
5246
icon: 'account-details',
53-
module: ProfileAboutMe,
47+
component: ProfileAboutMe,
5448
private: false
5549
},
5650
{
57-
moduleType: ModuleType.LinkedAccounts,
51+
type: ModuleType.LINKED_ACCOUNTS,
5852
icon: 'link-variant',
59-
module: LinkedAccounts,
53+
component: LinkedAccounts,
6054
private: true
6155
},
6256
{
63-
moduleType: ModuleType.ProfileFollowers,
57+
type: ModuleType.FOLLOWERS,
6458
icon: 'account-arrow-left',
65-
module: ProfileFollowers,
59+
component: ProfileFollowers,
6660
private: true
6761
},
6862
{
69-
moduleType: ModuleType.ProfileFollowings,
63+
type: ModuleType.FOLLOWINGS,
7064
icon: 'account-arrow-right',
71-
module: ProfileFollowings,
65+
component: ProfileFollowings,
7266
private: true
7367
},
7468
{
75-
moduleType: ModuleType.ProfileSettings,
69+
type: ModuleType.SETTINGS,
7670
icon: 'cog',
77-
module: ProfileSettings,
71+
component: ProfileSettings,
7872
private: true
7973
}
8074
]
@@ -86,12 +80,22 @@
8680
}
8781
8882
get moduleConfig() {
89-
return this.moduleConfigs.find(moduleConfig => moduleConfig.moduleType === this.moduleType)
83+
return this.moduleConfigs.find(moduleConfig => moduleConfig.type === this.moduleType)
9084
}
9185
9286
get computedModuleConfigs() {
9387
return this.moduleConfigs.filter(moduleConfig => !moduleConfig.private || this.isMyProfile)
9488
}
9589
90+
get componentProperties() {
91+
return this.moduleConfig?.componentProperties ?
92+
this.moduleConfig.componentProperties :
93+
{
94+
isMyProfile: this.isMyProfile,
95+
authUser: this.authUser,
96+
user: this.user
97+
}
98+
}
99+
96100
}
97101
</script>
Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,67 @@
11
<template>
22
<div class="container">
3-
<div class="columns is-centered">
3+
<div class="columns">
4+
<div class="column is-3">
5+
<b-menu>
6+
<b-menu-list>
7+
<b-menu-item v-for="(setting,index) in settingsMenuConfigs" :key="index" :icon="setting.icon"
8+
:active="settingsType === setting.type" :label="$t(`settings.${setting.type}`)"
9+
@click="settingsType = setting.type"/>
10+
</b-menu-list>
11+
</b-menu>
12+
</div>
413
<div class="column is-half">
5-
<ProfileUpdateForm :user="user"/>
14+
<component v-if="settingsMenuConfig" :is="settingsMenuConfig.component" v-bind="componentProperties"/>
615
</div>
716
</div>
817
</div>
918
</template>
1019

1120
<script lang="ts">
1221
import { Component } from 'nuxt-property-decorator';
13-
import ProfileUpdateForm from '~/components/form/ProfileUpdateForm.vue';
1422
import { reloadUserFromDatabase } from '~/service/rx-service';
23+
import { SettingsMenuConfig, SettingsType } from '~/types';
1524
import BaseModule from '~/mixin/BaseModule';
25+
import ProfileUpdateForm from '~/components/form/ProfileUpdateForm.vue';
26+
import ProfilePrivacyForm from '~/components/form/ProfilePrivacyForm.vue';
1627
1728
@Component({
18-
components: { ProfileUpdateForm }
29+
components: { ProfileUpdateForm, ProfilePrivacyForm }
1930
})
2031
export default class ProfileSettings extends BaseModule {
2132
33+
settingsType = SettingsType.GENERAL
34+
35+
settingsMenuConfigs: SettingsMenuConfig[] = [
36+
{
37+
type: SettingsType.GENERAL,
38+
icon: 'cogs',
39+
component: ProfileUpdateForm,
40+
private: true
41+
},
42+
{
43+
type: SettingsType.PRIVACY,
44+
icon: 'account-lock',
45+
component: ProfilePrivacyForm,
46+
private: true
47+
}
48+
]
49+
2250
created() {
2351
reloadUserFromDatabase.next()
2452
}
2553
54+
get settingsMenuConfig() {
55+
return this.settingsMenuConfigs.find(setting => setting.type === this.settingsType)
56+
}
57+
58+
get componentProperties() {
59+
return this.settingsMenuConfig?.componentProperties ?
60+
this.settingsMenuConfig.componentProperties :
61+
{
62+
user: this.user
63+
}
64+
}
65+
2666
}
2767
</script>

src/components/ui/dropdown/PrivacyDropdown.vue

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717
<b-dropdown :value="value" @input="input" aria-role="list" class="has-margin-top-10">
1818
<b-button v-if="selectedPrivacyType" slot="trigger" :class="selectedPrivacyType.type" :outlined="!value">
1919
<b-icon :icon="selectedPrivacyType.icon" class="has-margin-left-5"/>
20-
<span class="has-margin-left-5">{{$t(`privacy.${selectedPrivacyType.privacyType}.title`)}}</span>
20+
<span
21+
class="has-margin-left-5">{{$t(`privacy.${privacyFor}.${selectedPrivacyType.privacyType}.title`)}}</span>
2122
<b-icon icon="menu-down"></b-icon>
2223
</b-button>
2324

2425
<b-button v-else slot="trigger" class="is-primary" :outlined="!value">
25-
<b-icon icon="account-remove-outline" class="has-margin-left-5"/>
26-
<span class="has-margin-left-5">{{$t(`privacy.notSelected`)}}</span>
26+
<b-icon icon="account-lock-outline" class="has-margin-left-5"/>
27+
<span class="has-margin-left-5">{{$t(`privacy.${privacyFor}.notSelected`)}}</span>
2728
<b-icon icon="menu-down"></b-icon>
2829
</b-button>
2930

@@ -34,14 +35,16 @@
3435
<div class="media" :class="privacy.type">
3536
<b-icon class="media-left" :icon="privacy.icon"></b-icon>
3637
<div class="media-content">
37-
<h3>{{$t(`privacy.${privacy.privacyType}.title`)}}</h3>
38-
<h4>{{$t(`privacy.${privacy.privacyType}.subtitle`)}}</h4>
39-
<small>{{$t(`privacy.${privacy.privacyType}.description`)}}</small>
38+
<h3>{{$t(`privacy.${privacyFor}.${privacy.privacyType}.title`)}}</h3>
39+
<h4>{{$t(`privacy.${privacyFor}.${privacy.privacyType}.subtitle`)}}</h4>
40+
<small>{{$t(`privacy.${privacyFor}.${privacy.privacyType}.description`)}}</small>
4041
</div>
4142
</div>
4243
</b-dropdown-item>
4344
</b-dropdown>
44-
<small v-if="value" class="has-margin-top-5 has-margin-left-5">{{$t(`privacy.${value}.description`)}}</small>
45+
<small v-if="value" class="has-margin-top-5 has-margin-left-5">
46+
{{$t(`privacy.${privacyFor}.${value}.description`)}}
47+
</small>
4548
</b-field>
4649
</ValidationProvider>
4750
</template>
@@ -60,6 +63,7 @@
6063
6164
@Prop({ type: String, required: true }) vid !: string;
6265
@Prop({ type: String, required: true }) rules !: string;
66+
@Prop({ type: String, required: true }) privacyFor !: string;
6367
@Prop({ type: Boolean, required: false, default: false }) horizontal !: boolean;
6468
@Prop({ type: Boolean, required: false, default: false }) disabled !: boolean;
6569
@Prop({ type: String, required: false, default: '' }) labelPosition !: string;
@@ -77,6 +81,10 @@
7781
return PrivacyList
7882
}
7983
84+
get label() {
85+
return this.$t(`privacy.${this.privacyFor}.field`)
86+
}
87+
8088
}
8189
8290
</script>

0 commit comments

Comments
 (0)