From 40792273fe30eac1f89f8017f3e5ca0dcfaec7d6 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Pasquier Date: Fri, 8 May 2020 13:27:44 +0000 Subject: [PATCH] Fixes & Hubl branding --- .gitignore | 1 + README.md | 114 +++--- config.sample.federated.json | 35 +- config.sample.json | 21 +- package-lock.json | 2 +- package.json | 4 +- src/dependencies.pug | 67 ++-- src/header.pug | 6 +- src/images/favicon.png | Bin 1777 -> 7650 bytes src/images/logo.png | Bin 4018 -> 8729 bytes src/index.pug | 7 +- src/menu-left.pug | 39 +- src/page-messages.pug | 12 +- src/page-user-profile.pug | 8 +- src/scripts/index.js | 363 ------------------ src/scripts/login-element-visibility.js | 17 + src/scripts/navigate-event.js | 94 +++++ src/scripts/reactive-store.js | 173 +++++++++ src/scripts/sib-notifications.js | 60 +++ src/scripts/unreads-menu.js | 15 + src/scripts/widget-extension.js | 68 ++++ src/styles/base/form.scss | 2 +- src/styles/base/header.scss | 2 +- src/styles/base/menu-left.scss | 24 +- src/styles/base/table.scss | 19 +- src/styles/layout/user/admin-users.scss | 2 +- src/styles/layout/user/user-profile.scss | 4 +- src/templates/hd-business-provider.pug | 6 - .../{hd-captain.pug => hubl-captain.pug} | 11 +- ...d-circle-team.pug => hubl-circle-team.pug} | 14 +- .../{hd-customer.pug => hubl-customer.pug} | 2 +- src/templates/hubl-groups.pug | 3 + ...project-team.pug => hubl-project-team.pug} | 14 +- ...d-user-avatar.pug => hubl-user-avatar.pug} | 2 +- src/templates/template-groups.pug | 3 - src/templates/template-joboffers-filter.pug | 8 - src/templates/template-skills.pug | 5 - src/templates/template-status.pug | 4 - src/views/admin/page-admin-circles.pug | 38 +- .../admin/page-admin-projects-create.pug | 8 +- src/views/admin/page-admin-projects.pug | 22 +- src/views/admin/page-admin-users-create.pug | 9 +- src/views/admin/page-admin-users-edit.pug | 7 +- src/views/admin/page-admin-users.pug | 21 +- src/views/circle/page-circle-chat.pug | 3 +- src/views/circle/page-circle-edit.pug | 22 +- src/views/circle/page-circle-left.pug | 4 +- src/views/circle/page-circle-profile.pug | 18 +- src/views/project/page-project-chat.pug | 3 +- src/views/project/page-project-edit.pug | 10 +- src/views/project/page-project-profile.pug | 27 +- 51 files changed, 722 insertions(+), 701 deletions(-) delete mode 100644 src/scripts/index.js create mode 100644 src/scripts/login-element-visibility.js create mode 100644 src/scripts/navigate-event.js create mode 100644 src/scripts/reactive-store.js create mode 100644 src/scripts/sib-notifications.js create mode 100644 src/scripts/unreads-menu.js create mode 100644 src/scripts/widget-extension.js delete mode 100644 src/templates/hd-business-provider.pug rename src/templates/{hd-captain.pug => hubl-captain.pug} (61%) rename src/templates/{hd-circle-team.pug => hubl-circle-team.pug} (63%) rename src/templates/{hd-customer.pug => hubl-customer.pug} (96%) create mode 100644 src/templates/hubl-groups.pug rename src/templates/{hd-project-team.pug => hubl-project-team.pug} (66%) rename src/templates/{hd-user-avatar.pug => hubl-user-avatar.pug} (82%) delete mode 100644 src/templates/template-groups.pug delete mode 100644 src/templates/template-joboffers-filter.pug delete mode 100644 src/templates/template-skills.pug delete mode 100644 src/templates/template-status.pug diff --git a/.gitignore b/.gitignore index 9ed3cc4..2b25e21 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.iml *.swp dist +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index cbab858..990726f 100644 --- a/README.md +++ b/README.md @@ -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! diff --git a/config.sample.federated.json b/config.sample.federated.json index 953296a..0fa0a63 100644 --- a/config.sample.federated.json +++ b/config.sample.federated.json @@ -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": [] + } } diff --git a/config.sample.json b/config.sample.json index a5b14a5..fa65e10 100644 --- a/config.sample.json +++ b/config.sample.json @@ -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/" + } } diff --git a/package-lock.json b/package-lock.json index a8c3118..e053852 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "sib-app", + "name": "hubl", "version": "1.0.0", "lockfileVersion": 1, "requires": true, diff --git a/package.json b/package.json index 903d0b9..a1b4ce7 100644 --- a/package.json +++ b/package.json @@ -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:*", diff --git a/src/dependencies.pug b/src/dependencies.pug index 97124f4..60b0441 100644 --- a/src/dependencies.pug +++ b/src/dependencies.pug @@ -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') diff --git a/src/header.pug b/src/header.pug index 8662cfc..55d35a8 100644 --- a/src/header.pug +++ b/src/header.pug @@ -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"}` ) diff --git a/src/images/favicon.png b/src/images/favicon.png index a0d43ddb3d4aab6e6c91ba462f564a3ab393b2e5..e7152788c0172d45c7ea4010246284dee8d303e9 100644 GIT binary patch literal 7650 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 Q(*OVf07*qoM6N<$f_s|GIRF3v literal 1777 zcmb_d3sVw^7KXC4TGI6un(d0OZ1pDj09_MJF+rt#;tIa@YWYB=6-_CrOd~6{bwx8@ zna}l!p}2&aXc|_iwPIK|!v~Up*9WVKXzBIdnfn9oot^o<^L=OL%$YND&dj;xcg72} z-*7(w005y;$bcQa@^5PF-H9`%wYfV2Bn5c60~jMlG5}z26B>CcCcrJ=NUn zmjOVn{}r!wjDIdDe&Gu$2q09DIo_+4m=^pYsAkd7Sc)7b=nX2cIJ!beI-l@8su~>t zPjb#57!#sF%zO2=?=I(hj(z+GRc$N}EULgpTD0G!>TjVN@dooM z5wrq@bB%W~(J_Ge__8dgir(Iz&zk02Xp9tfb{-$Cv?{D&wh4V)6WY&PKYH*kXY@-l zIWX;xjG$S(72yy}sCrh5FJwMIlLIq@5o&^#O#{yc+inaVb)v1Xb4zhcNO;0EVig&8y&C_Iz zqbgTADorp1x0=uSjqAV0U>y1SrV+c3+Zd|4BG}LKvu}1#dUJOgG|&l*#tQ=p+hgv* z9*~zHAh_bN)n}L*Z&OlUng~U}vFk}1G$r2|{w^vrxq11$7I>*BJ-MxKed32{HUuiN zS(=E+R&bb4i5^kiks{8Ey<$@IjY(>62Dh6;2l3{3`?(-RC*#4}Zp+D)st9AtN$o#s zyROI%$+Po@n-m?yj6ADXUo>~!#}ZBJHn8cB&um9!9)Y&>81UGg{b?KO;`wXwpN645 zZ;mhouHZ;@-zFke(Xx1cwf_YL^q>Qflo z56hZ}0(oVZPj8bV#e*(zrs{W3R?Z}+E37T9H6SefA8GRr4J|+Jg8p@$Szc=$v|RoT zZ_}d36QT0PNoKThB9pKx3>5Ko-A8Pr;o?|~MlLb#ze}W(x4yZ$B2~JGsSBtGBVDyizTfvHC0hlvB(2{x8aR`@~DTEr*luCiWjzXAJZI z^r@5iYLdmD!{v)$zP4H*MgP+KnsZe)vRh47p`+0Qv6XBP&S1eGRVxS$+)2%);b-Th zZ->H!EGWY2RK+D*(vRxpDZgs-x*kd)R9^*b>UVg2)EQE%3iG!dMQPqFDLX7rWqA^@ zNpBKPPmSokuz1$+bE=bvGTG5lS7ZXHr{npU~SB4fN-n=yElwT>ww z??!9IQGK%(@O`{6$48R#DDL`)JN8h$q=FG*=B*H8z^?xTWRqoAM=oA6|0^$Z=Z68% Mo@bB@_o(at0wPaLBme*a diff --git a/src/images/logo.png b/src/images/logo.png index d47b12090ca2650956f554ac22fccb7253c2aa2a..ea256f29d210e739754ab48ece88df8aa11eb104 100644 GIT binary patch literal 8729 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 GtN#a$v$wwh literal 4018 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 diff --git a/src/index.pug b/src/index.pug index a6fd51f..5ae77e6 100644 --- a/src/index.pug +++ b/src/index.pug @@ -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}`) diff --git a/src/menu-left.pug b/src/menu-left.pug index 9a71b50..2d261c0 100644 --- a/src/menu-left.pug +++ b/src/menu-left.pug @@ -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' diff --git a/src/page-messages.pug b/src/page-messages.pug index f12cb83..545e643 100644 --- a/src/page-messages.pug +++ b/src/page-messages.pug @@ -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 ) diff --git a/src/page-user-profile.pug b/src/page-user-profile.pug index 9cc8d28..d10d1e1 100644 --- a/src/page-user-profile.pug +++ b/src/page-user-profile.pug @@ -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. diff --git a/src/scripts/index.js b/src/scripts/index.js deleted file mode 100644 index 983ae7b..0000000 --- a/src/scripts/index.js +++ /dev/null @@ -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"; - } - }); - -}); diff --git a/src/scripts/login-element-visibility.js b/src/scripts/login-element-visibility.js new file mode 100644 index 0000000..cc0daf1 --- /dev/null +++ b/src/scripts/login-element-visibility.js @@ -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(); + } + }); +}); \ No newline at end of file diff --git a/src/scripts/navigate-event.js b/src/scripts/navigate-event.js new file mode 100644 index 0000000..ba4eb0b --- /dev/null +++ b/src/scripts/navigate-event.js @@ -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(); + }); + } + ); +}); \ No newline at end of file diff --git a/src/scripts/reactive-store.js b/src/scripts/reactive-store.js new file mode 100644 index 0000000..3dc54f7 --- /dev/null +++ b/src/scripts/reactive-store.js @@ -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)); + }); + +}); diff --git a/src/scripts/sib-notifications.js b/src/scripts/sib-notifications.js new file mode 100644 index 0000000..d45bba7 --- /dev/null +++ b/src/scripts/sib-notifications.js @@ -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"; + } + }); +}); \ No newline at end of file diff --git a/src/scripts/unreads-menu.js b/src/scripts/unreads-menu.js new file mode 100644 index 0000000..3cd1904 --- /dev/null +++ b/src/scripts/unreads-menu.js @@ -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'); + } + }); +}); \ No newline at end of file diff --git a/src/scripts/widget-extension.js b/src/scripts/widget-extension.js new file mode 100644 index 0000000..d126f3b --- /dev/null +++ b/src/scripts/widget-extension.js @@ -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" + ); + } + } + }); +}); \ No newline at end of file diff --git a/src/styles/base/form.scss b/src/styles/base/form.scss index 1c4f179..d1b819c 100644 --- a/src/styles/base/form.scss +++ b/src/styles/base/form.scss @@ -398,7 +398,7 @@ /* CUSTOM WIDGETS */ - hd-member-form { + hubl-member-form { width: 100%; form { diff --git a/src/styles/base/header.scss b/src/styles/base/header.scss index 291b92e..eb11c3b 100644 --- a/src/styles/base/header.scss +++ b/src/styles/base/header.scss @@ -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%; diff --git a/src/styles/base/menu-left.scss b/src/styles/base/menu-left.scss index 57bf2be..e9368d8 100644 --- a/src/styles/base/menu-left.scss +++ b/src/styles/base/menu-left.scss @@ -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; diff --git a/src/styles/base/table.scss b/src/styles/base/table.scss index 1d2cb80..db2361d 100644 --- a/src/styles/base/table.scss +++ b/src/styles/base/table.scss @@ -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: '#'; } diff --git a/src/styles/layout/user/admin-users.scss b/src/styles/layout/user/admin-users.scss index 61f0e46..ddf18e7 100644 --- a/src/styles/layout/user/admin-users.scss +++ b/src/styles/layout/user/admin-users.scss @@ -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; } \ No newline at end of file diff --git a/src/styles/layout/user/user-profile.scss b/src/styles/layout/user/user-profile.scss index 2192233..87dafaf 100644 --- a/src/styles/layout/user/user-profile.scss +++ b/src/styles/layout/user/user-profile.scss @@ -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 { diff --git a/src/templates/hd-business-provider.pug b/src/templates/hd-business-provider.pug deleted file mode 100644 index 669f534..0000000 --- a/src/templates/hd-business-provider.pug +++ /dev/null @@ -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}% - \ No newline at end of file diff --git a/src/templates/hd-captain.pug b/src/templates/hubl-captain.pug similarity index 61% rename from src/templates/hd-captain.pug rename to src/templates/hubl-captain.pug index 30a4108..aacb117 100644 --- a/src/templates/hd-captain.pug +++ b/src/templates/hubl-captain.pug @@ -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 diff --git a/src/templates/hd-circle-team.pug b/src/templates/hubl-circle-team.pug similarity index 63% rename from src/templates/hd-circle-team.pug rename to src/templates/hubl-circle-team.pug index c22b713..f985788 100644 --- a/src/templates/hd-circle-team.pug +++ b/src/templates/hubl-circle-team.pug @@ -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} diff --git a/src/templates/hd-customer.pug b/src/templates/hubl-customer.pug similarity index 96% rename from src/templates/hd-customer.pug rename to src/templates/hubl-customer.pug index 791d69a..07abe0b 100644 --- a/src/templates/hd-customer.pug +++ b/src/templates/hubl-customer.pug @@ -1,4 +1,4 @@ -sib-widget(name='hd-customer') +sib-widget(name='hubl-customer') template div.customer-box div diff --git a/src/templates/hubl-groups.pug b/src/templates/hubl-groups.pug new file mode 100644 index 0000000..49bd446 --- /dev/null +++ b/src/templates/hubl-groups.pug @@ -0,0 +1,3 @@ +sib-widget(name='hubl-groups-name') + template ${value.name} + diff --git a/src/templates/hd-project-team.pug b/src/templates/hubl-project-team.pug similarity index 66% rename from src/templates/hd-project-team.pug rename to src/templates/hubl-project-team.pug index acc6280..6d47d27 100644 --- a/src/templates/hd-project-team.pug +++ b/src/templates/hubl-project-team.pug @@ -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} diff --git a/src/templates/hd-user-avatar.pug b/src/templates/hubl-user-avatar.pug similarity index 82% rename from src/templates/hd-user-avatar.pug rename to src/templates/hubl-user-avatar.pug index 8ee2dba..08a2876 100644 --- a/src/templates/hd-user-avatar.pug +++ b/src/templates/hubl-user-avatar.pug @@ -1,2 +1,2 @@ -sib-widget(name='hd-user-avatar') +sib-widget(name='hubl-user-avatar') template ${await value ? `` : ``} diff --git a/src/templates/template-groups.pug b/src/templates/template-groups.pug deleted file mode 100644 index 843a597..0000000 --- a/src/templates/template-groups.pug +++ /dev/null @@ -1,3 +0,0 @@ -sib-widget(name='groups-name') - template ${value.name} - diff --git a/src/templates/template-joboffers-filter.pug b/src/templates/template-joboffers-filter.pug deleted file mode 100644 index b9d5e0d..0000000 --- a/src/templates/template-joboffers-filter.pug +++ /dev/null @@ -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 \ No newline at end of file diff --git a/src/templates/template-skills.pug b/src/templates/template-skills.pug deleted file mode 100644 index cad1b90..0000000 --- a/src/templates/template-skills.pug +++ /dev/null @@ -1,5 +0,0 @@ -sib-widget(name='skills-name') - template - li(class='skill') ${value.name} - - diff --git a/src/templates/template-status.pug b/src/templates/template-status.pug deleted file mode 100644 index c6f5fa8..0000000 --- a/src/templates/template-status.pug +++ /dev/null @@ -1,4 +0,0 @@ -sib-widget(name='status-template') - template - div#member-status ${value == true ? 'Available' : 'Busy'} - diff --git a/src/views/admin/page-admin-circles.pug b/src/views/admin/page-admin-circles.pug index b7f9180..927688b 100644 --- a/src/views/admin/page-admin-circles.pug +++ b/src/views/admin/page-admin-circles.pug @@ -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" ) diff --git a/src/views/admin/page-admin-projects-create.pug b/src/views/admin/page-admin-projects-create.pug index 498a6e7..44c9101 100644 --- a/src/views/admin/page-admin-projects-create.pug +++ b/src/views/admin/page-admin-projects-create.pug @@ -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' diff --git a/src/views/admin/page-admin-projects.pug b/src/views/admin/page-admin-projects.pug index 89fb9f2..bf6e653 100644 --- a/src/views/admin/page-admin-projects.pug +++ b/src/views/admin/page-admin-projects.pug @@ -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) diff --git a/src/views/admin/page-admin-users-create.pug b/src/views/admin/page-admin-users-create.pug index a921df0..ab580b5 100644 --- a/src/views/admin/page-admin-users-create.pug +++ b/src/views/admin/page-admin-users-create.pug @@ -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. diff --git a/src/views/admin/page-admin-users-edit.pug b/src/views/admin/page-admin-users-edit.pug index e6daebb..61fddec 100644 --- a/src/views/admin/page-admin-users-edit.pug +++ b/src/views/admin/page-admin-users-edit.pug @@ -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' diff --git a/src/views/admin/page-admin-users.pug b/src/views/admin/page-admin-users.pug index f0944c3..fc0b5ec 100644 --- a/src/views/admin/page-admin-users.pug +++ b/src/views/admin/page-admin-users.pug @@ -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' ) diff --git a/src/views/circle/page-circle-chat.pug b/src/views/circle/page-circle-chat.pug index 37a3cbc..7e522a2 100644 --- a/src/views/circle/page-circle-chat.pug +++ b/src/views/circle/page-circle-chat.pug @@ -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 ) \ No newline at end of file diff --git a/src/views/circle/page-circle-edit.pug b/src/views/circle/page-circle-edit.pug index 04336b6..c0630b2 100644 --- a/src/views/circle/page-circle-edit.pug +++ b/src/views/circle/page-circle-edit.pug @@ -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' ) diff --git a/src/views/circle/page-circle-left.pug b/src/views/circle/page-circle-left.pug index 978f126..098c61a 100644 --- a/src/views/circle/page-circle-left.pug +++ b/src/views/circle/page-circle-left.pug @@ -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 administration et demande une invitation. + p Pour le rejoindre à nouveau, rends-toi dans le panneau administration ou contacte un administrateur. diff --git a/src/views/circle/page-circle-profile.pug b/src/views/circle/page-circle-profile.pug index f27999d..a6b5b21 100644 --- a/src/views/circle/page-circle-profile.pug +++ b/src/views/circle/page-circle-profile.pug @@ -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" ) diff --git a/src/views/project/page-project-chat.pug b/src/views/project/page-project-chat.pug index 4f16492..cd2c4c2 100644 --- a/src/views/project/page-project-chat.pug +++ b/src/views/project/page-project-chat.pug @@ -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 ) diff --git a/src/views/project/page-project-edit.pug b/src/views/project/page-project-edit.pug index 1650311..2a387f0 100644 --- a/src/views/project/page-project-edit.pug +++ b/src/views/project/page-project-edit.pug @@ -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' ) diff --git a/src/views/project/page-project-profile.pug b/src/views/project/page-project-profile.pug index dbd7758..ffdf5eb 100644 --- a/src/views/project/page-project-profile.pug +++ b/src/views/project/page-project-profile.pug @@ -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" )