Fixes & Hubl branding

This commit is contained in:
Jean-Baptiste Pasquier 2020-05-08 13:27:44 +00:00 committed by Rachel
parent 35a0a20119
commit 40792273fe
51 changed files with 722 additions and 701 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
*.iml
*.swp
dist
.DS_Store

114
README.md
View File

@ -1,6 +1,6 @@
# SiB App
# Hubl
SiB App is the magic tool that allows the Freelance Network to thrive in a decentralized way.
Hubl is the magic tool that allows the Freelance Network to thrive in a decentralized way.
## Getting Started
@ -8,52 +8,48 @@ These instructions will get you a copy of the project up and running on your loc
### Prerequisites
To install SiB App, you'll need:
To install Hubl, you'll need:
* A SIB server (djangoldp>=0.6.41) with the appropriate modules
* A Prosody Server (with [appropriate modules](https://git.happy-dev.fr/startinblox/prosody/custom-prosody-modules/)
* A Hubl Server (djangoldp>=0.6.42) with the appropriate modules
* A Prosody Server (with [appropriate modules](https://git.startinblox.com/infra/prosody-modules/)
* A SMTP Server (optional)
* NodeJS on your machine
Before diving in you have to check your SIB server supports the following LDP packages:
Before diving in you have to check your Hubl Server supports the following LDP packages:
* djangoldp_account
* djangoldp_circle
* djangoldp_dashboard
* djangoldp_joboffer
* djangoldp_conversation
* djangoldp_notification
* djangoldp_profile
* djangoldp_project
* djangoldp_skill
* djangoldp_uploader
* oidc_provider: 'git+https://github.com/jblemee/django-oidc-provider.git@develop'
Those packages are given with the last stable version tested.
Refer to the [documentation to install a SIB server](https://git.startinblox.com/documentation/doc/wikis/devops/install_sib_server) with this configuration.
Refer to the [documentation to install a Hubl Server](https://git.startinblox.com/documentation/doc/wikis/devops/install_sib_server) with this configuration.
## Build the application
In order to find your server(s) the client application needs to be assembled with the proper configuration.
Get the code of the SIB app on your machine:
Get the code of the Hubl on your machine:
```bash
git clone ...
cd sib-app
cd hubl
npm install
```
Then create a `config.json` based on your needs, see Mandatory and Optional Modules on this page. For convienence a `config.sample.json` exists in the source.
Federated Sib App needs to use `config.sample.federated.json` example.
Federated Hubl needs to use `config.sample.federated.json` example.
You can quickly update your API URI from the samples:
```
$ sed 's/http:\/\/localhost:8000/https:\/\/api.test2.startinblox.com/' config.sample.json > config.json
$ sed 's/http:\/\/localhost:8000/https:\/\/api.your-server.startinblox.com/' config.sample.json > config.json
```
Then build your new SIB App:
Then build your new Hubl:
```bash
npm run build
@ -71,9 +67,9 @@ npm run watch
## Mandatory modules
By default, a SIB App includes only individual chat modules.
By default, a Hubl includes only individual chat modules.
On Server: `djangoldp_account`, `djangoldp_profile`, `djangoldp_notification`, `oidc_provider` packages
On Server: `djangoldp_account`, `djangoldp_profile`, `djangoldp_notification`, `djangoldp_skill`, `djangoldp_upload`, `oidc_provider` packages
On `config.json`:
@ -89,7 +85,7 @@ On `config.json`:
Where:
* `xmpp` is your Prosody with [appropriate modules](https://git.happy-dev.fr/startinblox/prosody/custom-prosody-modules/) configured on.
* `xmpp` is your Prosody with [appropriate modules](https://git.startinblox.com/infra/prosody-modules/) configured on.
* `authority` is the OpenID Provider. Usually, if you use `djangoldp-account` it's the same as your djangoldp server.
* `endpoints.users` is the API endpoints for Users on your djangoldp server.
@ -98,7 +94,8 @@ Where:
On `config.json`:
```json
"clientName": "Sib App",
"clientName": "Hubl",
"clientFavicon": "/images/favicon.png",
"clientLogo": "/images/logo.png",
"clientLogoHeight": "32px",
"clientCSS": "/path/to/custom.css",
@ -107,21 +104,36 @@ On `config.json`:
Where:
* `clientName` is the name of your SIB App.
* `clientName` is the name of your Hubl.
* `clientFavicon` is an URL to a distant favicon
* `clientLogo` is an URL to a distant logo for your client
* `clientLogoHeight` allow a quick fix to manage different height logos
* `clientCSS` is an URL to a distant CSS that'll be the last one loaded by the SIB App
* `clientCSS` is an URL to a distant CSS that'll be the last one loaded by the Hubl
* `authorityName` is a visual name of your OpenID Provider
## Optional modules
### Analytics
Hubl support Google or Matomo as analytics trackers. To use them, add to your `config.json`:
```json
"analytics": [
{
"type": "matomo", //Or "google"
"url": "https://my-personal.matomo.cloud/",
"id": "1"
}
]
```
### Circles
Circles are a public group chat. To activate them, you need:
On Server: `djangoldp_circle` packages
On `config.json`:
On `config.json`:
```json
"endpoints": {
@ -129,18 +141,33 @@ On `config.json`:
}
```
### Dashboard
Dashboard includes card generation from HTML. To activate them, you need:
On Server: `djangoldp_dashboard` packages
On `config.json`:
```json
"endpoints": {
"dashboard": "http://server.url/dashboard/"
}
```
### Events
Events allow to create and manage instance-level evenement. To activate them, you need:
On Server: `djangoldp_event` and `djangoldp_upload` packages
On Server: `djangoldp_event`, `djangoldp_upload` packages
On `config.json`:
On `config.json`:
```json
"endpoints": {
"events": "http://server.url/events/",
"typeevents": "http://server.url/typeevents/",
"uploads": "http://server.url/upload/"
}
```
@ -150,7 +177,7 @@ On `config.json`:
On Server: `djangoldp_project` packages
On `config.json`:
On `config.json`:
```json
"endpoints": {
@ -165,44 +192,35 @@ On `config.json`:
(In development) Directory includes a listing of each users of your app and editable individual profile. To activate them, you need:
On `config.json`:
On Server: `djangoldp_skill`, `djangoldp_upload` packages
On `config.json`:
```json
"publicDirectory": true,
"endpoints": {
"users": "http://server.url/users/",
"groups": "http://server.url/groups/",
"skills": "http://server.url/skills/",
"uploads": "http://server.url/upload/"
}
```
### Dashboard
### Job Offers
Dashboard includes card generation from HTML. To activate them, you need:
(In development) Job Offers includes a job board with conversation. To activate them, you need:
On `config.json`:
On Server: `djangoldp_joboffer`, `djangoldp_skill`, `djangoldp_upload`, `djangoldp_conversation` packages
On `config.json`:
```json
"endpoints": {
"dashboard": "http://server.url/dashboard/"
"joboffers": "http://server.url/joboffers/",
"skills": "http://server.url/skills/",
"uploads": "http://server.url/upload/"
}
```
### Analytics
SIB App support Google or Matomo as analytics trackers. To use them, add to your `config.json`:
```json
"analytics": [
{
"type": "matomo", //Or "google"
"url": "https://my-personal-.matomo.cloud/",
"id": "1"
}
]
```
## Built With
* [Sib-Core](https://git.happy-dev.fr/startinblox/framework/sib-core/) - An awesome new framework!
* [Sib-Core](https://git.startinblox.com/framework/sib-core/) - An awesome new framework!

View File

@ -1,41 +1,16 @@
{
"xmpp": "https://jabber.happy-dev.fr/http-bind/",
"authority": "http://localhost:8000/",
"clientName": "Sib App",
"clientLogo": "/images/logo.png",
"clientLogoHeight": "32px",
"clientCSS": "/path/to/custom.css",
"authorityName": "djangoldp-server-name",
"publicDirectory": false,
"endpoints": {
"get": {
"dashboards": "http://localhost:8000/dashboards/",
"groups": "http://localhost:8000/groups/",
"circles": "http://localhost:8000/circles/",
"projects": "http://localhost:8000/projects/",
"customers": "http://localhost:8000/customers/",
"businessproviders": "http://localhost:8000/sources/businessproviders/",
"skills": "http://localhost:8000/sources/skills/",
"events": "http://localhost:8000/events/",
"typeevents": "http://localhost:8000/typeevents/",
"skills": "http://localhost:8000/skills/",
"users": "http://localhost:8000/users/",
"groups": "http://localhost:8000/groups/",
"uploads": "http://localhost:8000/upload/"
"groups": "http://localhost:8000/groups/"
},
"post": {
"dashboards": "http://localhost:8000/dashboards/",
"groups": "http://localhost:8000/groups/",
"circles": "http://localhost:8000/circles/",
"projects": "http://localhost:8000/projects/",
"customers": "http://localhost:8000/customers/",
"businessproviders": "http://localhost:8000/sources/businessproviders/",
"skills": "http://localhost:8000/sources/skills/",
"events": "http://localhost:8000/events/",
"typeevents": "http://localhost:8000/typeevents/",
"skills": "http://localhost:8000/skills/",
"users": "http://localhost:8000/users/",
"groups": "http://localhost:8000/groups/",
"uploads": "http://localhost:8000/upload/"
"groups": "http://localhost:8000/groups/"
}
},
"analytics": []
}
}

View File

@ -1,25 +1,10 @@
{
"xmpp": "https://jabber.happy-dev.fr/http-bind/",
"authority": "http://localhost:8000/",
"clientName": "Sib App",
"clientLogo": "/images/logo.png",
"clientLogoHeight": "32px",
"clientCSS": "/path/to/custom.css",
"authorityName": "djangoldp-server-name",
"publicDirectory": false,
"endpoints": {
"dashboards": "http://localhost:8000/dashboards/",
"groups": "http://localhost:8000/groups/",
"circles": "http://localhost:8000/circles/",
"projects": "http://localhost:8000/projects/",
"customers": "http://localhost:8000/customers/",
"businessproviders": "http://localhost:8000/sources/businessproviders/",
"skills": "http://localhost:8000/sources/skills/",
"events": "http://localhost:8000/events/",
"groups": "http://localhost:8000/groups/",
"typeevents": "http://localhost:8000/typeevents/",
"skills": "http://localhost:8000/skills/",
"users": "http://localhost:8000/users/",
"uploads": "http://localhost:8000/upload/"
},
"analytics": []
"groups": "http://localhost:8000/groups/"
}
}

2
package-lock.json generated
View File

@ -1,5 +1,5 @@
{
"name": "sib-app",
"name": "hubl",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,

View File

@ -1,10 +1,10 @@
{
"name": "sib-app",
"name": "hubl",
"version": "1.0.0",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://git.startinblox.com/applications/sib-app.git"
"url": "https://git.startinblox.com/applications/hubl.git"
},
"scripts": {
"build": "run-p copy:* build:*",

View File

@ -1,37 +1,38 @@
script(src="/scripts/index.js")
script(type="module" src="https://unpkg.com/@startinblox/core@0.9" defer)
//- script(type="module" src="/lib/sib-core/dist/index.js" defer)
//- Scripts - use add `"libLocal" = true` on config.json to use your local `lib` folder
if libLocal
script(type="module" src="/lib/sib-oidc/index.js")
script(type="module" src="/lib/sib-router/src/index.js")
script(type="module" src="/lib/sib-notifications/index.js")
if endpoints.users || (endpoints.get && endpoints.get.users)
script(type="module" src="/lib/sib-chat/sib-chat.js")
if endpoints.events || (endpoints.get && endpoints.get.events)
script(type="module" src="/lib/sib-event/sib-event.js")
if endpoints.joboffers || (endpoints.get && endpoints.get.joboffers)
script(type="module" src="/lib/sib-job-board/sib-job-board.js")
script(type="module" src="/lib/sib-conversation/sib-conversation.js")
if publicDirectory && (endpoints.users || (endpoints.get && endpoints.get.users))
script(type="module" src="/lib/sib-directory/sib-directory.js")
if endpoints.dashboards || (endpoints.get && endpoints.get.dashboards)
script(type="module" src="/lib/sib-dashboard/sib-dashboard.js")
else
script(type="module" src="https://unpkg.com/@startinblox/oidc@0.8")
script(type="module" src="https://unpkg.com/@startinblox/core@0.9")
script(type="module" src="https://unpkg.com/@startinblox/router@0.7")
script(type="module" src="https://unpkg.com/@startinblox/component-notifications@0.3")
if endpoints.users || (endpoints.get && endpoints.get.users)
script(type="module" src="https://unpkg.com/@startinblox/component-chat@0.5")
if endpoints.events || (endpoints.get && endpoints.get.events)
script(type="module" src="https://unpkg.com/@startinblox/component-event@0.1")
if endpoints.joboffers || (endpoints.get && endpoints.get.joboffers)
script(type="module" src="https://unpkg.com/@startinblox/component-job-board@0.3")
script(type="module" src="https://unpkg.com/@startinblox/component-conversation@0.3")
if publicDirectory && (endpoints.users || (endpoints.get && endpoints.get.users))
script(type="module" src="https://unpkg.com/@startinblox/component-directory@0.3")
if endpoints.dashboards || (endpoints.get && endpoints.get.dashboards)
script(type="module" src="https://unpkg.com/@startinblox/component-dashboard@0.1")
script(type="module" src="https://unpkg.com/@startinblox/oidc@0.8" defer)
//- script(type="module" src="/lib/sib-oidc/index.js" defer)
script(type="module" src="https://unpkg.com/@startinblox/router@0.7" defer)
//- script(type="module" src="/lib/sib-router/src/index.js" defer)
script(type="module" src="https://unpkg.com/@startinblox/component-notifications@0.3" defer)
//- script(type="module" src="/lib/sib-notifications/index.js" defer)
if endpoints.events || (endpoints.get && endpoints.get.events)
script(type="module" src="https://unpkg.com/@startinblox/component-event@0.1" defer)
//- script(type="module" src="/lib/sib-event/sib-event.js" defer)
if endpoints.joboffers || (endpoints.get && endpoints.get.joboffers)
script(type="module" src="https://unpkg.com/@startinblox/component-job-board@0.3" defer)
script(type="module" src="https://unpkg.com/@startinblox/component-conversation@0.3" defer)
//- script(type="module" src="/lib/sib-job-board/sib-job-board.js" defer)
//- script(type="module" src="/lib/sib-conversation/sib-conversation.js" defer)
if publicDirectory && (endpoints.users || (endpoints.get && endpoints.get.users))
script(type="module" src="https://unpkg.com/@startinblox/component-directory@0.3" defer)
//- script(type="module" src="/lib/sib-directory/sib-directory.js" defer)
if endpoints.dashboards || (endpoints.get && endpoints.get.dashboards)
script(type="module" src="https://unpkg.com/@startinblox/component-dashboard@0.1" defer)
//- script(type="module" src="/lib/sib-dashboard/sib-dashboard.js" defer)
if endpoints.users || (endpoints.get && endpoints.get.users)
script(type="module" src="https://unpkg.com/@startinblox/component-chat@0.6" defer)
//- script(type="module" src="/lib/sib-chat/sib-chat.js" defer)
script(src="/scripts/index.js" defer)
//- Stylesheets
link(rel='stylesheet', href='/styles/index.css')

View File

@ -12,13 +12,13 @@ sib-notifications.notLoggedIn(
bind-user
)
include templates/hd-user-avatar.pug
include templates/hubl-user-avatar.pug
details#user-controls.notLoggedIn
summary(tabindex='0' role='button')
sib-display#user-controls__profile(
fields='first_name, account.picture'
widget-account.picture='hd-user-avatar'
widget-account.picture='hubl-user-avatar'
bind-user
)
#user-controls__panel
@ -41,6 +41,6 @@ sib-auth(style='display:none!important')
sib-auth-provider(
data-authority=`${authority}`
data-id=`${authorityName || "authority"}`
data-client-name=`${clientName || "SIB App"}`
data-client-name=`${clientName || "Hubl"}`
)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -3,10 +3,13 @@ doctype html
html(lang="en")
head
meta(charset="UTF-8")
title #{clientName || "Sib App"}
title #{clientName || "My Personal Hubl"}
meta(name="viewport", content="width=device-width, initial-scale=1.0")
meta(http-equiv="X-UA-Compatible", content="ie=edge")
link(rel="icon" type="image/png" href="/images/favicon.png")
if clientFavicon
link(rel="icon" type="image/png" href=`${clientFavicon}`)
else
link(rel="icon" type="image/png" href="/images/favicon.png")
include dependencies.pug
if clientCSS
link(rel='stylesheet', href=`${clientCSS}`)

View File

@ -1,33 +1,41 @@
sib-widget(name='hd-counter')
sib-widget(name='hubl-counter')
template
sib-fix-badge(data-src="${value == 'badge' ? src : value}")
sib-widget(name='hd-create')
sib-widget(name='hubl-menu-jabberid')
template
div.hidden(
data-jabberID="${value}"
)
sib-widget(name='hubl-create')
template
p.create Tu ne fais partie d'aucun ${value}.
br
| Pour en créer un nouveau, tu peux te rendre dans le
sib-link(next='admin') panneau d'administration
sib-widget(name='menu-fix-url-circle')
sib-widget(name='hubl-menu-fix-url-circle')
template
sib-display(
data-src='${value}'
fields='name, badge'
fields='name, jabberID, badge'
value-badge='${value}'
widget-badge='hd-counter'
widget-badge='hubl-counter'
widget-jabberID='hubl-menu-jabberid'
widget-name='sib-display-div'
)
sib-widget(name='menu-fix-url-project')
sib-widget(name='hubl-menu-fix-url-project')
template
sib-display(
data-src='${value}'
fields='project(customer.name, name), badge'
fields='project(customer.name, name, jabberID), badge'
class-name='project-name'
class-customer.name='project-customer'
value-badge='${value}'
widget-badge='hd-counter'
widget-jabberID='hubl-menu-jabberid'
widget-badge='hubl-counter'
widget-name='sib-display-div'
)
@ -67,9 +75,9 @@ nav#main__menu.jsLeftMenu
bind-user
nested-field='projects'
fields='project'
empty-widget='hd-create'
empty-widget='hubl-create'
empty-value='project'
widget-project='menu-fix-url-project'
widget-project='hubl-menu-fix-url-project'
order-by='project.customer.name'
next='project'
)
@ -88,9 +96,9 @@ nav#main__menu.jsLeftMenu
bind-user
nested-field='circles'
fields='circle'
empty-widget='hd-create'
empty-widget='hubl-create'
empty-value='circle'
widget-circle='menu-fix-url-circle'
widget-circle='hubl-menu-fix-url-circle'
order-by='circle.name'
next='circle'
)
@ -106,9 +114,10 @@ nav#main__menu.jsLeftMenu
div.sub-menu.menu-notification
sib-display.nosub(
data-src=`${endpoints.users || (endpoints.get && endpoints.get.users)}`
fields='username, badge'
widget-username='sib-display-div'
widget-badge='hd-counter'
fields='name, chatProfile.jabberID, badge'
widget-name='sib-display-div'
widget-badge='hubl-counter'
widget-chatProfile.jabberID='hubl-menu-jabberid'
action-badge='badge'
order-by='username'
next='messages'

View File

@ -1,16 +1,22 @@
.content-box.full-width
sib-display.content-box__header(
bind-resources
fields='username'
fields='name, parenthesis, username, endParenthesis'
value-parenthesis=" ("
value-endParenthesis=")"
class-parenthesis='name'
class-endParenthesis='name'
class-name='name'
class-username='name'
)
.chat-view
sib-chat(
data-authentication='login',
data-auto-login='true',
data-bosh-service-url=`${xmpp}`,
data-debug='false',
data-locales-url='en',
data-i18n='en',
bind-resources
)

View File

@ -1,4 +1,4 @@
include templates/template-groups.pug
include templates/hubl-groups.pug
.content-box.with-form.user-profile__container
@ -19,7 +19,7 @@ include templates/template-groups.pug
label-groups=''
multiple-groups=''
widget-groups='groups-name'
widget-groups='hubl-groups-name'
class-username='username'
)
@ -48,7 +48,7 @@ include templates/template-groups.pug
class-account.picture='form-label is-light'
label-account.picture='your picture'
widget-instruction='hd-instruction'
widget-instruction='hubl-instruction'
)
.section.user-skills
@ -65,7 +65,7 @@ include templates/template-groups.pug
)
sib-widget(name='hd-instruction')
sib-widget(name='hubl-instruction')
template
span Show us your most beautiful smile
p Pictures help us to know ourselves and also to recognize ourselves, so don't be afraid to show your pretty face and avoid strange avatars.

View File

@ -1,363 +0,0 @@
function applyAdapt(prefix, sibDisplay, user) {
//- Allow to bind-user on selected attribute
if (sibDisplay.getAttribute(prefix + "-user-id")) {
sibDisplay.setAttribute(
sibDisplay.getAttribute(prefix + "-user-id"),
user["@id"]
);
}
//- Allow to set data-src to a children sib-form
if (sibDisplay.getAttribute(prefix + "-bind-resources")) {
let form = sibDisplay.querySelector(
sibDisplay.getAttribute(prefix + "-bind-resources") + " sib-form"
);
if (form) {
form.setAttribute(
"data-src",
sibDisplay.component.resourceId.replace("members/", "")
);
}
}
//- Allow to put user on a targetted search field
if (sibDisplay.getAttribute(prefix + "-bind-user2input")) {
sibDisplay.querySelector(
sibDisplay.getAttribute(prefix + "-bind-user2input")
).value = user["@id"];
}
}
function recursiveAdaptWidgets(prefix, element, user) {
element.addEventListener("populate", () => {
//- This function is a workaround for the currently unworking populate
//- Feel free to see examples on page-circles-
element.querySelectorAll("[" + prefix + "-user-id]").forEach(el => {
el.setAttribute(el.getAttribute(prefix + "-user-id"), user["@id"]);
});
applyAdapt(prefix, element, user);
document.querySelectorAll('sib-display, sib-form').forEach(sibDisplay => {
applyAdapt(prefix, sibDisplay, user);
});
});
}
// auxiliary function closes the user profile menu
function closeUserControls() {
let userControls = document.querySelector("#user-controls");
if (userControls) userControls.removeAttribute("open");
}
function closeLeftMenu() {
let leftMenu = document.querySelector("#main__menu");
if (leftMenu) leftMenu.removeAttribute("open");
}
function closeRightMenu() {
let rightMenu = document.querySelectorAll(".jsRightMenu");
if (Array.from(rightMenu).filter(el => el.hasAttribute("open")).length > 0) {
Array.from(document.querySelectorAll(".views-container")).forEach(vC =>
vC.classList.toggle("sidebar-is-closed")
);
Array.from(rightMenu).forEach(el => el.removeAttribute("open"));
}
}
function openRightMenu() {
let rightMenu = document.querySelectorAll(".jsRightMenu");
Array.from(rightMenu).forEach(el => el.setAttribute("open", ""));
Array.from(document.querySelectorAll(".views-container")).forEach(vC =>
vC.classList.toggle("sidebar-is-closed")
);
}
//auxiliary function clears cache & refreshes sib-displays for a given resource ID
function refreshSibDisplays(resourceId, clearCache = true) {
let cacheCleared = false;
Array.from(document.querySelectorAll("sib-display"))
.filter(sibDisplay => sibDisplay.component.resourceId == resourceId) // keep only elements with resource == edited resource
.forEach(e => {
//clear cache if we were unable to before
if ((clearCache && !cacheCleared) && e.component.resource != null) {
e.component.resource.clearCache();
cacheCleared = true;
}
e.dataset.src = e.dataset.src;
}); // and update them
}
async function updateSources(resource) {
let res = resource.split('/');
res.splice(3, 0, 'sources');
let cacheCleared = false;
if (event.target.component.resource != null) {
event.target.component.resource.clearCache();
cacheCleared = true;
}
refreshSibDisplays(res.join('/'),cacheCleared);
}
//auxiliary function updates displays using a given resource
//NOTE: this is a temporary workaround and should be replaced by a reactive storage
//https://git.happy-dev.fr/startinblox/framework/sib-core/issues/524
async function refreshResource(event) {
// if of the edited resource || id of the container of the created resource
const resourceId = event.detail.resource["@id"] || event.target.dataset.src;
updateSources(resourceId, event);
let resource = document
.querySelector('[data-src="' + resourceId + '"]')
.component.resource.getResourceData();
//special case: refresh circles/X/ from circle-members/Y/
let partnerId = null;
if (resourceId.includes("circle-members")) {
partnerId = resource["http://happy-dev.fr/owl/#circle"]["@id"];
} else if (resourceId.includes("project-members")) {
partnerId = resource["http://happy-dev.fr/owl/#project"]["@id"];
}
//refresh all resources using the partner ID
if (partnerId != null) {
refreshSibDisplays(partnerId);
refreshSibDisplays(partnerId + "members/");
}
//special cases updating users/X/circles for the left-side-menu (leaving or joining circle)
let user = await document.querySelector('sib-auth').getUser();
if(resourceId.includes('circle') && user != null) {
let userId = user['@id'];
refreshSibDisplays(userId + "circles/");
refreshSibDisplays(resourceId.split('/').slice(0,4).join('/')+'/joinable/');
}
//clear cache on this resource
//NOTE: this is required because the cache is not refreshed after POSTing changes on the resource
let cacheCleared = false;
if (event.target.component.resource != null) {
event.target.component.resource.clearCache();
cacheCleared = true;
}
//update all displays which use this resource
refreshSibDisplays(resourceId, cacheCleared);
}
//auxiliary function performs a redirect
//NOTE: currently a sib-display is required to dispatch the requestNavigation event
function performRedirect(route) {
document.dispatchEvent(
new CustomEvent("requestNavigation", {
bubbles: true,
detail: { route: route }
})
);
}
//auxiliary function redirects after leaving a project/circle
//NOTE: this is a temporary workaround until the following issues are resolved:
//https://git.happy-dev.fr/startinblox/framework/sib-core/issues/476
//https://git.happy-dev.fr/startinblox/framework/sib-core/issues/546
async function checkForPostLeaveRedirect(event) {
//a redirect will only be required if I left in the information page of the resource
if(!window.location.href.includes('-information')) return;
//first need to get a sib-display with this resource id (to have access to the target Proxy, containing model fields)
const resourceId = event.detail.resource['@id'] || event.target.dataset.src;
let target = document.querySelector('[data-src="' + resourceId + '"]');
let resource = target.component.resource.getResourceData();
//no redirect is required for public circles
let targetCircleId = resource["http://happy-dev.fr/owl/#circle"]["@id"];
if(targetCircleId != undefined) {
let targetCircle = document.querySelector('[data-src="' + targetCircleId + '"]');
let targetCircleResource = targetCircle.component.resource.getResourceData();
if(targetCircleResource['http://happy-dev.fr/owl/#status'] == 'Public') return;
}
//a redirect will only be required if I've deleted myself
let targetUser = resource['http://happy-dev.fr/owl/#user'];
//compare with current user
let user = await document.querySelector('sib-auth').getUser();
if(targetUser['@id'] != user['@id'] && targetUser['@id'] != undefined) return;
//perform the redirect
if(resourceId.includes('circle')) performRedirect('circle-left');
else if(resourceId.includes('project')) performRedirect('project-left');
}
//- Update badges from notifications list
async function updateBadges(element) {
const unreadNotifications = new Map();
const notifications = element.component.resource;
if (!notifications) return;
// Generate unread map
for (let notification of notifications['ldp:contains']) {
if (await notification['unread']) {
const object = await notification['object'];
unreadNotifications.set(object['@id'], (unreadNotifications.get(object['@id']) || 0) + 1);
}
}
// update badges
unreadNotifications.forEach((notifNumber, objectId) => {
const badge = document.querySelector(`sib-fix-badge[data-src="${objectId}"]`);
if (badge) {
badge.innerText = notifNumber || '';
badge.style.display = notifNumber ? 'block' : 'none';
}
})
}
document.addEventListener("DOMContentLoaded", function(event) {
const menuWrappers = Array.from(document.querySelectorAll(".menu-wrapper"));
//- View change event
window.addEventListener("navigate", event => {
closeLeftMenu();
closeUserControls();
});
//- Toggle sub-menus
menuWrappers.forEach(menuWrapper => {
const menu = menuWrapper.querySelector(".menu");
menu.addEventListener("click", e => {
menuWrapper.classList.toggle("is-closed");
});
});
//- Watch every sib-forms & update data-src of linked sib-display
document.querySelector("body").addEventListener("save", event => {
refreshResource(event);
});
document.querySelector("body").addEventListener("resourceDeleted", event => {
//I might need to be redirected from this page
checkForPostLeaveRedirect(event).then(refreshResource(event));
});
document
.querySelector("sib-auth")
.getUser()
.then(user => {
if (user !== null) {
document
.querySelectorAll(".notLoggedIn")
.forEach(el => (el.style.visibility = "visible"));
// Hide login button if already logged
document
.querySelector('.loggedIn')
.setAttribute("style", "display:none !important");
document.querySelectorAll('sib-display, sib-form').forEach(element => {
// Set current user id on set-user-id of sib-display
recursiveAdaptWidgets("hd-inherit", element, user);
});
for (leaveBtn of document.querySelectorAll(
"admin-circle-leave > sib-ac-checker:not([hidden])"
)) {
leaveBtn.parentNode.parentNode.parentNode.nextElementSibling.setAttribute(
"style",
"display:none !important"
); // Hide Join button
}
} else {
document.querySelector('sib-auth').login();
}
})
.catch(error => console.log(error));
// Document -> close menu
document.addEventListener("click", event => {
if (!event.target.closest("#user-controls")) {
closeUserControls();
}
if (
!event.target.closest("#main__menu") &&
event.target.id != "toggleMainMenu"
) {
closeLeftMenu();
}
if (
!event.target.className.includes("jsMobileSidebarOpenButton") &&
!event.target.className.includes("jsOffsiteToggle")
) {
closeRightMenu();
}
});
document.querySelector("#toggleMainMenu").addEventListener("click", event => {
let leftMenu = document.querySelector("#main__menu");
if (leftMenu.hasAttribute("open")) {
closeLeftMenu();
} else {
leftMenu.setAttribute("open", "");
}
});
Array.from(document.querySelectorAll(".jsMobileSidebarOpenButton")).forEach(
el => {
el.addEventListener("click", event => {
openRightMenu();
});
}
);
const rightMenus = Array.from(document.querySelectorAll("nav.jsRightMenu"));
rightMenus.forEach(rightMenu => {
const btnRightMenu = rightMenu.querySelector("li.jsOffsiteToggle");
btnRightMenu.addEventListener("click", e => {
if (rightMenu.hasAttribute("open")) {
closeRightMenu();
} else {
openRightMenu();
}
});
});
// listen for keypress
document.onkeydown = e => {
e = e || window.event;
if (e.key === "Escape" || e.key === "Esc") {
closeUserControls();
closeLeftMenu();
closeRightMenu();
}
};
//- Fix badges performances
// on load time
const checkNotificationMenuExist = setInterval(function () { // wait for notification menu to exist
const notifsMenu = document.getElementById('notifications-list');
if (notifsMenu) {
clearInterval(checkNotificationMenuExist);
notifsMenu.addEventListener('populate', (event) => {
const checkExist = setInterval(function () { // wait for left menus to exist
const subMenus = document.querySelectorAll('.sub-menu > sib-display > div');
if (subMenus.length >= 2) {
updateBadges(event.target);
clearInterval(checkExist);
}
}, 500);
}, { once: true });
}
}, 500);
// on refresh notification list
window.addEventListener('notificationsRefresh', () => {
document.getElementById('notifications-list').addEventListener('populate', (event) => {
updateBadges(event.target);
}, { once: true });
});
// on read notification
window.addEventListener('read', (event) => {
if (event.detail && event.detail.resource && event.detail.resource['@id']) {
const badge = document.querySelector(`sib-fix-badge[data-src="${event.detail.resource['@id']}"]`);
if (badge) badge.style.display = "none";
}
});
});

View File

@ -0,0 +1,17 @@
document.addEventListener("DOMContentLoaded", function (event) {
document
.querySelector("sib-auth")
.getUser()
.then(user => {
if (user !== null) {
document
.querySelectorAll(".notLoggedIn")
.forEach(el => (el.style.visibility = "visible"));
document
.querySelector('.loggedIn')
.setAttribute("style", "display:none !important");
} else {
document.querySelector('sib-auth').login();
}
});
});

View File

@ -0,0 +1,94 @@
// auxiliary function closes the user profile menu
function closeUserControls() {
let userControls = document.querySelector("#user-controls");
if (userControls) userControls.removeAttribute("open");
}
function closeLeftMenu() {
let leftMenu = document.querySelector("#main__menu");
if (leftMenu) leftMenu.removeAttribute("open");
}
function closeRightMenu() {
let rightMenu = document.querySelectorAll(".jsRightMenu");
if (Array.from(rightMenu).filter(el => el.hasAttribute("open")).length > 0) {
Array.from(document.querySelectorAll(".views-container")).forEach(vC =>
vC.classList.toggle("sidebar-is-closed")
);
Array.from(rightMenu).forEach(el => el.removeAttribute("open"));
}
}
function openRightMenu() {
let rightMenu = document.querySelectorAll(".jsRightMenu");
Array.from(rightMenu).forEach(el => el.setAttribute("open", ""));
Array.from(document.querySelectorAll(".views-container")).forEach(vC =>
vC.classList.toggle("sidebar-is-closed")
);
}
document.addEventListener("DOMContentLoaded", function(event) {
//- View change event
window.addEventListener("navigate", event => {
closeLeftMenu();
closeUserControls();
});
// Document -> close menu
document.addEventListener("click", event => {
if (!event.target.closest("#user-controls")) {
closeUserControls();
}
if (
!event.target.closest("#main__menu") &&
event.target.id != "toggleMainMenu"
) {
closeLeftMenu();
}
if (
!event.target.className.includes("jsMobileSidebarOpenButton") &&
!event.target.className.includes("jsOffsiteToggle")
) {
closeRightMenu();
}
});
// listen for keypress
document.onkeydown = e => {
e = e || window.event;
if (e.key === "Escape" || e.key === "Esc") {
closeUserControls();
closeLeftMenu();
closeRightMenu();
}
};
document.querySelector("#toggleMainMenu").addEventListener("click", event => {
let leftMenu = document.querySelector("#main__menu");
if (leftMenu.hasAttribute("open")) {
closeLeftMenu();
} else {
leftMenu.setAttribute("open", "");
}
});
const rightMenus = Array.from(document.querySelectorAll("nav.jsRightMenu"));
rightMenus.forEach(rightMenu => {
const btnRightMenu = rightMenu.querySelector("li.jsOffsiteToggle");
btnRightMenu.addEventListener("click", e => {
if (rightMenu.hasAttribute("open")) {
closeRightMenu();
} else {
openRightMenu();
}
});
});
Array.from(document.querySelectorAll(".jsMobileSidebarOpenButton")).forEach(
el => {
el.addEventListener("click", event => {
openRightMenu();
});
}
);
});

View File

@ -0,0 +1,173 @@
//auxiliary function clears cache & refreshes sib-displays for a given resource ID
function refreshSibDisplays(resourceId, clearCache = true) {
let cacheCleared = false;
Array.from(document.querySelectorAll("sib-display"))
.filter(sibDisplay => sibDisplay.component.resourceId == resourceId) // keep only elements with resource == edited resource
.forEach(async (e) => {
//clear cache if we were unable to before
if ((clearCache && !cacheCleared) && e.component.resource != null) {
await e.component.resource.clearCache();
cacheCleared = true;
}
e.dataset.src = e.dataset.src;
}); // and update them
}
async function updateSources(resource) {
let res = resource.split('/');
res.splice(3, 0, 'sources');
let cacheCleared = false;
if (event.target.component.resource != null) {
await event.target.component.resource.clearCache();
cacheCleared = true;
}
refreshSibDisplays(res.join('/'),cacheCleared);
}
//auxiliary function updates displays using a given resource
//NOTE: this is a temporary workaround and should be replaced by a reactive storage
//https://git.startinblox.com/framework/sib-core/issues/524
async function refreshResource(event) {
// if of the edited resource || id of the container of the created resource
const resourceId = event.detail.resource["@id"] || event.target.dataset.src;
updateSources(resourceId, event);
let resource;
try {
resource = document
.querySelector('[data-src="' + resourceId + '"]')
.component.resource.getResourceData();
} catch (e) {
try {
resource = document
.querySelector('[data-src="' + resourceId.replace('circle-members','circles').split('/').slice(0, 4).join('/') + '/"]')
.component.resource.getResourceData();
} catch (e) {
try {
resource = document
.querySelector('[nested-field="' + resourceId.split('/').slice(3, 4).join('').replace('circle-members','circles') + '"]')
.component.resource.getResourceData();
} catch (e) {
resource = undefined;
}
}
}
if(resource) {
//special case: refresh circles/X/ from circle-members/Y/
let partnerId = null;
if (resourceId.includes("circle-members")) {
partnerId = resource["http://happy-dev.fr/owl/#circle"]["@id"];
} else if (resourceId.includes("project-members")) {
partnerId = resource["http://happy-dev.fr/owl/#project"]["@id"];
}
//refresh all resources using the partner ID
if (partnerId != null) {
refreshSibDisplays(partnerId);
refreshSibDisplays(partnerId + "members/");
}
}
//special cases updating users/X/circles for the left-side-menu (leaving or joining circle)
let user = await document.querySelector('sib-auth').getUser();
if(resourceId.includes('circle') && user != null) {
let userId = user['@id'];
refreshSibDisplays(userId + "circles/");
refreshSibDisplays(resourceId.replace('circle-members','circles').split('/').slice(0, 3).join('/') + '/circles/joinable/');
refreshSibDisplays(resourceId.replace('circle-members','circles').split('/').slice(0, 3).join('/') + '/sources/circlesjoinable/');
}
if(resourceId.includes('users')) {
refreshSibDisplays(resourceId.split('/').slice(0, 3).join('/') + '/users/');
refreshSibDisplays(resourceId.split('/').slice(0, 3).join('/') + '/sources/users/');
}
//clear cache on this resource
//NOTE: this is required because the cache is not refreshed after POSTing changes on the resource
let cacheCleared = false;
if (event.target.component.resource != null) {
await event.target.component.resource.clearCache();
cacheCleared = true;
}
//update all displays which use this resource
refreshSibDisplays(resourceId, cacheCleared);
}
//auxiliary function performs a redirect
//NOTE: currently a sib-display is required to dispatch the requestNavigation event
function performRedirect(route) {
document.dispatchEvent(
new CustomEvent("requestNavigation", {
bubbles: true,
detail: { route: route }
})
);
}
//auxiliary function redirects after leaving a project/circle
//NOTE: this is a temporary workaround until the following issues are resolved:
//https://git.startinblox.com/framework/sib-core/issues/476
//https://git.startinblox.com/framework/sib-core/issues/546
async function checkForPostLeaveRedirect(event) {
//a redirect will only be required if I left in the information page of the resource
if(!window.location.href.includes('-information')) {
return;
}
//first need to get a sib-display with this resource id (to have access to the target Proxy, containing model fields)
const resourceId = event.detail.resource['@id'] || event.target.dataset.src;
let target = document.querySelector('[data-src="' + resourceId + '"]');
let resource = target.component.resource.getResourceData();
//no redirect is required for public circles
let targetCircleId = resource["http://happy-dev.fr/owl/#circle"];
if(targetCircleId != undefined) {
let targetCircle = document.querySelector('[data-src="' + targetCircleId["@id"] + '"]');
let targetCircleResource = targetCircle.component.resource.getResourceData();
if(targetCircleResource['http://happy-dev.fr/owl/#status'] == 'Public') {
return;
}
}
//a redirect will only be required if I've deleted myself
let targetUser = resource['http://happy-dev.fr/owl/#user'];
if(targetUser != undefined) {
//compare with current user
let user = await document.querySelector('sib-auth').getUser();
if(targetUser['@id'] != user['@id'] && targetUser['@id'] != undefined) {
return;
}
}
//perform the redirect
if(resourceId.includes('circle')) {
performRedirect('circle-left');
} else if(resourceId.includes('project')) {
performRedirect('project-left');
}
}
document.addEventListener("DOMContentLoaded", function(event) {
const menuWrappers = Array.from(document.querySelectorAll(".menu-wrapper"));
//- Toggle sub-menus
menuWrappers.forEach(menuWrapper => {
const menu = menuWrapper.querySelector(".menu");
menu.addEventListener("click", e => {
menuWrapper.classList.toggle("is-closed");
});
});
//- Watch every sib-forms & update data-src of linked sib-display
document.querySelector("body").addEventListener("save", event => {
refreshResource(event);
});
document.querySelector("body").addEventListener("resourceDeleted", event => {
//I might need to be redirected from this page
checkForPostLeaveRedirect(event).then(refreshResource(event));
});
});

View File

@ -0,0 +1,60 @@
//- Update badges from notifications list
async function updateBadges(element) {
const unreadNotifications = new Map();
const notifications = element.component.resource;
if (!notifications) return;
// Generate unread map
for (let notification of notifications['ldp:contains']) {
if (await notification['unread']) {
const object = await notification['object'];
unreadNotifications.set(object['@id'], (unreadNotifications.get(object['@id']) || 0) + 1);
}
}
// update badges
unreadNotifications.forEach((notifNumber, objectId) => {
const badge = document.querySelector(`sib-fix-badge[data-src="${objectId}"]`);
if (badge) {
badge.innerText = notifNumber || '';
badge.style.display = notifNumber ? 'block' : 'none';
}
})
}
document.addEventListener("DOMContentLoaded", function (event) {
//- Fix badges performances
// on load time
const checkNotificationMenuExist = setInterval(function () { // wait for notification menu to exist
const notifsMenu = document.getElementById('notifications-list');
if (notifsMenu) {
clearInterval(checkNotificationMenuExist);
notifsMenu.addEventListener('populate', (event) => {
const checkExist = setInterval(function () { // wait for left menus to exist
const subMenus = document.querySelectorAll('.sub-menu > sib-display > div');
if (subMenus.length >= 2) {
updateBadges(event.target);
clearInterval(checkExist);
}
}, 500);
}, {
once: true
});
}
}, 500);
// on refresh notification list
window.addEventListener('notificationsRefresh', () => {
document.getElementById('notifications-list').addEventListener('populate', (event) => {
updateBadges(event.target);
}, {
once: true
});
});
// on read notification
window.addEventListener('read', (event) => {
if (event.detail && event.detail.resource && event.detail.resource['@id']) {
const badge = document.querySelector(`sib-fix-badge[data-src="${event.detail.resource['@id']}"]`);
if (badge) badge.style.display = "none";
}
});
});

View File

@ -0,0 +1,15 @@
document.addEventListener("DOMContentLoaded", function (event) {
window.addEventListener('newMessage', event => {
let jid = event.detail.jid;
Array.from(document.querySelectorAll('[data-jabberID="'+jid+'"]')).forEach(el => {
el.parentElement.parentElement.classList.add('unread');
});
});
window.addEventListener('read', (event) => {
if (event.detail && event.detail.resource && event.detail.resource['@id']) {
const badge = document.querySelector(`sib-fix-badge[data-src="${event.detail.resource['@id']}"]`);
if (badge) badge.parentElement.parentElement.classList.remove('unread');
}
});
});

View File

@ -0,0 +1,68 @@
function applyAdapt(prefix, sibDisplay, user) {
//- Allow to bind-user on selected attribute
if (sibDisplay.getAttribute(prefix + "-user-id")) {
sibDisplay.setAttribute(
sibDisplay.getAttribute(prefix + "-user-id"),
user["@id"]
);
}
//- Allow to set data-src to a children sib-form
if (sibDisplay.getAttribute(prefix + "-bind-resources")) {
let form = sibDisplay.querySelector(
sibDisplay.getAttribute(prefix + "-bind-resources") + " sib-form"
);
if (form) {
form.setAttribute(
"data-src",
sibDisplay.component.resourceId.replace("members/", "")
);
}
}
//- Allow to put user on a targetted search field
if (sibDisplay.getAttribute(prefix + "-bind-user2input")) {
let qS = sibDisplay.querySelector(
sibDisplay.getAttribute(prefix + "-bind-user2input")
);
if(qS) qS.value = user["@id"];
}
}
//- This function is a workaround for the currently unworking populate
//- Feel free to see examples on page-circles-
function recursiveAdaptWidgets(prefix, element, user) {
element.addEventListener("populate", () => {
element.querySelectorAll("[" + prefix + "-user-id]").forEach(el => {
el.setAttribute(el.getAttribute(prefix + "-user-id"), user["@id"]);
});
applyAdapt(prefix, element, user);
document.querySelectorAll('sib-display, sib-form').forEach(sibDisplay => {
applyAdapt(prefix, sibDisplay, user);
});
});
}
document.addEventListener("DOMContentLoaded", function (event) {
document
.querySelector("sib-auth")
.getUser()
.then(user => {
if (user !== null) {
document.querySelectorAll('sib-display, sib-form').forEach(element => {
// Set current user id on set-user-id of sib-display
recursiveAdaptWidgets("hubl-inherit", element, user);
});
for (leaveBtn of document.querySelectorAll(
"admin-circle-leave > sib-ac-checker:not([hidden])"
)) {
// Hide Join button
leaveBtn.parentNode.parentNode.parentNode.nextElementSibling.setAttribute(
"style",
"display:none !important"
);
}
}
});
});

View File

@ -398,7 +398,7 @@
/* CUSTOM WIDGETS */
hd-member-form {
hubl-member-form {
width: 100%;
form {

View File

@ -141,7 +141,7 @@
vertical-align: middle;
}
hd-user-avatar {
hubl-user-avatar {
align-items: center;
background-color: $color-213-20-91;
border-radius: 50%;

View File

@ -10,6 +10,10 @@
&.open {
transform: translateX(0);
}
.unread {
font-weight: bolder;
}
sib-router {
@ -119,7 +123,7 @@
}
}
hd-counter {
hubl-counter {
margin-top: 16px;
}
}
@ -145,8 +149,8 @@
>div {
color: $color-244-10-70;
cursor: pointer;
>menu-fix-url-circle>sib-display>div,
>menu-fix-url-project>sib-display>div {
>hubl-menu-fix-url-circle>sib-display>div,
>hubl-menu-fix-url-project>sib-display>div {
padding: 1rem 1rem 1rem 3rem;
}
}
@ -157,8 +161,8 @@
}
&>sib-display[active]>div,
&>sib-display>div>menu-fix-url-circle>sib-display[active]>div,
&>sib-display>div>menu-fix-url-project>sib-display[active]>div {
&>sib-display>div>hubl-menu-fix-url-circle>sib-display[active]>div,
&>sib-display>div>hubl-menu-fix-url-project>sib-display[active]>div {
background-color: $color-46-100-67;
color: $color-233-18-29;
font-weight: bold;
@ -166,18 +170,18 @@
}
&.menu-notification {
> sib-display > div > sib-display > div > menu-fix-url-circle,
> sib-display > div > sib-display > div > menu-fix-url-project {
> sib-display > div > sib-display > div > hubl-menu-fix-url-circle,
> sib-display > div > sib-display > div > hubl-menu-fix-url-project {
flex: 1;
}
> sib-display > div > sib-display > div,
> sib-display > div > sib-display > div > menu-fix-url-circle > sib-display > div,
> sib-display > div > sib-display > div > menu-fix-url-project > sib-display > div {
> sib-display > div > sib-display > div > hubl-menu-fix-url-circle > sib-display > div,
> sib-display > div > sib-display > div > hubl-menu-fix-url-project > sib-display > div {
display: flex;
sib-display-div {
flex: 3;
}
hd-counter {
hubl-counter {
height: 20px;
width: 20px;
margin-right: 1em;

View File

@ -7,6 +7,10 @@
#admin-project-create,
#admin-users-list {
[widget="hubl-team-template-edit"]>div {
flex: 1;
}
.table {
.table-header {
@ -24,7 +28,7 @@
>* {
border-right: 1px solid white;
flex: 1;
//flex: 1;
padding: 2.1rem 0;
text-align: center;
}
@ -34,10 +38,10 @@
}
}
.table-body {
.table-body, .table-header {
>div:first-of-type>sib-display>div,
team-template-edit[name='members'] {
hubl-team-template-edit[name='members'] {
display: flex;
border-left: 1px solid $color-228-25-79;
}
@ -50,6 +54,7 @@
.cell {
text-align: center;
word-wrap: break-word;
white-space: nowrap;
}
.w25 {
@ -64,6 +69,14 @@
width: 50%;
}
.w66 {
width: 66.6666%;
}
.w75 {
width: 75%;
}
.hashtag::before {
content: '#';
}

View File

@ -1,6 +1,6 @@
/* Fix. Could disappear when we can add .class on set fields */
sib-set-default[name='cell-1'] {
@extend .w33;
@extend .w75;
@extend .cell;
@extend .border;
}

View File

@ -34,7 +34,7 @@
display: flex;
padding-left: 1.4rem;
groups-name {
hubl-groups-name {
@extend %tag-role;
}
}
@ -49,7 +49,7 @@
margin-bottom: 1rem;
}
hd-instruction {
hubl-instruction {
margin-left: 1rem;
span {

View File

@ -1,6 +0,0 @@
sib-widget(name='hd-business-provider')
template
ul
li #[span Happy Dev Paris: ] 5%
li #[span Apporteur d'affaire : ] ${await value.name ? await value.name : ""}${await value.name ? "," : ""} ${await value.fee ? await value.fee:0}%

View File

@ -1,6 +1,6 @@
include hd-user-avatar.pug
include hubl-user-avatar.pug
sib-widget(name='hd-captain')
sib-widget(name='hubl-captain')
template
sib-display.user-thumb(
data-src="${await value}"
@ -11,9 +11,6 @@ sib-widget(name='hd-captain')
class-profile.city='user-thumb__city'
class-is_lead='user-thumb__lead'
widget-account.picture='hd-user-avatar'
widget-is_lead='hd-user-lead'
widget-account.picture='hubl-user-avatar'
value-is_lead='Project lead'
)
sib-widget(name='hd-user-lead')
template Project lead

View File

@ -1,6 +1,6 @@
include hd-user-avatar.pug
include hubl-user-avatar.pug
sib-widget(name='circle-team-template')
sib-widget(name='hubl-circle-team-template')
template
sib-display.user-thumb(
data-src='${await value.user}'
@ -13,15 +13,15 @@ sib-widget(name='circle-team-template')
class-groups='tag-group'
class-profile.city='user-thumb__city'
widget-account.picture='hd-user-avatar'
widget-isadmin='hd-circle-user-admin'
widget-groups='hd-circle-user-groups'
widget-account.picture='hubl-user-avatar'
widget-isadmin='hubl-circle-user-admin'
widget-groups='hubl-circle-user-groups'
multiple-groups=''
)
sib-widget(name='hd-circle-user-admin')
sib-widget(name='hubl-circle-user-admin')
template ${(await value) != "false" ? "Administrateur" : ""}
sib-widget(name='hd-circle-user-groups')
sib-widget(name='hubl-circle-user-groups')
template ${await value.name}

View File

@ -1,4 +1,4 @@
sib-widget(name='hd-customer')
sib-widget(name='hubl-customer')
template
div.customer-box
div

View File

@ -0,0 +1,3 @@
sib-widget(name='hubl-groups-name')
template ${value.name}

View File

@ -1,6 +1,6 @@
include hd-user-avatar.pug
include hubl-user-avatar.pug
sib-widget(name='hd-project-team')
sib-widget(name='hubl-project-team')
template
sib-display.user-thumb(
data-src='${await value}'
@ -15,15 +15,15 @@ sib-widget(name='hd-project-team')
class-user.profile.city='user-thumb__city'
class-name='user-thumb__lead'
widget-user.account.picture='hd-user-avatar'
widget-isadmin='hd-project-user-admin'
widget-user.groups='hd-project-user-groups'
widget-user.account.picture='hubl-user-avatar'
widget-isadmin='hubl-project-user-admin'
widget-user.groups='hubl-project-user-groups'
multiple-user.groups=''
)
sib-widget(name='hd-project-user-admin')
sib-widget(name='hubl-project-user-admin')
template ${(await value) == "false" ? "" : "Administrateur"}
sib-widget(name='hd-project-user-groups')
sib-widget(name='hubl-project-user-groups')
template ${await value.name}

View File

@ -1,2 +1,2 @@
sib-widget(name='hd-user-avatar')
sib-widget(name='hubl-user-avatar')
template ${await value ? `<img src="${await value}" style="max-width:100%; max-height: 100%;" />` : `<object type="image/svg+xml" data="/images/alien.svg"></object>`}

View File

@ -1,3 +0,0 @@
sib-widget(name='groups-name')
template ${value.name}

View File

@ -1,8 +0,0 @@
sib-widget(name='joboffers-filter')
template
select
option(name='Offers',disabled) Offers
option(selected,name='Current offers') Current offers
option(name='Expired offers') Expired offers
option(name='All offers') All offers
option(name='My offers') Only my offers

View File

@ -1,5 +0,0 @@
sib-widget(name='skills-name')
template
li(class='skill') ${value.name}

View File

@ -1,4 +0,0 @@
sib-widget(name='status-template')
template
div#member-status ${value == true ? '<span class="status-one">Available</span>' : '<span class="status-two">Busy</span>'}

View File

@ -7,15 +7,12 @@
div.content-box__header
h1.without-margin Administration
#circle-left(hidden)
include ../circle/page-circle-left.pug
include ../circle/page-circle-left.pug
#admin-circle-list(hidden)
include ../../templates/hd-user-avatar.pug
include ../../templates/hubl-user-avatar.pug
sib-widget(name='circle-owner')
sib-widget(name='hubl-circle-owner')
template
sib-display.user-thumb(
data-src='${await value}'
@ -25,7 +22,7 @@
class-name='user-thumb__name'
class-username='user-thumb__username'
widget-account.picture='hd-user-avatar'
widget-account.picture='hubl-user-avatar'
)
@ -43,11 +40,11 @@
.table
div.table-header.grey-color
div Nom
div Administrateurs
div Rejoindre
div.w33 Nom
div.w33 Administrateurs
div.w33 Rejoindre
sib-widget(name='admin-circle-leave-button')
sib-widget(name='hubl-admin-circle-leave-button')
template
sib-delete(
class='button text-bold text-uppercase reversed button-dark bordered with-icon icon-close'
@ -67,21 +64,18 @@
class-leaveButton='w33 cell border cell-with-buttons'
action-leaveButton="joinButton"
widget-leaveButton="admin-circle-leave-button"
widget-circle.owner='circle-owner'
widget-leaveButton="hubl-admin-circle-leave-button"
widget-circle.owner='hubl-circle-owner'
)
sib-widget(name='admin-circle-join-button')
sib-widget(name='hubl-admin-circle-join-button')
template
sib-form.button.text-bold.text-uppercase.reversed.button-blue.bordered.with-icon.icon-arrow-right-circle.flex(
data-src='${value}'
fields='user.@id'
label-user.@id=''
value-user.@id='self'
widget-user.@id='sib-form-hidden'
hd-inherit-bind-user2input="input[name='user.@id']"
fields='user.username'
value-user.username='hubl-workaround-493'
widget-user.username='sib-form-hidden'
submit-button='Rejoindre'
)
@ -94,10 +88,10 @@
class-name='w33 cell border cell-with-name'
class-owner='w33 cell border cell-with-id-card'
widget-owner='circle-owner'
widget-owner='hubl-circle-owner'
class-members='w33 cell border cell-with-buttons'
widget-members="admin-circle-join-button"
widget-members="hubl-admin-circle-join-button"
)

View File

@ -1,11 +1,11 @@
sib-widget(name='hd-template-project-title')
sib-widget(name='hubl-template-project-title')
template
p ${value}
div.content-box__info
sib-link(class="backlink right" next='admin-project-list') Retour
sib-widget(name="admin-project-add-user")
sib-widget(name="hubl-admin-project-add-user")
template
sib-form(
data-holder
@ -25,11 +25,11 @@ div.content-box__info
class-fieldset-fee='fieldset'
value-fieldset-fee='Contributions'
widget-fieldset-fee='hd-template-project-title'
widget-fieldset-fee='hubl-template-project-title'
class-fieldset-captain='fieldset'
value-fieldset-captain='Capitaine'
widget-fieldset-captain='hd-template-project-title'
widget-fieldset-captain='hubl-template-project-title'
label-customer='Nom du client*'
class-customer='member-select form-label is-light is-half-width'

View File

@ -11,7 +11,7 @@
include ../project/page-project-left.pug
#admin-project-list(hidden)
include ../../templates/hd-user-avatar.pug
include ../../templates/hubl-user-avatar.pug
div.content-box__info
div.admin-header
@ -28,7 +28,7 @@
div Capitaines
div Accès
sib-widget(name="admin-project-leave-button")
sib-widget(name="hubl-admin-project-leave-button")
template
sib-delete(
class='button text-bold text-uppercase reversed button-dark bordered with-icon icon-close'
@ -36,7 +36,7 @@
data-label='Quitter'
)
sib-widget(name='project-captain')
sib-widget(name='hubl-project-captain')
template
sib-display.user-thumb(
data-src='${await value}'
@ -46,10 +46,10 @@
class-name='user-thumb__name'
class-username='user-thumb__username'
widget-account.picture='hd-user-avatar'
widget-account.picture='hubl-user-avatar'
)
sib-widget(name='project-admins')
sib-widget(name='hubl-project-admins')
template
sib-display(
data-src='${value}'
@ -57,21 +57,21 @@
search-fields='is_admin'
search-value-is_admin='true'
search-widget-is_admin='sib-form-hidden'
widget-user='project-captain'
widget-user='hubl-project-captain'
)
sib-widget(name="admin-project-buttons")
sib-widget(name="hubl-admin-project-buttons")
template
sib-display(
data-src='${src}'
nested-field='members'
fields='relation'
action-relation='relation'
widget-relation='admin-project-leave-button'
widget-relation='hubl-admin-project-leave-button'
search-fields='user'
search-widget-user='sib-form-hidden'
search-value-user="-"
hd-inherit-user-id="search-value-user"
hubl-inherit-user-id="search-value-user"
)
sib-display(
@ -88,8 +88,8 @@
widget-buttons="admin-project-buttons"
action-buttons="buttons"
widget-captain='project-captain'
widget-members='project-admins'
widget-captain='hubl-project-captain'
widget-members='hubl-project-admins'
)
#admin-project-create(hidden)

View File

@ -7,22 +7,17 @@ div.content-box__info
data-src=`${endpoints.users || endpoints.post.users}`
range-groups=`${endpoints.groups || endpoints.get.groups}`
fields='line-1(first_name, last_name), line-2(username, email), line-3(password), line-4-border-top(groups)'
fields='line-1(first_name, last_name), line-2(username, email), line-3(password)'
class-first_name='form-label is-light is-half-width'
class-last_name='form-label is-light is-half-width'
class-username='form-label is-light is-half-width'
class-email='form-label is-light is-half-width'
class-groups='form-label is-light is-half-width select-groups'
label-first_name='Prénom *'
label-last_name='Nom *'
label-username='Nom d\'utilisateur *'
label-email='E-mail *'
label-groups='Groupes'
multiple-groups='sib-multiple-select'
widget-groups='sib-form-auto-completion'
value-password=''
widget-password='sib-form-hidden'
@ -31,5 +26,3 @@ div.content-box__info
submit-button='Enregistrer'
)
p Seuls les administrateurs de ta plateforme peuvent créer de nouveaux Groupes dans l'Administration Django.

View File

@ -12,22 +12,17 @@ div.content-box__info
bind-resources=''
range-groups=`${endpoints.groups || endpoints.get.groups}`
fields='line-1(first_name, last_name), line-2(username, email), line-4-border-top(groups)'
fields='line-1(first_name, last_name), line-2(username, email)'
class-first_name='form-label is-light is-half-width'
class-last_name='form-label is-light is-half-width'
class-username='form-label is-light is-half-width'
class-email='form-label is-light is-half-width'
class-groups='form-label is-light is-half-width select-groups'
label-first_name='Prénom *'
label-last_name='Nom *'
label-username='Nom d\'utilisateur *'
label-email='E-mail *'
label-groups='Groupes'
multiple-groups='sib-multiple-select'
widget-groups='sib-form-auto-completion'
next='admin-user-list'

View File

@ -7,7 +7,7 @@
div.content-box__header
h1.without-margin Administration
sib-widget(name='sib-action-hd-custom')
sib-widget(name='hubl-sib-action-custom')
template
sib-ac-checker(data-src="${src}", permission='acl:Write')
sib-link(
@ -16,7 +16,7 @@
next="${value}"
)
sib-widget(name='hd-user-admin-groups-display')
sib-widget(name='hubl-user-admin-groups-display')
template
sib-display(
data-src="${value}"
@ -36,29 +36,24 @@
.table
div.table-header.grey-color
div Nom
div Groupes
div
div.w75 Nom
div.w25
sib-display(
class='table-body'
data-src=`${endpoints.users || endpoints.get.users}`
fields='cell-1(user-thumb(account.picture, sup(name), sub(username))), groups, actions'
fields='cell-1(user-thumb(account.picture, sup(name), sub(username))), actions'
class-account.picture='user-thumb__picture'
class-name='user-thumb__name'
class-username='user-thumb__username'
class-profile.city='user-thumb__city'
widget-account.picture='hd-user-avatar'
class-groups='w33 cell border cell-with-groups'
multiple-groups=''
widget-groups='hd-user-admin-groups-display'
widget-account.picture='hubl-user-avatar'
label-actions='Edit'
action-actions='admin-users-edit'
class-actions='w33 cell border cell-with-buttons'
widget-actions='sib-action-hd-custom'
class-actions='w25 cell border cell-with-buttons'
widget-actions='hubl-sib-action-custom'
order-by='username'
)

View File

@ -3,7 +3,6 @@
data-authentication='login',
data-auto-login='true',
data-bosh-service-url=`${xmpp}`,
data-debug='false',
data-locales-url='en',
data-i18n='en',
bind-resources
)

View File

@ -1,14 +1,14 @@
div.content-box__info
include ../../templates/hd-user-avatar.pug
include ../../templates/hubl-user-avatar.pug
sib-widget(name='hd-user-groups')
sib-widget(name='hubl-user-groups')
template ${await value.name}
sib-widget(name='team-template-edit')
sib-widget(name='hubl-team-template-edit')
template
sib-display.user-thumb(
class='w50 cell border cell-with-id-card user-thumb'
class='w66 cell border cell-with-id-card user-thumb'
data-src='${await value.user}'
fields='account.picture, sup(name, groups), sub(profile.city)'
@ -17,14 +17,14 @@ div.content-box__info
class-groups='user-thumb__groups'
class-profile.city='user-thumb__city'
widget-account.picture='hd-user-avatar'
widget-account.picture='hubl-user-avatar'
multiple-groups=''
widget-groups='hd-user-groups'
widget-groups='hubl-user-groups'
)
sib-ac-checker(
class='w50 cell border'
class='w33 cell border'
permission="acl:Delete"
data-src="${value['@id']}"
)
@ -36,7 +36,7 @@ div.content-box__info
//- Only to show the table grid
sib-ac-checker(
class='w50 cell border'
class='w33 cell border'
no-permission="acl:Delete"
data-src="${value['@id']}"
)
@ -87,8 +87,8 @@ div.content-box__info
.table
div.table-header.grey-color
div Nom
div Accès
div.w66 Nom
div.w33 Accès
//-class='table-body'
sib-display(
@ -97,6 +97,6 @@ div.content-box__info
fields='members'
multiple-members=''
widget-members='team-template-edit'
widget-members='hubl-team-template-edit'
)

View File

@ -1,5 +1,5 @@
#circle-left
#circle-left(hidden)
div.content-box__info(style="padding: 15px")
p Tu as quitté ce canal.
p Ceci est un groupe privé. Pour le rejoindre, rends-toi dans le panneau <sib-link next="admin-circle-list">administration</sib-link> et demande une invitation.
p Pour le rejoindre à nouveau, rends-toi dans le panneau <sib-link next="admin-circle-list">administration</sib-link> ou contacte un administrateur.

View File

@ -3,7 +3,7 @@ sib-router(default-route='circle-profile', hidden)
sib-route(name='circle-edit')
#circle-profile(hidden)
include ../../templates/hd-circle-team.pug
include ../../templates/hubl-circle-team.pug
.content-box__info
.space-between
@ -28,7 +28,7 @@ sib-router(default-route='circle-profile', hidden)
fields='members'
multiple-members=''
widget-members='circle-team-template'
widget-members='hubl-circle-team-template'
)
div.box-button
@ -39,7 +39,7 @@ sib-router(default-route='circle-profile', hidden)
data-label='Supprimer le canal'
)
sib-widget(name='circle-leave-button')
sib-widget(name='hubl-circle-leave-button')
template
sib-delete(
class='button btn-margin-left text-bold text-uppercase reversed button-dark bordered with-icon icon-close'
@ -47,7 +47,7 @@ sib-router(default-route='circle-profile', hidden)
data-label='Quitter le canal'
)
sib-widget(name='circle-join-button')
sib-widget(name='hubl-circle-join-button')
template
button.button.btn-margin-left.text-bold.text-uppercase.reversed.button-dark.bordered.with-icon.icon-arrow-right-circle.flex
sib-form(
@ -59,7 +59,7 @@ sib-router(default-route='circle-profile', hidden)
value-user.@id=''
widget-user.@id='sib-form-hidden'
hd-inherit-bind-user2input="input[name='user.@id']"
hubl-inherit-bind-user2input="input[name='user.@id']"
submit-button='Rejoindre le canal'
)
@ -69,13 +69,13 @@ sib-router(default-route='circle-profile', hidden)
nested-field='members'
fields='relation'
action-relation='relation'
widget-relation='circle-leave-button'
widget-relation='hubl-circle-leave-button'
search-fields='user'
search-widget-user='sib-form-hidden'
search-value-user=""
empty-widget='circle-join-button'
hd-inherit-bind-resources='circle-join-button'
hd-inherit-user-id="search-value-user"
empty-widget='hubl-circle-join-button'
hubl-inherit-bind-resources='hubl-circle-join-button'
hubl-inherit-user-id="search-value-user"
)

View File

@ -3,7 +3,6 @@
data-authentication='login',
data-auto-login='true',
data-bosh-service-url=`${xmpp}`,
data-debug='false',
data-locales-url='en',
data-i18n='en',
bind-resources
)

View File

@ -1,8 +1,8 @@
div.content-box__info
include ../../templates/hd-user-avatar.pug
include ../../templates/hubl-user-avatar.pug
sib-widget(name='hd-fieldset-title')
sib-widget(name='hubl-fieldset-title')
template
label ${label}
@ -24,7 +24,7 @@ div.content-box__info
range-customer=`${endpoints.customers || endpoints.get.customers}`
label-name='Nom du projet*'
label-description='Description du projet'
widget-fieldset-info='hd-fieldset-title'
widget-fieldset-info='hubl-fieldset-title'
widget-description='sib-form-textarea'
class-fieldset-fee='fieldset'
@ -33,7 +33,7 @@ div.content-box__info
label-fieldset-fee='Contributions'
label-businessprovider='Apporteur d\'affaire'
label-businessproviderfee='Montant de la contribution'
widget-fieldset-fee='hd-fieldset-title'
widget-fieldset-fee='hubl-fieldset-title'
submit-button='Enregistrer'
)
@ -66,5 +66,5 @@ div.content-box__info
fields='members'
multiple-members=''
widget-members='team-template-edit'
widget-members='hubl-team-template-edit'
)

View File

@ -3,11 +3,10 @@ sib-router(default-route='project-profile', hidden)
sib-route(name='project-edit')
#project-profile(hidden)
include ../../templates/hd-business-provider.pug
include ../../templates/hd-captain.pug
include ../../templates/hd-circle-team.pug
include ../../templates/hd-customer.pug
include ../../templates/hd-project-team.pug
include ../../templates/hubl-captain.pug
include ../../templates/hubl-circle-team.pug
include ../../templates/hubl-customer.pug
include ../../templates/hubl-project-team.pug
.content-box__info
@ -33,7 +32,7 @@ sib-router(default-route='project-profile', hidden)
value-label-captain='Capitaine :'
class-label-captain='h2-like'
widget-captain='hd-captain'
widget-captain='hubl-captain'
)
sib-display(
class='customer-logo'
@ -47,19 +46,13 @@ sib-router(default-route='project-profile', hidden)
sib-link(next='project-contributions-help').button-question__position
button(aria-label='modal activator').icon-question.button-question__color
sib-display(
bind-resources
fields='businessProvider',
widget-businessProvider='hd-business-provider'
)
h2 Informations sur le client :
sib-display(
bind-resources
fields='customer'
widget-customer='hd-customer'
widget-customer='hubl-customer'
)
h2 Equipe :
@ -68,11 +61,11 @@ sib-router(default-route='project-profile', hidden)
bind-resources
fields='members'
widget-members='hd-project-team'
widget-members='hubl-project-team'
multiple-members
)
sib-widget(name='project-leave-button')
sib-widget(name='hubl-project-leave-button')
template
sib-delete(
class='button btn-margin-left text-bold text-uppercase reversed button-dark bordered with-icon icon-close'
@ -87,13 +80,13 @@ sib-router(default-route='project-profile', hidden)
fields='relation'
action-relation='relation'
widget-relation='project-leave-button'
widget-relation='hubl-project-leave-button'
search-fields='user'
search-widget-user='sib-form-hidden'
search-value-user=""
hd-inherit-user-id="search-value-user"
hubl-inherit-user-id="search-value-user"
)