summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue')
-rw-r--r--app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue135
1 files changed, 135 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue b/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue
new file mode 100644
index 00000000000..54313297b14
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue
@@ -0,0 +1,135 @@
+<script>
+import { GlBreadcrumb, GlIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
+
+import LegacyContainer from './components/legacy_container.vue';
+import WelcomePage from './components/welcome.vue';
+
+export default {
+ components: {
+ GlBreadcrumb,
+ GlIcon,
+ WelcomePage,
+ LegacyContainer,
+ },
+ directives: {
+ SafeHtml,
+ },
+ props: {
+ title: {
+ type: String,
+ required: true,
+ },
+ initialBreadcrumb: {
+ type: String,
+ required: true,
+ },
+ panels: {
+ type: Array,
+ required: true,
+ },
+ jumpToLastPersistedPanel: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ persistenceKey: {
+ type: String,
+ required: true,
+ },
+ experiment: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
+
+ data() {
+ return {
+ activePanelName: null,
+ };
+ },
+
+ computed: {
+ activePanel() {
+ return this.panels.find((p) => p.name === this.activePanelName);
+ },
+
+ details() {
+ return this.activePanel.details || this.activePanel.description;
+ },
+
+ hasTextDetails() {
+ return typeof this.details === 'string';
+ },
+
+ breadcrumbs() {
+ if (!this.activePanel) {
+ return null;
+ }
+
+ return [
+ { text: this.initialBreadcrumb, href: '#' },
+ { text: this.activePanel.title, href: `#${this.activePanel.name}` },
+ ];
+ },
+ },
+
+ created() {
+ this.handleLocationHashChange();
+
+ if (this.jumpToLastPersistedPanel) {
+ this.activePanelName = localStorage.getItem(this.persistenceKey) || this.panels[0].name;
+ }
+
+ window.addEventListener('hashchange', () => {
+ this.handleLocationHashChange();
+ this.$emit('panel-change');
+ });
+
+ this.$root.$on('clicked::link', (e) => {
+ window.location = e.target.href;
+ });
+ },
+
+ methods: {
+ handleLocationHashChange() {
+ this.activePanelName = window.location.hash.substring(1) || null;
+ if (this.activePanelName) {
+ localStorage.setItem(this.persistenceKey, this.activePanelName);
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <welcome-page
+ v-if="activePanelName === null"
+ :panels="panels"
+ :title="title"
+ :experiment="experiment"
+ >
+ <template #footer>
+ <slot name="welcome-footer"> </slot>
+ </template>
+ </welcome-page>
+ <div v-else class="row">
+ <div class="col-lg-3">
+ <div v-safe-html="activePanel.illustration" class="gl-text-white"></div>
+ <h4>{{ activePanel.title }}</h4>
+
+ <p v-if="hasTextDetails">{{ details }}</p>
+ <component :is="details" v-else />
+
+ <slot name="extra-description"></slot>
+ </div>
+ <div class="col-lg-9">
+ <gl-breadcrumb v-if="breadcrumbs" :items="breadcrumbs">
+ <template #separator>
+ <gl-icon name="chevron-right" :size="8" />
+ </template>
+ </gl-breadcrumb>
+ <legacy-container :key="activePanel.name" class="gl-mt-3" :selector="activePanel.selector" />
+ </div>
+ </div>
+</template>