Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔙 from #579 - Click to go back button to show MacroGroup list from Group page within ChangeMapMenu.vue #585

Merged
merged 1 commit into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
280 changes: 169 additions & 111 deletions src/components/ChangeMapMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@

<template>
<div id="g3w-change-map-menu">
<template v-if="isChildNode">
<div style="display: flex; align-items: center; color: #ffffff" class="skin-background-color">
<!-- current node is a child -->
<template v-if="'root' !== this.current">
<div
style="
display: flex;
align-items: center;
color: #ffffff"
class="skin-background-color"
>
<span
v-t-tooltip:bottom.create="'change_session'"
v-disabled="loading"
Expand All @@ -20,27 +27,40 @@
border-radius: 3px;
"
>
<i style="color: #FFFFFF" :class="g3wtemplate.getFontClass('reply')"></i>
<i
style="color: #FFFFFF"
:class="g3wtemplate.getFontClass('reply')">
</i>
</span>

<div v-if="parent" style="margin: auto">
<h3 style="font-weight: bold">{{parent.title || parent.name}}</h3>
<div
v-if="parent"
style="margin: auto"
>
<h3 style="font-weight: bold">
{{parent.title || parent.name}}
</h3>
</div>
</div>
</template>

<div v-if="items.length" class="g3w-change-map-menu-container">
<div
v-if="items.length"
class="g3w-change-map-menu-container">
<div
v-for="item in items"
:key="item.title"
:key="item.name"
class="menu-item"
>

<!-- ITEM IMAGE -->
<div class="menu-item-image" @click.stop="trigger(item)">
<div
class="menu-item-image"
@click.stop="trigger(item)"
>
<img
:src="item.thumbnail || item.header_logo_img || item.logo_img"
@error="setFallBackImage(item)"
@error="setItemImageSrc({ item, type: 'net_error' })"
alt="logo"
class="img-responsive"
>
Expand All @@ -49,7 +69,9 @@
<!-- ITEM CONTENT -->
<div class="menu-item-content">
<div class="menu-item-text">
<h4 class="menu-item-title">{{ item.title }}</h4>
<h4 class="menu-item-title">
{{ item.title }}
</h4>
<div v-html="item.description"></div>
</div>
</div>
Expand All @@ -58,7 +80,10 @@
</div>

<template v-else>
<h3 style="font-weight: bold" v-t="`no_other_${current}`"></h3>
<h3
style="font-weight: bold"
v-t="`no_other_${current}`">
</h3>
</template>

</div>
Expand All @@ -73,6 +98,18 @@ import { API_BASE_URLS, LOGO_GIS3W } from 'constant';
const Projections = require('g3w-ol/projection/projections');
const { XHR } = require('utils');

/** Cached HTTP GET request */
async function get_macro(id) {
get_macro[id] = get_macro[id] || await XHR.get({ url: encodeURI(`/${ApplicationService.getApplicationUser().i18n}${API_BASE_URLS.ABOUT.group}${id}/`) });
return get_macro[id];
}

/** Cached HTTP GET request */
async function get_group(id) {
get_group[id] = get_group[id] || await XHR.get({ url: encodeURI(`/${ApplicationService.getApplicationUser().i18n}${API_BASE_URLS.ABOUT.projects.replace('__G3W_GROUP_ID__', id)}`) });
return get_group[id];
}

export default {

/** @since 3.8.6 */
Expand Down Expand Up @@ -107,102 +144,129 @@ export default {
parent: null,

/**
* @type {Array}
* @type { Array } all items from top to bottom
*/
steps: [],
steps: [],

/**
* @type {string}
* @type { string } ID of current project group
*/
currentProjectGroupId: null,
curr_group: null,

}
},

computed: {
methods: {

/**
* @returns {boolean} whether current node isn't a "root" element
* @returns { Promise<void> }
*/
isChildNode() {
return 'root' !== this.current;
},
async back() {
const last_step = this.steps.pop(); // remove last
const has_steps = this.steps.length > 0;
const item = has_steps && this.steps[this.steps.length - 1]; //get last step

// back to macrogrup
if (
(has_steps && undefined !== item.macrogroup_id) ||
(!has_steps && undefined === last_step && Array.isArray(this.parent.macrogroup_id) && this.parent.macrogroup_id.length > 0) // no steps done on first time
) {
const macrogroup_id = has_steps ? item.macrogroup_id : this.parent.macrogroup_id;
const add = has_steps ? false : true; // false = step it's comping from bottom to top
return this.showMacroGroups(macrogroup_id, add);
}

},
// back to group
if (has_steps && undefined === item.macrogroup_id) {
return this.showGroups(item, false);
}

methods: {
// back to root
if (!has_steps) {
return this.showRoot();
}
},

/**
* Set a fallback image on network error.
* @param { Array } macrogroup_id
* @param { boolean } addStep Boolean
*
* @returns { Promise<void> }
*
* @since 3.10.0
*/
setFallBackImage(item) {
const g3w_logo = `${ApplicationService.getConfig().urls.clienturl}${LOGO_GIS3W}`;
if (item.thumbnail || item.logo_img) item.thumbnail = g3w_logo;
else if (item.header_logo_img) item.header_logo_img = g3w_logo;
},

back() {
if (this.steps.length > 1) {
const item = this.steps[0];
this.steps = [];
this.showGroups(item);
} else {
this.showRoot();
async showMacroGroups(macrogroup_id=[], addStep=true) {
// current project belongs to just one macrogroup
if (1 === macrogroup_id.length) {
this.parent = this.macrogroups.find(mg => macrogroup_id[0] === mg.id);
return await this.showGroups(this.parent);
}
},

showRoot() {
this.current = 'root';
this.items = this.macrogroupsandgroups;
this.steps = [];
},
// current project belongs to more than one macrogroup
this.items = this.macrogroups.filter(m => macrogroup_id.includes(m.id));
this.current = 'macrogroups';
this.parent = {
macrogroup_id,
title: null, // hide title
name: null // hide name
}

_onChangeRoot(item) {
// item is a macrogroup
if (undefined === item.srid) {
this.showGroups(item)
} else {
// item is a group
this.showProjects(item);
if (addStep) {
this.steps.push(this.parent);
}
},

async showGroups(item) {
this.loading = true;
this.parent = item;
/**
* @param item
* @param { boolean } addStep Boolean
*
* @returns { Promise<void> }
*/
async showGroups(item, addStep=true) {
try {
this.items = await XHR.get({
url: encodeURI(`/${ApplicationService.getApplicationUser().i18n}${API_BASE_URLS.ABOUT.group}${item.id}/`)
});
this.loading = true;
this.parent = item;
this.items = await get_macro(item.id);
this.current = 'groups';
} catch(err) {
} catch(e) {
console.warn(e);
this.items = [];
} finally {
if (addStep) {
this.steps.push(this.parent);
}
this.loading = false;
}
this.steps.push(this.parent);
this.loading = false;
},

/**
* @param item
*
* @returns { Promise<void> }
*/
async showProjects(item) {
this.loading = true;
this.parent = item;

if (this.parent.id === this.currentProjectGroupId) {
this.items = ProjectsRegistry.getListableProjects();
try {
this.loading = true;
this.parent = item;
this.items = (
this.parent.id === this.curr_group
? ProjectsRegistry.getListableProjects()
: await get_group(item.id, item => this.setItemImageSrc({ item, type: 'project' }))
);
this.current = 'projects';
} else {
try {
this.items = await XHR.get({
url: encodeURI(`/${ApplicationService.getApplicationUser().i18n}${API_BASE_URLS.ABOUT.projects.replace('__G3W_GROUP_ID__', item.id)}`)
});
this.items.forEach(item => this.setItemImageSrc({ item, type: 'project' }));
this.current = 'projects';
} catch(err) {
this.items = [];
}
} catch(e) {
console.warn(e);
this.items = [];
} finally {
this.steps.push(this.parent);
this.loading = false;
}
},

this.steps.push(this.parent);
this.loading = false;
showRoot() {
this.current = 'root';
this.items = [...this.macrogroups, ...this.groups];
this.steps = [];
},

/**
Expand All @@ -217,18 +281,18 @@ export default {
try {
new URL(base_url);
url = `${base_url}${item.url || item.map_url.replace(/^\//, "")}`;
} catch(err) {
} catch(e) {
url = `${location.origin}${base_url}${item.url || item.map_url.replace(/^\//, "")}`;
}
return ApplicationService.changeMapProject({ url, epsg });
},

async trigger(item) {
switch(this.current) {
case 'root': return this._onChangeRoot(item);
case 'macrogroup': return this.showGroups(item);
case 'groups': return await this.showProjects(item);
case 'projects': return await this.changeMapProject(item);
case 'root': return undefined === item.srid ? this.showGroups(item) : this.showProjects(item); // `srid` is undefined when item is a macrogroup
case 'macrogroups': return this.showGroups(item);
case 'groups': return await this.showProjects(item);
case 'projects': return await this.changeMapProject(item);
}
},

Expand All @@ -243,6 +307,14 @@ export default {
case 'project': item.thumbnail = this._setSrc(item.thumbnail); break;
case 'group': item.header_logo_img = this._setSrc(item.header_logo_img); break;
case 'macrogroup': item.logo_img = this._setSrc(item.logo_img); break;
// Set a fallback image on network error.
case 'net_error':
if (item.thumbnail || item.logo_img) {
item.thumbnail = `${ApplicationService.getConfig().urls.clienturl}${LOGO_GIS3W}`;
} else if (item.header_logo_img) {
item.header_logo_img = `${ApplicationService.getConfig().urls.clienturl}${LOGO_GIS3W}`;
}
break;
}
},

Expand Down Expand Up @@ -272,38 +344,24 @@ export default {

},

created() {

// at start time set item projects
this.items = ProjectsRegistry.getListableProjects();
this.items.forEach(item => this.setItemImageSrc({ item, type: 'project' }));
this.parent = ProjectsRegistry.getCurrentProjectGroup();
this.currentProjectGroupId = this.parent.id;

// get macrogroups
this.macrogroups = ApplicationService.getConfig().macrogroups;
this.macrogroups.forEach(item => this.setItemImageSrc({ item, type: 'magrocroup' }));

// get groups
this.groups = ApplicationService.getConfig().groups;
this.groups.forEach(item => this.setItemImageSrc({ item, type: 'group' }));

// collect all groups and macrogroups
this.macrogroupsandgroups = [...this.macrogroups, ...this.groups];

// check if group on initConfig is referred to macrogrop
const isMacroGroup = this.macrogroups.find(macrogroup => macrogroup.id === this.parent.id);
if (isMacroGroup) {
// check belong group
const findGroup = this.groups.find(group => group.id === this.parent.id);
if (findGroup) {
this.parent = findGroup;
this.currentProjectGroupId = this.parent.id;
}
}

async created() {

const config = ApplicationService.getConfig();

// setup items data (macrogrups and groups).
this.items = ProjectsRegistry.getListableProjects();
this.parent = ProjectsRegistry.getCurrentProjectGroup();
this.curr_group = this.parent.id;
this.macrogroups = config.macrogroups;
this.groups = config.groups;

// setup items images
Object
.entries({ 'project': this.items, 'magrocroup': this.macrogroups, 'group': this.groups })
.forEach(([type, d]) => d.forEach(item => this.setItemImageSrc({ item, type })))

if (0 === this.items.length) {
this.showRoot();
this.back();
}

},
Expand Down
Loading