Refactor: Switch Settings index page to setup sugar (#8374)
* refactor(client): Make Settings index page use <script setup> * chore(client): address review comments
This commit is contained in:
		
							parent
							
								
									2442592ef1
								
							
						
					
					
						commit
						939773a5b9
					
				
					 1 changed files with 209 additions and 231 deletions
				
			
		|  | @ -22,8 +22,8 @@ | ||||||
| </MkSpacer> | </MkSpacer> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script setup lang="ts"> | ||||||
| import { computed, defineAsyncComponent, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue'; | import { computed, defineAsyncComponent, nextTick, onMounted, ref, watch } from 'vue'; | ||||||
| import { i18n } from '@/i18n'; | import { i18n } from '@/i18n'; | ||||||
| import MkInfo from '@/components/ui/info.vue'; | import MkInfo from '@/components/ui/info.vue'; | ||||||
| import MkSuperMenu from '@/components/ui/super-menu.vue'; | import MkSuperMenu from '@/components/ui/super-menu.vue'; | ||||||
|  | @ -34,241 +34,219 @@ import * as symbols from '@/symbols'; | ||||||
| import { instance } from '@/instance'; | import { instance } from '@/instance'; | ||||||
| import { $i } from '@/account'; | import { $i } from '@/account'; | ||||||
| 
 | 
 | ||||||
| export default defineComponent({ | const props = defineProps<{ | ||||||
| 	components: { |   initialPage?: string | ||||||
| 		MkInfo, | }>(); | ||||||
| 		MkSuperMenu, |  | ||||||
| 	}, |  | ||||||
| 
 | 
 | ||||||
| 	props: { | const indexInfo = { | ||||||
| 		initialPage: { | 	title: i18n.ts.settings, | ||||||
| 			type: String, | 	icon: 'fas fa-cog', | ||||||
| 			required: false | 	bg: 'var(--bg)', | ||||||
|  | 	hideHeader: true, | ||||||
|  | }; | ||||||
|  | const INFO = ref(indexInfo); | ||||||
|  | const page = ref(props.initialPage); | ||||||
|  | const narrow = ref(false); | ||||||
|  | const view = ref(null); | ||||||
|  | const el = ref<HTMLElement | null>(null); | ||||||
|  | const childInfo = ref(null); | ||||||
|  | const menuDef = computed(() => [{ | ||||||
|  | 	title: i18n.ts.basicSettings, | ||||||
|  | 	items: [{ | ||||||
|  | 		icon: 'fas fa-user', | ||||||
|  | 		text: i18n.ts.profile, | ||||||
|  | 		to: '/settings/profile', | ||||||
|  | 		active: page.value === 'profile', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-lock-open', | ||||||
|  | 		text: i18n.ts.privacy, | ||||||
|  | 		to: '/settings/privacy', | ||||||
|  | 		active: page.value === 'privacy', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-laugh', | ||||||
|  | 		text: i18n.ts.reaction, | ||||||
|  | 		to: '/settings/reaction', | ||||||
|  | 		active: page.value === 'reaction', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-cloud', | ||||||
|  | 		text: i18n.ts.drive, | ||||||
|  | 		to: '/settings/drive', | ||||||
|  | 		active: page.value === 'drive', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-bell', | ||||||
|  | 		text: i18n.ts.notifications, | ||||||
|  | 		to: '/settings/notifications', | ||||||
|  | 		active: page.value === 'notifications', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-envelope', | ||||||
|  | 		text: i18n.ts.email, | ||||||
|  | 		to: '/settings/email', | ||||||
|  | 		active: page.value === 'email', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-share-alt', | ||||||
|  | 		text: i18n.ts.integration, | ||||||
|  | 		to: '/settings/integration', | ||||||
|  | 		active: page.value === 'integration', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-lock', | ||||||
|  | 		text: i18n.ts.security, | ||||||
|  | 		to: '/settings/security', | ||||||
|  | 		active: page.value === 'security', | ||||||
|  | 	}], | ||||||
|  | }, { | ||||||
|  | 	title: i18n.ts.clientSettings, | ||||||
|  | 	items: [{ | ||||||
|  | 		icon: 'fas fa-cogs', | ||||||
|  | 		text: i18n.ts.general, | ||||||
|  | 		to: '/settings/general', | ||||||
|  | 		active: page.value === 'general', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-palette', | ||||||
|  | 		text: i18n.ts.theme, | ||||||
|  | 		to: '/settings/theme', | ||||||
|  | 		active: page.value === 'theme', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-list-ul', | ||||||
|  | 		text: i18n.ts.menu, | ||||||
|  | 		to: '/settings/menu', | ||||||
|  | 		active: page.value === 'menu', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-music', | ||||||
|  | 		text: i18n.ts.sounds, | ||||||
|  | 		to: '/settings/sounds', | ||||||
|  | 		active: page.value === 'sounds', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-plug', | ||||||
|  | 		text: i18n.ts.plugins, | ||||||
|  | 		to: '/settings/plugin', | ||||||
|  | 		active: page.value === 'plugin', | ||||||
|  | 	}], | ||||||
|  | }, { | ||||||
|  | 	title: i18n.ts.otherSettings, | ||||||
|  | 	items: [{ | ||||||
|  | 		icon: 'fas fa-boxes', | ||||||
|  | 		text: i18n.ts.importAndExport, | ||||||
|  | 		to: '/settings/import-export', | ||||||
|  | 		active: page.value === 'import-export', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-volume-mute', | ||||||
|  | 		text: i18n.ts.instanceMute, | ||||||
|  | 		to: '/settings/instance-mute', | ||||||
|  | 		active: page.value === 'instance-mute', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-ban', | ||||||
|  | 		text: i18n.ts.muteAndBlock, | ||||||
|  | 		to: '/settings/mute-block', | ||||||
|  | 		active: page.value === 'mute-block', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-comment-slash', | ||||||
|  | 		text: i18n.ts.wordMute, | ||||||
|  | 		to: '/settings/word-mute', | ||||||
|  | 		active: page.value === 'word-mute', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-key', | ||||||
|  | 		text: 'API', | ||||||
|  | 		to: '/settings/api', | ||||||
|  | 		active: page.value === 'api', | ||||||
|  | 	}, { | ||||||
|  | 		icon: 'fas fa-ellipsis-h', | ||||||
|  | 		text: i18n.ts.other, | ||||||
|  | 		to: '/settings/other', | ||||||
|  | 		active: page.value === 'other', | ||||||
|  | 	}], | ||||||
|  | }, { | ||||||
|  | 	items: [{ | ||||||
|  | 		type: 'button', | ||||||
|  | 		icon: 'fas fa-trash', | ||||||
|  | 		text: i18n.ts.clearCache, | ||||||
|  | 		action: () => { | ||||||
|  | 			localStorage.removeItem('locale'); | ||||||
|  | 			localStorage.removeItem('theme'); | ||||||
|  | 			unisonReload(); | ||||||
|  | 		}, | ||||||
|  | 	}, { | ||||||
|  | 		type: 'button', | ||||||
|  | 		icon: 'fas fa-sign-in-alt fa-flip-horizontal', | ||||||
|  | 		text: i18n.ts.logout, | ||||||
|  | 		action: () => { | ||||||
|  | 			signout(); | ||||||
|  | 		}, | ||||||
|  | 		danger: true, | ||||||
|  | 	},], | ||||||
|  | }]); | ||||||
|  | 
 | ||||||
|  | const pageProps = ref({}); | ||||||
|  | const component = computed(() => { | ||||||
|  | 	if (page.value == null) return null; | ||||||
|  | 	switch (page.value) { | ||||||
|  | 		case 'accounts': return defineAsyncComponent(() => import('./accounts.vue')); | ||||||
|  | 		case 'profile': return defineAsyncComponent(() => import('./profile.vue')); | ||||||
|  | 		case 'privacy': return defineAsyncComponent(() => import('./privacy.vue')); | ||||||
|  | 		case 'reaction': return defineAsyncComponent(() => import('./reaction.vue')); | ||||||
|  | 		case 'drive': return defineAsyncComponent(() => import('./drive.vue')); | ||||||
|  | 		case 'notifications': return defineAsyncComponent(() => import('./notifications.vue')); | ||||||
|  | 		case 'mute-block': return defineAsyncComponent(() => import('./mute-block.vue')); | ||||||
|  | 		case 'word-mute': return defineAsyncComponent(() => import('./word-mute.vue')); | ||||||
|  | 		case 'instance-mute': return defineAsyncComponent(() => import('./instance-mute.vue')); | ||||||
|  | 		case 'integration': return defineAsyncComponent(() => import('./integration.vue')); | ||||||
|  | 		case 'security': return defineAsyncComponent(() => import('./security.vue')); | ||||||
|  | 		case '2fa': return defineAsyncComponent(() => import('./2fa.vue')); | ||||||
|  | 		case 'api': return defineAsyncComponent(() => import('./api.vue')); | ||||||
|  | 		case 'apps': return defineAsyncComponent(() => import('./apps.vue')); | ||||||
|  | 		case 'other': return defineAsyncComponent(() => import('./other.vue')); | ||||||
|  | 		case 'general': return defineAsyncComponent(() => import('./general.vue')); | ||||||
|  | 		case 'email': return defineAsyncComponent(() => import('./email.vue')); | ||||||
|  | 		case 'theme': return defineAsyncComponent(() => import('./theme.vue')); | ||||||
|  | 		case 'theme/install': return defineAsyncComponent(() => import('./theme.install.vue')); | ||||||
|  | 		case 'theme/manage': return defineAsyncComponent(() => import('./theme.manage.vue')); | ||||||
|  | 		case 'menu': return defineAsyncComponent(() => import('./menu.vue')); | ||||||
|  | 		case 'sounds': return defineAsyncComponent(() => import('./sounds.vue')); | ||||||
|  | 		case 'custom-css': return defineAsyncComponent(() => import('./custom-css.vue')); | ||||||
|  | 		case 'deck': return defineAsyncComponent(() => import('./deck.vue')); | ||||||
|  | 		case 'plugin': return defineAsyncComponent(() => import('./plugin.vue')); | ||||||
|  | 		case 'plugin/install': return defineAsyncComponent(() => import('./plugin.install.vue')); | ||||||
|  | 		case 'import-export': return defineAsyncComponent(() => import('./import-export.vue')); | ||||||
|  | 		case 'account-info': return defineAsyncComponent(() => import('./account-info.vue')); | ||||||
|  | 		case 'delete-account': return defineAsyncComponent(() => import('./delete-account.vue')); | ||||||
|  | 	} | ||||||
|  | 	return null; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | watch(component, () => { | ||||||
|  | 	pageProps.value = {}; | ||||||
|  | 
 | ||||||
|  | 	nextTick(() => { | ||||||
|  | 		scroll(el.value, { top: 0 }); | ||||||
|  | 	}); | ||||||
|  | }, { immediate: true }); | ||||||
|  | 
 | ||||||
|  | watch(() => props.initialPage, () => { | ||||||
|  | 	if (props.initialPage == null && !narrow.value) { | ||||||
|  | 		page.value = 'profile'; | ||||||
|  | 	} else { | ||||||
|  | 		page.value = props.initialPage; | ||||||
|  | 		if (props.initialPage == null) { | ||||||
|  | 			INFO.value = indexInfo; | ||||||
| 		} | 		} | ||||||
| 	}, | 	} | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| 	setup(props, context) { | onMounted(() => { | ||||||
| 		const indexInfo = { | 	narrow.value = el.value.offsetWidth < 800; | ||||||
| 			title: i18n.ts.settings, | 	if (!narrow.value) { | ||||||
| 			icon: 'fas fa-cog', | 		page.value = 'profile'; | ||||||
| 			bg: 'var(--bg)', | 	} | ||||||
| 			hideHeader: true, | }); | ||||||
| 		}; |  | ||||||
| 		const INFO = ref(indexInfo); |  | ||||||
| 		const page = ref(props.initialPage); |  | ||||||
| 		const narrow = ref(false); |  | ||||||
| 		const view = ref(null); |  | ||||||
| 		const el = ref(null); |  | ||||||
| 		const childInfo = ref(null); |  | ||||||
| 		const menuDef = computed(() => [{ |  | ||||||
| 			title: i18n.ts.basicSettings, |  | ||||||
| 			items: [{ |  | ||||||
| 				icon: 'fas fa-user', |  | ||||||
| 				text: i18n.ts.profile, |  | ||||||
| 				to: '/settings/profile', |  | ||||||
| 				active: page.value === 'profile', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-lock-open', |  | ||||||
| 				text: i18n.ts.privacy, |  | ||||||
| 				to: '/settings/privacy', |  | ||||||
| 				active: page.value === 'privacy', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-laugh', |  | ||||||
| 				text: i18n.ts.reaction, |  | ||||||
| 				to: '/settings/reaction', |  | ||||||
| 				active: page.value === 'reaction', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-cloud', |  | ||||||
| 				text: i18n.ts.drive, |  | ||||||
| 				to: '/settings/drive', |  | ||||||
| 				active: page.value === 'drive', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-bell', |  | ||||||
| 				text: i18n.ts.notifications, |  | ||||||
| 				to: '/settings/notifications', |  | ||||||
| 				active: page.value === 'notifications', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-envelope', |  | ||||||
| 				text: i18n.ts.email, |  | ||||||
| 				to: '/settings/email', |  | ||||||
| 				active: page.value === 'email', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-share-alt', |  | ||||||
| 				text: i18n.ts.integration, |  | ||||||
| 				to: '/settings/integration', |  | ||||||
| 				active: page.value === 'integration', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-lock', |  | ||||||
| 				text: i18n.ts.security, |  | ||||||
| 				to: '/settings/security', |  | ||||||
| 				active: page.value === 'security', |  | ||||||
| 			}], |  | ||||||
| 		}, { |  | ||||||
| 			title: i18n.ts.clientSettings, |  | ||||||
| 			items: [{ |  | ||||||
| 				icon: 'fas fa-cogs', |  | ||||||
| 				text: i18n.ts.general, |  | ||||||
| 				to: '/settings/general', |  | ||||||
| 				active: page.value === 'general', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-palette', |  | ||||||
| 				text: i18n.ts.theme, |  | ||||||
| 				to: '/settings/theme', |  | ||||||
| 				active: page.value === 'theme', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-list-ul', |  | ||||||
| 				text: i18n.ts.menu, |  | ||||||
| 				to: '/settings/menu', |  | ||||||
| 				active: page.value === 'menu', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-music', |  | ||||||
| 				text: i18n.ts.sounds, |  | ||||||
| 				to: '/settings/sounds', |  | ||||||
| 				active: page.value === 'sounds', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-plug', |  | ||||||
| 				text: i18n.ts.plugins, |  | ||||||
| 				to: '/settings/plugin', |  | ||||||
| 				active: page.value === 'plugin', |  | ||||||
| 			}], |  | ||||||
| 		}, { |  | ||||||
| 			title: i18n.ts.otherSettings, |  | ||||||
| 			items: [{ |  | ||||||
| 				icon: 'fas fa-boxes', |  | ||||||
| 				text: i18n.ts.importAndExport, |  | ||||||
| 				to: '/settings/import-export', |  | ||||||
| 				active: page.value === 'import-export', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-volume-mute', |  | ||||||
| 				text: i18n.ts.instanceMute, |  | ||||||
| 				to: '/settings/instance-mute', |  | ||||||
| 				active: page.value === 'instance-mute', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-ban', |  | ||||||
| 				text: i18n.ts.muteAndBlock, |  | ||||||
| 				to: '/settings/mute-block', |  | ||||||
| 				active: page.value === 'mute-block', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-comment-slash', |  | ||||||
| 				text: i18n.ts.wordMute, |  | ||||||
| 				to: '/settings/word-mute', |  | ||||||
| 				active: page.value === 'word-mute', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-key', |  | ||||||
| 				text: 'API', |  | ||||||
| 				to: '/settings/api', |  | ||||||
| 				active: page.value === 'api', |  | ||||||
| 			}, { |  | ||||||
| 				icon: 'fas fa-ellipsis-h', |  | ||||||
| 				text: i18n.ts.other, |  | ||||||
| 				to: '/settings/other', |  | ||||||
| 				active: page.value === 'other', |  | ||||||
| 			}], |  | ||||||
| 		}, { |  | ||||||
| 			items: [{ |  | ||||||
| 				type: 'button', |  | ||||||
| 				icon: 'fas fa-trash', |  | ||||||
| 				text: i18n.ts.clearCache, |  | ||||||
| 				action: () => { |  | ||||||
| 					localStorage.removeItem('locale'); |  | ||||||
| 					localStorage.removeItem('theme'); |  | ||||||
| 					unisonReload(); |  | ||||||
| 				}, |  | ||||||
| 			}, { |  | ||||||
| 				type: 'button', |  | ||||||
| 				icon: 'fas fa-sign-in-alt fa-flip-horizontal', |  | ||||||
| 				text: i18n.ts.logout, |  | ||||||
| 				action: () => { |  | ||||||
| 					signout(); |  | ||||||
| 				}, |  | ||||||
| 				danger: true, |  | ||||||
| 			},], |  | ||||||
| 		}]); |  | ||||||
| 
 | 
 | ||||||
| 		const pageProps = ref({}); | const emailNotConfigured = computed(() => instance.enableEmail && ($i.email == null || !$i.emailVerified)); | ||||||
| 		const component = computed(() => { |  | ||||||
| 			if (page.value == null) return null; |  | ||||||
| 			switch (page.value) { |  | ||||||
| 				case 'accounts': return defineAsyncComponent(() => import('./accounts.vue')); |  | ||||||
| 				case 'profile': return defineAsyncComponent(() => import('./profile.vue')); |  | ||||||
| 				case 'privacy': return defineAsyncComponent(() => import('./privacy.vue')); |  | ||||||
| 				case 'reaction': return defineAsyncComponent(() => import('./reaction.vue')); |  | ||||||
| 				case 'drive': return defineAsyncComponent(() => import('./drive.vue')); |  | ||||||
| 				case 'notifications': return defineAsyncComponent(() => import('./notifications.vue')); |  | ||||||
| 				case 'mute-block': return defineAsyncComponent(() => import('./mute-block.vue')); |  | ||||||
| 				case 'word-mute': return defineAsyncComponent(() => import('./word-mute.vue')); |  | ||||||
| 				case 'instance-mute': return defineAsyncComponent(() => import('./instance-mute.vue')); |  | ||||||
| 				case 'integration': return defineAsyncComponent(() => import('./integration.vue')); |  | ||||||
| 				case 'security': return defineAsyncComponent(() => import('./security.vue')); |  | ||||||
| 				case '2fa': return defineAsyncComponent(() => import('./2fa.vue')); |  | ||||||
| 				case 'api': return defineAsyncComponent(() => import('./api.vue')); |  | ||||||
| 				case 'apps': return defineAsyncComponent(() => import('./apps.vue')); |  | ||||||
| 				case 'other': return defineAsyncComponent(() => import('./other.vue')); |  | ||||||
| 				case 'general': return defineAsyncComponent(() => import('./general.vue')); |  | ||||||
| 				case 'email': return defineAsyncComponent(() => import('./email.vue')); |  | ||||||
| 				case 'theme': return defineAsyncComponent(() => import('./theme.vue')); |  | ||||||
| 				case 'theme/install': return defineAsyncComponent(() => import('./theme.install.vue')); |  | ||||||
| 				case 'theme/manage': return defineAsyncComponent(() => import('./theme.manage.vue')); |  | ||||||
| 				case 'menu': return defineAsyncComponent(() => import('./menu.vue')); |  | ||||||
| 				case 'sounds': return defineAsyncComponent(() => import('./sounds.vue')); |  | ||||||
| 				case 'custom-css': return defineAsyncComponent(() => import('./custom-css.vue')); |  | ||||||
| 				case 'deck': return defineAsyncComponent(() => import('./deck.vue')); |  | ||||||
| 				case 'plugin': return defineAsyncComponent(() => import('./plugin.vue')); |  | ||||||
| 				case 'plugin/install': return defineAsyncComponent(() => import('./plugin.install.vue')); |  | ||||||
| 				case 'import-export': return defineAsyncComponent(() => import('./import-export.vue')); |  | ||||||
| 				case 'account-info': return defineAsyncComponent(() => import('./account-info.vue')); |  | ||||||
| 				case 'delete-account': return defineAsyncComponent(() => import('./delete-account.vue')); |  | ||||||
| 			} |  | ||||||
| 			return null; |  | ||||||
| 		}); |  | ||||||
| 
 | 
 | ||||||
| 		watch(component, () => { | const pageChanged = (page) => { | ||||||
| 			pageProps.value = {}; | 	if (page == null) return; | ||||||
|  | 	childInfo.value = page[symbols.PAGE_INFO]; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| 			nextTick(() => { | defineExpose({ | ||||||
| 				scroll(el.value, { top: 0 }); | 	[symbols.PAGE_INFO]: INFO, | ||||||
| 			}); |  | ||||||
| 		}, { immediate: true }); |  | ||||||
| 
 |  | ||||||
| 		watch(() => props.initialPage, () => { |  | ||||||
| 			if (props.initialPage == null && !narrow.value) { |  | ||||||
| 				page.value = 'profile'; |  | ||||||
| 			} else { |  | ||||||
| 				page.value = props.initialPage; |  | ||||||
| 				if (props.initialPage == null) { |  | ||||||
| 					INFO.value = indexInfo; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		onMounted(() => { |  | ||||||
| 			narrow.value = el.value.offsetWidth < 800; |  | ||||||
| 			if (!narrow.value) { |  | ||||||
| 				page.value = 'profile'; |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		const emailNotConfigured = computed(() => instance.enableEmail && ($i.email == null || !$i.emailVerified)); |  | ||||||
| 
 |  | ||||||
| 		const pageChanged = (page) => { |  | ||||||
| 			if (page == null) return; |  | ||||||
| 			childInfo.value = page[symbols.PAGE_INFO]; |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		return { |  | ||||||
| 			[symbols.PAGE_INFO]: INFO, |  | ||||||
| 			page, |  | ||||||
| 			menuDef, |  | ||||||
| 			narrow, |  | ||||||
| 			view, |  | ||||||
| 			el, |  | ||||||
| 			pageProps, |  | ||||||
| 			component, |  | ||||||
| 			emailNotConfigured, |  | ||||||
| 			pageChanged, |  | ||||||
| 			childInfo, |  | ||||||
| 		}; |  | ||||||
| 	}, |  | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue