Create group tabs

This commit is contained in:
Pierre HUBERT 2021-03-15 18:04:20 +01:00
parent d0812e2d85
commit 9d1ebf5899
11 changed files with 271 additions and 269 deletions

View File

@ -35,3 +35,21 @@
display: table;
margin: auto;
}
.group-header .box-body {
display: flex;
}
.group-header .box-body .spacer {
flex: 2;
}
.group-header .box-body .col-metadata {
flex: 1;
display: flex;
flex-direction: column;
align-items: baseline;
justify-content: center;
min-width: 160px;
}

View File

@ -11,7 +11,7 @@
* @param {String} calloutMessage The message of the callout
* @param {String} calloutType The type of the callout (danger, info, warning, success)
*/
ComunicWeb.common.messages.createCalloutElem = function(calloutTitle, calloutMessage, calloutType){
function createCallout(calloutTitle, calloutMessage, calloutType){
//Prepare callout message
calloutMessage = "<p>" + calloutMessage + "</p>";
@ -39,6 +39,8 @@ ComunicWeb.common.messages.createCalloutElem = function(calloutTitle, calloutMes
return calloutElem;
}
ComunicWeb.common.messages.createCalloutElem = createCallout;
/**
* Create loading callout element
*

View File

@ -4,7 +4,7 @@
* @author Pierre HUBERT
*/
ComunicWeb.pages.groups.main = {
const GroupsPage = {
/**
* Open groups page
@ -12,10 +12,15 @@ ComunicWeb.pages.groups.main = {
* @param {object} args Optionnal arguments
* @param {HTMLElement} target The target for the page
*/
open: function(args, target){
open: async function(args, target){
try {
//Determine which page / group should be opened
if(!args.subfolder)
if(args.groupID)
page = args.groupID;
else if(!args.subfolder)
var page = "main";
else {
@ -43,8 +48,8 @@ ComunicWeb.pages.groups.main = {
//Else determine which group page to open (specified after the ID of the group)
var groupID = page;
if(args.subfolder.split("/").length < 2){
page = "group";
if(!args.subfolder || args.subfolder.split("/").length < 2){
page = "posts";
}
else {
//Extract the page to open from the URL
@ -52,10 +57,50 @@ ComunicWeb.pages.groups.main = {
//Check if there is nothing after "/"
if(page.length < 2)
page = "group";
page = "posts";
}
//Check which page to open
/** @type {AdvancedGroupInfo} Get information about the group*/
const group = await new Promise((res, rej) => GroupsInterface.getAdvancedInfo(groupID, function(result){
//Check for errors
if(result.error){
//Check the code of the error
if(result.error.code == 401)
ComunicWeb.pages.groups.pages.forbidden.open(id, target);
//The group does not exists
else
ComunicWeb.common.error.pageNotFound({}, target);
return;
}
res(result);
}));
//Update page title
ComunicWeb.common.pageTitle.setTitle(group.name);
// Display the header for the group
GroupSectionHeader.display(group, target);
// Display the tabs of the group
await GroupTabs.show(group, target, page);
} catch(e) {
console.error(e);
target.appendChild(createCallout(
tr("Error"),
tr("Failed to load group page!"),
"danger"
))
}
/*//Check which page to open
if(page == "group")
ComunicWeb.pages.groups.pages.group.open(groupID, target);
@ -68,7 +113,9 @@ ComunicWeb.pages.groups.main = {
//Unrecognized page
else
ComunicWeb.common.error.pageNotFound(args, target);
ComunicWeb.common.error.pageNotFound(args, target);*/
}
};
ComunicWeb.pages.groups.main = GroupsPage;

View File

@ -1,110 +0,0 @@
/**
* Group page
*
* @author Pierre HUBERT
*/
ComunicWeb.pages.groups.pages.group = {
/**
* Open (display) a group page
*
* @param {Number} id The ID of the group to display
* @param {HTMLElement} target The target for the page
*/
open: function(id, target){
//Get information about the group
ComunicWeb.components.groups.interface.getAdvancedInfo(id, function(result){
//Check for errors
if(result.error){
//Check the code of the error
if(result.error.code == 401){
ComunicWeb.pages.groups.pages.forbidden.open(id, target);
}
else
//The group does not exists
ComunicWeb.common.error.pageNotFound({}, target);
}
else
//Display group page
ComunicWeb.pages.groups.pages.group.display(id, result, target);
});
},
/**
* Display information about a group
*
* @param {Number} id The ID of the group to display
* @param {Object} info Information about the group to display
* @param {HTMLElement} target The target for the page
*/
display: function(id, info, target){
//Update page title
ComunicWeb.common.pageTitle.setTitle(info.name);
//Create page row
var pageRow = createElem2({
appendTo: target,
type: "div",
class: "row group-page"
});
//Create header column
var headerColumn = createElem2({
appendTo: pageRow,
type: "div",
class: "col-md-6"
});
//Display the header for the group
ComunicWeb.pages.groups.sections.header.display(info, headerColumn);
//Check if the user can create posts or not
if(ComunicWeb.components.groups.utils.canCreatePosts(info)){
//Intialize posts creation form
var postFormRow = createElem2({
appendTo: target,
type: "div",
class: "row group-page"
});
//Add column
var postFormCol = createElem2({
appendTo: postFormRow,
type: "div",
class: "col-md-6"
});
//Display form
ComunicWeb.components.posts.form.display("group", id, postFormCol);
}
//Display group posts
var postsRow = createElem2({
appendTo: target,
type: "div",
class: "row group-page"
});
var postsCol = createElem2({
appendTo: postsRow,
type: "div",
class: "col-md-6"
});
ComunicWeb.pages.groups.sections.posts.display(info, postsCol);
}
}

View File

@ -0,0 +1,56 @@
/**
* Group page
*
* @author Pierre HUBERT
*/
const GroupPostsPage = {
/**
* Display information about a group
*
* @param {Number} id The ID of the group to display
* @param {Object} info Information about the group to display
* @param {HTMLElement} target The target for the page
*/
display: function(id, info, target){
//Check if the user can create posts or not
if(ComunicWeb.components.groups.utils.canCreatePosts(info)){
//Intialize posts creation form
var postFormRow = createElem2({
appendTo: target,
type: "div",
class: "row group-page"
});
//Add column
var postFormCol = createElem2({
appendTo: postFormRow,
type: "div",
class: "col-md-6"
});
//Display form
ComunicWeb.components.posts.form.display("group", id, postFormCol);
}
//Display group posts
var postsRow = createElem2({
appendTo: target,
type: "div",
class: "row group-page"
});
var postsCol = createElem2({
appendTo: postsRow,
type: "div",
class: "col-md-6"
});
ComunicWeb.pages.groups.sections.posts.display(info, postsCol);
}
}

View File

@ -4,7 +4,7 @@
* @author Pierre HUBERT
*/
ComunicWeb.pages.groups.sections.header = {
const GroupSectionHeader = {
/**
* Display groups page header
@ -14,29 +14,43 @@ ComunicWeb.pages.groups.sections.header = {
*/
display: function(info, target){
//Create header container
var headerContainer = createElem2({
//Create page row
var pageRow = createElem2({
appendTo: target,
type: "div",
class: "row group-page"
});
//Create header column
var headerColumn = createElem2({
appendTo: pageRow,
type: "div",
class: "col-md-6"
});
//Create header container
const headerContainer = createElem2({
appendTo: headerColumn,
type: "div",
class: "group-header box box-primary"
});
//Create a row
var row = createElem2({
const row = createElem2({
appendTo: headerContainer,
type: "div",
class: "box-body row"
});
//First column
var firstColumn = createElem2({
const firstColumn = createElem2({
appendTo: row,
type: "div",
class: "col-md-4 group-col-icon",
});
//Group icon
var groupIcon = createElem2({
const groupIcon = createElem2({
appendTo: firstColumn,
type: "img",
src: info.icon_url,
@ -44,7 +58,7 @@ ComunicWeb.pages.groups.sections.header = {
});
//Group name
var groupName = createElem2({
const groupName = createElem2({
appendTo: firstColumn,
type: "span",
class: "group-name",
@ -62,132 +76,29 @@ ComunicWeb.pages.groups.sections.header = {
}
//Second column : Information about the company
var secondColumn = createElem2({
createElem2({
appendTo: row,
type: "div",
class: "col-md-4 col-info"
});
class: "spacer"
})
//Group URL (if any)
if(info.url != "null"){
var urlElem = createElem2({
appendTo: secondColumn,
type: "a",
class: "a",
href: info.url,
innerHTML: "<i class='fa fa-link'></i> " + info.url
});
urlElem.target = "_blank";
}
//Group description (if any)
if(info.description != "null")
createElem2({
appendTo: secondColumn,
type: "div",
innerHTML: "<i class='fa fa-file-text-o'></i> " + info.description
});
//Add separator
add_p(secondColumn, "&nbsp;");
//Third column : information about the group
// Second column : basic information about the group
var thirdColumn = createElem2({
appendTo: row,
type: "div",
class: "col-md-4 col-metadata"
});
//Add join date
createElem2({
appendTo: thirdColumn,
type: "div",
innerHTML: '<i class="fa fa-clock-o"></i> Created '+ComunicWeb.common.date.timeDiffToStr(info.time_create)+' ago'
});
//Add number of members
var members = createElem2({
appendTo: thirdColumn,
type: "div",
innerHTML: '<i class="fa fa-group"></i> '+ info.number_members+' members'
});
//Check if the user is a moderator or an admin
if(info.membership == "administrator" || info.membership == "moderator"){
//Turn members information into a link
members.className = "a";
members.addEventListener("click", function(e){
openPage("groups/" + info.id + "/members");
});
}
//Group visibility
var visibility = {
open: "Open group",
private: "Private group",
secrete: "Secrete group"
};
createElem2({
appendTo: thirdColumn,
type: "div",
innerHTML: "<i class='fa fa-lock'></i> " + visibility[info.visibility]
});
//Group registration
var levels = {
open: "Open registration",
moderated: "Moderated registration",
closed: "Closed registration"
}
createElem2({
appendTo: thirdColumn,
type: "div",
innerHTML: "<i class='fa fa-pencil'></i> " + levels[info.registration_level]
class: "col-md-7 col-metadata"
});
//Display membership level
if(signed_in())
ComunicWeb.pages.groups.sections.membershipBlock.display(info, thirdColumn);
//Display follow block
if(signed_in() && ComunicWeb.components.groups.utils.isGroupMember(info))
ComunicWeb.pages.groups.sections.followBlock.display(info, thirdColumn);
//If the user is an admin, add a link to configure the page
if(signed_in() && info.membership == "administrator"){
var settingsLink = createElem2({
appendTo: thirdColumn,
type: "div",
class: "a",
innerHTML: " <i class='fa fa-gear'></i>Settings"
});
settingsLink.addEventListener("click", function(e){
openPage("groups/" + info.id + "/settings");
});
}
//Display likes block
ComunicWeb.components.like.button.display(
"group",
info.id,
info.number_likes,
info.is_liking,
createElem2({
appendTo: thirdColumn,
type: "div"
})
);
},
};
ComunicWeb.pages.groups.sections.header = GroupSectionHeader;

View File

@ -0,0 +1,38 @@
/**
* Group tags
*
* @author Pierre Hubert
*/
const GroupTabs = {
/**
* @param {AdvancedGroupInfo} group Group information
* @param {HTMLElement} target Target
* @param {String} activePage Current active page
*/
show: async function(group, target, activePage) {
// Load template
const tpl = await Page.loadHTMLTemplate("pages/groups/sections/GroupTabs.html");
const el = document.createElement("div")
el.innerHTML = tpl;
target.appendChild(el);
Vue.createApp({
data: () => {
return {
isAdmin: group.membership == "administrator",
canSeeMembers: group.membership == "administrator" || group.membership == "moderator",
activePage: activePage
}
},
methods: {
openPage: (uri) => openPage("groups/" + group.id + "/" + uri)
}
}).mount(el);
}
}

View File

@ -28,7 +28,7 @@ ComunicWeb.pages.virtualDirectory.page = {
//Check if the page is a group
if(r.kind == "group"){
ComunicWeb.pages.groups.pages.group.open(r.id, target);
GroupsPage.open({groupID: r.id}, target);
}
});

26
assets/js/typings/Group.d.ts vendored Normal file
View File

@ -0,0 +1,26 @@
/**
* Group typings
*
* @author Pierre Hubert
*/
declare interface Group {
id: Number,
name: String,
icon_url: String,
number_members: Number,
visibility: "open"|"private"|"secrete",
registration_level: "open"|"moderated"|"closed",
posts_level: "moderators"|"members",
virtual_directory: String,
membership: "administrator"|"moderator"|"member"|"invited"|"pending"|"visitor",
following: Boolean,
}
declare interface AdvancedGroupInfo extends Group {
time_create: Number,
description: String,
url: String,
number_likes: Number,
is_liking: Boolean
}

View File

@ -0,0 +1,13 @@
<!-- Group tabs section -->
<div class="row group-page">
<div class="col-md-6">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li v-bind:class="activePage == 'posts' ? 'active': ''"><a @click="openPage('posts')">tr("Posts")</a></li>
<li v-bind:class="activePage == 'members' ? 'active': ''"><a @click="openPage('members')" v-if="canSeeMembers">tr("Members")</a></li>
<li v-bind:class="activePage == 'about' ? 'active': ''"><a @click="openPage('about')">tr("About")</a></li>
<li class="pull-right" v-if="isAdmin" v-bind:class="activePage == 'admin' ? 'active': ''"><a @click="openPage('admin')" class="text-muted"><i class="fa fa-gear"></i></a></li>
</ul>
</div>
</div>

View File

@ -529,7 +529,7 @@ class Dev {
//Groups sub pages
"js/pages/groups/pages/main.js",
"js/pages/groups/pages/create.js",
"js/pages/groups/pages/group.js",
"js/pages/groups/pages/posts.js",
"js/pages/groups/pages/settings.js",
"js/pages/groups/pages/members.js",
"js/pages/groups/pages/forbidden.js",
@ -539,6 +539,7 @@ class Dev {
"js/pages/groups/sections/membershipBlock.js",
"js/pages/groups/sections/posts.js",
"js/pages/groups/sections/followBlock.js",
"js/pages/groups/sections/tabs.js",
//User settings page