diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cbb9c8a..704c6db 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -44,6 +44,7 @@ test:e2e:
before_script:
# install missing dependencies
- npm install -g sirv-cli
+ - npm install cypress-localstorage-commands
# making sure the process is orphan
- sirv dist --port 3000 > /dev/null 2>&1 &
script:
diff --git a/cypress.json b/cypress.json
index 2f9683b..eaf2081 100644
--- a/cypress.json
+++ b/cypress.json
@@ -1,7 +1,8 @@
{
"baseUrl": "http://127.0.0.1:3000",
- "defaultCommandTimeout": 60000,
+ "defaultCommandTimeout": 1000,
"chromeWebSecurity": false,
"viewportWidth": 1920,
- "viewportHeight": 1080
+ "viewportHeight": 1080,
+ "video": false
}
diff --git a/cypress/README.md b/cypress/README.md
new file mode 100644
index 0000000..3081ad7
--- /dev/null
+++ b/cypress/README.md
@@ -0,0 +1,54 @@
+## Users:
+```
+ - signin
+ - signup
+ - create
+ - listing
+ - edit
+ // TO-FIX: Uncomment workaround (blocked by: nested routing bug)
+```
+
+## Job Offers:
+```
+ - create
+ - edit
+ - listing
+ // TO-FIX: Search by title and description (blocked by: no search fields available)
+ - post
+ // TO-DO: Entire flow (blocked by: no published / unpublished flag)
+```
+
+## Channels:
+```
+ - create
+ - edit
+ - leave
+ - retire
+ - delete
+ - join
+ // TO-DO: Join other user created project (blocked by: can't create new user to create a channel)
+ - invite
+ // TO-DO
+```
+
+## Projects:
+```
+ - create
+ - edit
+ - leave
+ - retire
+ - delete
+ // TO-DO: Delete a project (blocked by: no option to delete a project)
+ - join
+ // TO-DO: Join other user created project (blocked by: can't create new user to create a project)
+ - invite
+ // TO-DO
+```
+
+## Breakdown:
+```
+DONE: 15
+TO-FIX: 2
+BLOCKED: 4
+NOT DONE: 2
+```
diff --git a/cypress/fixtures/admin.json b/cypress/fixtures/admin.json
new file mode 100644
index 0000000..fb25ded
--- /dev/null
+++ b/cypress/fixtures/admin.json
@@ -0,0 +1,4 @@
+{
+ "username": "admin",
+ "password": "admin"
+}
\ No newline at end of file
diff --git a/cypress/integration/create-channel.spec.js b/cypress/integration/create-channel.spec.js
new file mode 100644
index 0000000..b28c0f1
--- /dev/null
+++ b/cypress/integration/create-channel.spec.js
@@ -0,0 +1,116 @@
+///
+/* globals cy, expect */
+
+context('Create Channel Browser Testing', () => {
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Channel Creation process #1', () => {
+ let channelName = 'Test Channel ',
+ description = 'Test Description ';
+ it('should visit the channel creation screen', () => {
+ cy.visit('/admin/admin-circle-create');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-circle-create');
+ });
+ });
+ it('should enter correct channel data', () => {
+ cy.randomNum().then(num => {
+ channelName += num;
+ description += num;
+ cy.get('#admin-circle-create input[name="name"]').clear().type(channelName);
+ cy.get('#admin-circle-create input[name="name"]').should('have.value', channelName);
+ cy.get('#admin-circle-create input[name="description"]').clear().type(description);
+ cy.get('#admin-circle-create input[name="description"]').should('have.value', description);
+ });
+ });
+ it('should click on create channel button', () => {
+ cy.get('#admin-circle-create input[type="submit"]').click();
+ });
+ it('should land on channels list screen', () => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin');
+ });
+ });
+ it('should land newly created channel on channels list screen', () => {
+ cy.contains('solid-display-value[name="circle.name"]', channelName).should("exist");
+ cy.fixture('admin.json').then(admin => {
+ cy.contains('solid-display-value[name="username"]', admin.username).should("exist");
+ });
+ });
+ });
+ describe('Channel Creation process #2', () => {
+ let channelName = 'Test Channel ',
+ description = 'Test Description ';
+ it('should visit the channel creation screen', () => {
+ cy.visit('/admin/admin-circle-create');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-circle-create');
+ });
+ });
+ it('should enter correct channel data', () => {
+ cy.randomNum().then(num => {
+ channelName += num;
+ description += num;
+ cy.get('#admin-circle-create input[name="name"]').clear().type(channelName);
+ cy.get('#admin-circle-create input[name="name"]').should('have.value', channelName);
+ cy.get('#admin-circle-create input[name="description"]').clear().type(description);
+ cy.get('#admin-circle-create input[name="description"]').should('have.value', description);
+ });
+ });
+ it('should click on create channel button', () => {
+ cy.get('#admin-circle-create input[type="submit"]').click();
+ });
+ it('should land on channels list screen', () => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin');
+ });
+ });
+ it('should land newly created channel on channels list screen', () => {
+ cy.contains('solid-display-value[name="circle.name"]', channelName).should("exist");
+ cy.fixture('admin.json').then(admin => {
+ cy.contains('solid-display-value[name="username"]', admin.username).should("exist");
+ });
+ });
+ });
+ describe('Channel Creation process #3', () => {
+ let channelName = 'Test Channel ',
+ description = 'Test Description ';
+ it('should visit the channel creation screen', () => {
+ cy.visit('/admin/admin-circle-create');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-circle-create');
+ });
+ });
+ it('should enter correct channel data', () => {
+ cy.randomNum().then(num => {
+ channelName += num;
+ description += num;
+ cy.get('#admin-circle-create input[name="name"]').clear().type(channelName);
+ cy.get('#admin-circle-create input[name="name"]').should('have.value', channelName);
+ cy.get('#admin-circle-create input[name="description"]').clear().type(description);
+ cy.get('#admin-circle-create input[name="description"]').should('have.value', description);
+ });
+ });
+ it('should click on create channel button', () => {
+ cy.get('#admin-circle-create input[type="submit"]').click();
+ });
+ it('should land on channels list screen', () => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin');
+ });
+ });
+ it('should land newly created channel on channels list screen', () => {
+ cy.contains('solid-display-value[name="circle.name"]', channelName).should("exist");
+ cy.fixture('admin.json').then(admin => {
+ cy.contains('solid-display-value[name="username"]', admin.username).should("exist");
+ });
+ });
+ });
+});
diff --git a/cypress/integration/create-job-offer.spec.js b/cypress/integration/create-job-offer.spec.js
new file mode 100644
index 0000000..ad960d4
--- /dev/null
+++ b/cypress/integration/create-job-offer.spec.js
@@ -0,0 +1,52 @@
+///
+/* globals cy, expect */
+
+context('Create Job Offer Browser Testing', () => {
+ let jobDate = '',
+ jobTitle = 'Test Job Offer ',
+ description = 'Test Description ';
+ before(() => {
+ cy.nextYear(1).then(year => {
+ jobDate = year + '-12-31';
+ });
+ cy.randomNum().then(num => {
+ jobTitle += num;
+ description += num;
+ });
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Job Offer Creation process', () => {
+ it('should visit the job offer creation screen', () => {
+ cy.visit('/job-offers/job-offers-create');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/job-offers/job-offers-create');
+ });
+ });
+ it('should enter correct job offer data', () => {
+ cy.get('#job-offers-create input[name="closingDate"]').clear().type(jobDate);
+ cy.get('#job-offers-create input[name="closingDate"]').should('have.value', jobDate);
+ cy.get('#job-offers-create input[name="title"]').clear().type(jobTitle);
+ cy.get('#job-offers-create input[name="title"]').should('have.value', jobTitle);
+ cy.get('#job-offers-create textarea[name="description"]').clear().type(description);
+ cy.get('#job-offers-create textarea[name="description"]').should('have.value', description);
+ });
+ it('should click on create job offer button', () => {
+ cy.get('#job-offers-create input[type="submit"]').click();
+ });
+ it('should land on job offers list screen', () => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/job-offers');
+ });
+ });
+ it('should land newly created job offer on job offers list screen', () => {
+ cy.contains('solid-display-value[name="title"]', jobTitle).should("exist");
+ cy.contains('solid-display-value[name="description"]', description).should("exist");
+ });
+ });
+});
diff --git a/cypress/integration/create-project.spec.js b/cypress/integration/create-project.spec.js
new file mode 100644
index 0000000..8775a1e
--- /dev/null
+++ b/cypress/integration/create-project.spec.js
@@ -0,0 +1,90 @@
+///
+/* globals cy, expect */
+
+context('Create Project Browser Testing', () => {
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Project Creation process #1', () => {
+ let projectName = 'Test Project ',
+ customerName = 'Test Customer ',
+ description = 'Test Description ';
+ it('should visit the project creation screen', () => {
+ cy.visit('/admin/admin-projects/admin-project-create');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-projects/admin-project-create');
+ });
+ });
+ it('should enter correct project data', () => {
+ cy.randomNum().then(num => {
+ projectName += num;
+ customerName += num;
+ description += num;
+ cy.get('#admin-project-create input[name="customer.name"]').clear().type(customerName);
+ cy.get('#admin-project-create input[name="customer.name"]').should('have.value', customerName);
+ cy.get('#admin-project-create input[name="name"]').clear().type(projectName);
+ cy.get('#admin-project-create input[name="name"]').should('have.value', projectName);
+ cy.get('#admin-project-create textarea[name="description"]').clear().type(description);
+ cy.get('#admin-project-create textarea[name="description"]').should('have.value', description);
+ });
+ });
+ it('should click on create project button', () => {
+ cy.get('#admin-project-create input[type="submit"]').click();
+ });
+ it('should land on projects list screen', () => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-projects');
+ });
+ });
+ it('should land newly created project on projects list screen', () => {
+ cy.contains('solid-display-value[name="project.name"]', projectName).should("exist");
+ cy.fixture('admin.json').then(admin => {
+ cy.contains('solid-display-value[name="username"]', admin.username).should("exist");
+ });
+ });
+ });
+ describe('Project Creation process #2', () => {
+ let projectName = 'Test Project ',
+ customerName = 'Test Customer ',
+ description = 'Test Description ';
+ it('should visit the project creation screen', () => {
+ cy.visit('/admin/admin-projects/admin-project-create');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-projects/admin-project-create');
+ });
+ });
+ it('should enter correct project data', () => {
+ cy.randomNum().then(num => {
+ projectName += num;
+ customerName += num;
+ description += num;
+ cy.get('#admin-project-create input[name="customer.name"]').clear().type(customerName);
+ cy.get('#admin-project-create input[name="customer.name"]').should('have.value', customerName);
+ cy.get('#admin-project-create input[name="name"]').clear().type(projectName);
+ cy.get('#admin-project-create input[name="name"]').should('have.value', projectName);
+ cy.get('#admin-project-create textarea[name="description"]').clear().type(description);
+ cy.get('#admin-project-create textarea[name="description"]').should('have.value', description);
+ });
+ });
+ it('should click on create project button', () => {
+ cy.get('#admin-project-create input[type="submit"]').click();
+ });
+ it('should land on projects list screen', () => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-projects');
+ });
+ });
+ it('should land newly created project on projects list screen', () => {
+ cy.contains('solid-display-value[name="project.name"]', projectName).should("exist");
+ cy.fixture('admin.json').then(admin => {
+ cy.contains('solid-display-value[name="username"]', admin.username).should("exist");
+ });
+ });
+ });
+});
diff --git a/cypress/integration/create-user.spec.js b/cypress/integration/create-user.spec.js
new file mode 100644
index 0000000..8cf9ee9
--- /dev/null
+++ b/cypress/integration/create-user.spec.js
@@ -0,0 +1,54 @@
+///
+/* globals cy, expect */
+
+context('Create User Browser Testing', () => {
+ let firstName = 'First ',
+ lastName = 'Last ',
+ username = 'testuser_creation_',
+ email = '';
+ before(() => {
+ cy.randomNum().then(num => {
+ firstName += num;
+ lastName += num;
+ username += num;
+ email = username + '@testemail.com';
+ });
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('User Creation process', () => {
+ it('should visit the user creation screen', () => {
+ cy.visit('/admin/admin-users/admin-users-create');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-users/admin-users-create');
+ });
+ });
+ it('should enter correct user data', () => {
+ cy.get('#admin-users-create input[name="first_name"]').clear().type(firstName);
+ cy.get('#admin-users-create input[name="first_name"]').should('have.value', firstName);
+ cy.get('#admin-users-create input[name="last_name"]').clear().type(lastName);
+ cy.get('#admin-users-create input[name="last_name"]').should('have.value', lastName);
+ cy.get('#admin-users-create input[name="username"]').clear().type(username);
+ cy.get('#admin-users-create input[name="username"]').should('have.value', username);
+ cy.get('#admin-users-create input[name="email"]').clear().type(email);
+ cy.get('#admin-users-create input[name="email"]').should('have.value', email);
+ });
+ it('should click on create user button', () => {
+ cy.get('#admin-users-create input[type="submit"]').click();
+ });
+ it('should land on users list screen', () => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-users');
+ });
+ });
+ it('should land newly created user on users list screen', () => {
+ cy.contains('solid-display-value[name="name"]', firstName + ' ' + lastName).should("exist");
+ cy.contains('solid-display-value[name="username"]', username).should("exist");
+ });
+ });
+});
diff --git a/cypress/integration/delete-channel.spec.js b/cypress/integration/delete-channel.spec.js
new file mode 100644
index 0000000..ac97861
--- /dev/null
+++ b/cypress/integration/delete-channel.spec.js
@@ -0,0 +1,63 @@
+///
+/* globals cy, expect */
+
+context('Delete Channel Browser Testing', () => {
+ let menuQuery = [
+ 'solid-display.circle-tab',
+ 'solid-display:last-child',
+ 'solid-display[order-by="name"]'
+ ],
+ menuCountQuery = [
+ 'solid-display.circle-tab',
+ 'solid-display',
+ 'solid-display[order-by="name"]'
+ ];
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screend', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Channel Retirement process', () => {
+ let channelsLength;
+ it('should visit the channels list screen', () => {
+ cy.visit('/admin');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin');
+ });
+ });
+ it('should visit the last channel edit screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.visit('/circle/@' + id + '/circle-information');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/circle/@' + id + '/circle-information');
+ });
+ }));
+ });
+ it('should count the number of joined channels', () => {
+ cy.get(menuCountQuery.join(' ')).its('length').then(length => channelsLength = length);
+ });
+ it('should click button to retire the channel', () => {
+ cy.get('#circle-profile solid-delete[data-label="Supprimer le canal"] button').click();
+ });
+ it('should stay on channel edit screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/circle/@' + id + '/circle-information');
+ });
+ }));
+ });
+ it('should check if chennel was retired', () => {
+ cy.get(menuCountQuery.join(' ')).its('length').should(length => {
+ expect(length).to.eq(channelsLength - 1);
+ });
+ });
+ });
+});
diff --git a/cypress/integration/edit-channel.spec.js b/cypress/integration/edit-channel.spec.js
new file mode 100644
index 0000000..b1a8227
--- /dev/null
+++ b/cypress/integration/edit-channel.spec.js
@@ -0,0 +1,65 @@
+///
+/* globals cy, expect */
+
+context('Edit Channel Browser Testing', () => {
+ let channelName = 'Edited Test Channel ',
+ description = 'Edited Test Description ',
+ menuQuery = [
+ 'solid-display.circle-tab',
+ 'solid-display:last-child',
+ 'solid-display[order-by="name"]'
+ ];
+ before(() => {
+ cy.randomNum().then(num => {
+ channelName += num;
+ description += num;
+ });
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Channel Edition process', () => {
+ it('should visit the channel list screen', () => {
+ cy.visit('/admin');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin');
+ });
+ });
+ it('should visit the last channel edit screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.visit('/circle/@' + id + '/circle-information/circle-edit');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/circle/@' + id + '/circle-information/circle-edit');
+ });
+ }));
+ });
+ it('should enter new channel data', () => {
+ cy.get('#circle-edit input[name="name"]').clear().type(channelName);
+ cy.get('#circle-edit input[name="name"]').should('have.value', channelName);
+ cy.get('#circle-edit input[name="description"]').clear().type(description);
+ cy.get('#circle-edit input[name="description"]').should('have.value', description);
+ });
+ it('should click button to save the channel', () => {
+ cy.get('#circle-edit input[value="Enregistrer"]').click();
+ });
+ it('should land on channel information screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/circle/@' + id + '/circle-information');
+ });
+ }));
+ });
+ it('should show edited channel data on channel information screen', () => {
+ cy.contains('solid-display-value[name="name"]', channelName).should("exist");
+ cy.contains('solid-display-value[name="description"]', description).should("exist");
+ });
+ });
+});
diff --git a/cypress/integration/edit-job-offer.spec.js b/cypress/integration/edit-job-offer.spec.js
new file mode 100644
index 0000000..0ce7690
--- /dev/null
+++ b/cypress/integration/edit-job-offer.spec.js
@@ -0,0 +1,66 @@
+///
+/* globals cy, expect */
+
+context('Edit Job Offer Browser Testing', () => {
+ let jobDate = '',
+ jobTitle = 'Edited Test Job Offer ',
+ description = 'Edited Test Description ',
+ menuQuery = [
+ 'solid-display.job-board__list',
+ 'solid-display:last-child'
+ ];
+ before(() => {
+ cy.nextYear(2).then(year => {
+ jobDate = year + '-12-31';
+ });
+ cy.randomNum().then(num => {
+ jobTitle += num;
+ description += num;
+ });
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Job Offer Edition process', () => {
+ it('should visit the job offers list screen', () => {
+ cy.visit('/job-offers');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/job-offers');
+ });
+ });
+ it('should visit the last job offer edit screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.visit('/job-offers/job-offers-edit/@' + id);
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/job-offers/job-offers-edit/@' + id);
+ });
+ }));
+ });
+ it('should enter new job offer data', () => {
+ cy.get('#job-offers-edit input[name="closingDate"]').clear().type(jobDate);
+ cy.get('#job-offers-edit input[name="closingDate"]').should('have.value', jobDate);
+ cy.get('#job-offers-edit input[name="title"]').clear().type(jobTitle);
+ cy.get('#job-offers-edit input[name="title"]').should('have.value', jobTitle);
+ cy.get('#job-offers-edit textarea[name="description"]').clear().type(description);
+ cy.get('#job-offers-edit textarea[name="description"]').should('have.value', description);
+ });
+ it('should click button to save the job offer', () => {
+ cy.get('#job-offers-edit input[type="submit"]').click();
+ });
+ it('should land on job offers list screen', () => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/job-offers');
+ });
+ });
+ it('should show edited job offer data on job offer information screen', () => {
+ cy.contains('solid-display-value[name="title"]', jobTitle).should("exist");
+ cy.contains('solid-display-value[name="description"]', description).should("exist");
+ });
+ });
+});
diff --git a/cypress/integration/edit-project.spec.js b/cypress/integration/edit-project.spec.js
new file mode 100644
index 0000000..f3d7c54
--- /dev/null
+++ b/cypress/integration/edit-project.spec.js
@@ -0,0 +1,69 @@
+///
+/* globals cy, expect */
+
+context('Edit Project Browser Testing', () => {
+ let projectName = 'Edited Test Project ',
+ customerName = 'Edited Test Customer ',
+ description = 'Edited Test Description ',
+ menuQuery = [
+ 'solid-display.project-tab',
+ 'solid-display:last-child',
+ 'solid-display[order-by="customer.name"]'
+ ];
+ before(() => {
+ cy.randomNum().then(num => {
+ projectName += num;
+ customerName += num;
+ description += num;
+ });
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Project Edition process', () => {
+ it('should visit the project list screen', () => {
+ cy.visit('/admin/admin-projects');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-projects');
+ });
+ });
+ it('should visit the last project edit screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.visit('/project/@' + id + '/project-information/project-edit');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/project/@' + id + '/project-information/project-edit');
+ });
+ }));
+ });
+ it('should enter new project data', () => {
+ cy.get('#project-edit input[name="customer.name"]').clear().type(customerName);
+ cy.get('#project-edit input[name="customer.name"]').should('have.value', customerName);
+ cy.get('#project-edit input[name="name"]').clear().type(projectName);
+ cy.get('#project-edit input[name="name"]').should('have.value', projectName);
+ cy.get('#project-edit textarea[name="description"]').clear().type(description);
+ cy.get('#project-edit textarea[name="description"]').should('have.value', description);
+ });
+ it('should click button to save the project', () => {
+ cy.get('#project-edit input[value="Enregistrer"]').click();
+ });
+ it('should land on project information screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/project/@' + id + '/project-information');
+ });
+ }));
+ });
+ it('should show edited project data on project information screen', () => {
+ cy.contains('solid-display-value[name="customer.name"]', customerName).should("exist");
+ cy.contains('solid-display-value[name="name"]', projectName).should("exist");
+ });
+ });
+});
diff --git a/cypress/integration/edit-user.spec.js b/cypress/integration/edit-user.spec.js
new file mode 100644
index 0000000..5bc2923
--- /dev/null
+++ b/cypress/integration/edit-user.spec.js
@@ -0,0 +1,73 @@
+///
+/* globals cy, expect */
+
+context('Edit User Browser Testing', () => {
+ let userFirstName = 'Edited User First Name ',
+ userLastName = 'Edited User Last Name ',
+ jobDescription = 'Edited Job Description ',
+ city = 'Edited City ',
+ phone = '+1234',
+ website = 'https://test.site/';
+ before(() => {
+ cy.randomNum().then(num => {
+ userFirstName += num;
+ userLastName += num;
+ jobDescription += num;
+ city += num;
+ phone += num;
+ website += num;
+ });
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('User Edition process', () => {
+ it('should visit the user edit screen', () => {
+ cy.visit('/profile/solid-profile-edit-profile');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/profile/solid-profile-edit-profile');
+ });
+ });
+ /// Workaround - Routing bug - user won't land on edit profile screen
+ it('should navigate to user edit screen', () => {
+ cy.get('#solid-profile-my-profile solid-link[next="solid-profile-edit-profile"]').click();
+ });
+ /// End workaround
+ it('should enter new user data', () => {
+ cy.get('#solid-profile-edit-profile input[name="first_name"]').clear().type(userFirstName);
+ cy.get('#solid-profile-edit-profile input[name="first_name"]').should('have.value', userFirstName);
+ cy.get('#solid-profile-edit-profile input[name="last_name"]').clear().type(userLastName);
+ cy.get('#solid-profile-edit-profile input[name="last_name"]').should('have.value', userLastName);
+ cy.get('#solid-profile-edit-profile textarea[name="profile.job"]').clear().type(jobDescription);
+ cy.get('#solid-profile-edit-profile textarea[name="profile.job"]').should('have.value', jobDescription);
+ cy.get('#solid-profile-edit-profile input[name="profile.city"]').clear().type(city);
+ cy.get('#solid-profile-edit-profile input[name="profile.city"]').should('have.value', city);
+ cy.get('#solid-profile-edit-profile input[name="profile.phone"]').clear().type(phone);
+ cy.get('#solid-profile-edit-profile input[name="profile.phone"]').should('have.value', phone);
+ cy.get('#solid-profile-edit-profile input[name="profile.website"]').clear().type(website);
+ cy.get('#solid-profile-edit-profile input[name="profile.website"]').should('have.value', website);
+ });
+ it('should click button to save the user', () => {
+ cy.get('#solid-profile-edit-profile input[value="ENREGISTRER"]').click();
+ });
+ it('should land on user information screen', () => {
+ cy.location().should(location => {
+ /// Workaround - Routing bug - route pathname won't be /profile as it should
+ expect(location.pathname).to.eq('/');
+ // expect(location.pathname).to.eq('/profile');
+ /// End workaround
+ });
+ });
+ it('should show edited user data on user information screen', () => {
+ cy.contains('solid-display-value[name="name"]', userFirstName + ' ' + userLastName).should("exist");
+ cy.contains('solid-display-value[name="profile.job"]', jobDescription).should("exist");
+ cy.contains('solid-display-value[name="profile.city"]', city).should("exist");
+ cy.contains('solid-display-tel[name="profile.phone"] a', phone).should("exist");
+ cy.contains('profile-website[name="profile.website"] a', website).should("exist");
+ });
+ });
+});
diff --git a/cypress/integration/leave-channel.spec.js b/cypress/integration/leave-channel.spec.js
new file mode 100644
index 0000000..3b762c3
--- /dev/null
+++ b/cypress/integration/leave-channel.spec.js
@@ -0,0 +1,42 @@
+///
+/* globals cy, expect */
+
+context('Leave Channel Browser Testing', () => {
+ let tableQuery = [
+ 'solid-display.table-body',
+ 'solid-display:last-child',
+ 'hubl-admin-circle-leave-button',
+ 'solid-delete'
+ ],
+ tableListQuery = [
+ 'solid-display[nested-field="circles"]',
+ 'div >',
+ 'solid-display'
+ ];
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screend', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Channel Leaving process', () => {
+ it('should visit the channels list screen', () => {
+ cy.visit('/admin');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin');
+ });
+ });
+ it('should click the last channel leave button', () => {
+ cy.get(tableListQuery.join(' ')).its('length').as('channelsLength');
+ cy.get(tableQuery.join(' ')).click();
+ });
+ it('should check if chennel was left', () => {
+ cy.get(tableListQuery.join(' ')).its('length').should(length => {
+ expect(length).to.eq(this.channelsLength - 1);
+ });
+ });
+ });
+});
diff --git a/cypress/integration/leave-project.spec.js b/cypress/integration/leave-project.spec.js
new file mode 100644
index 0000000..886d3a2
--- /dev/null
+++ b/cypress/integration/leave-project.spec.js
@@ -0,0 +1,42 @@
+///
+/* globals cy, expect */
+
+context('Leave Project Browser Testing', () => {
+ let tableQuery = [
+ 'solid-display.table-body',
+ 'solid-display:last-child',
+ 'hubl-admin-project-leave-button',
+ 'solid-delete'
+ ],
+ tableListQuery = [
+ 'solid-display[nested-field="projects"]',
+ 'div >',
+ 'solid-display'
+ ];
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screend', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Project Leaving process', () => {
+ it('should visit the projects list screen', () => {
+ cy.visit('/admin/admin-projects');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-projects');
+ });
+ });
+ it('should click the last project leave button', () => {
+ cy.get(tableListQuery.join(' ')).its('length').as('projectsLength');
+ cy.get(tableQuery.join(' ')).click();
+ });
+ it('should check if project was left', () => {
+ cy.get(tableListQuery.join(' ')).its('length').should(length => {
+ expect(length).to.eq(this.projectsLength - 1);
+ });
+ });
+ });
+});
diff --git a/cypress/integration/list-job-offers.spec.js b/cypress/integration/list-job-offers.spec.js
new file mode 100644
index 0000000..8def06b
--- /dev/null
+++ b/cypress/integration/list-job-offers.spec.js
@@ -0,0 +1,84 @@
+///
+/* globals cy, expect */
+
+context('List Job Offers Browser Testing', () => {
+ let listQuery = 'solid-display.job-board__list',
+ filtersQuery = [
+ listQuery,
+ 'solid-form',
+ 'input'
+ ],
+ listingCountQuery = [
+ listQuery,
+ 'solid-display'
+ ],
+ firstListingQuery = [
+ listQuery,
+ 'solid-display:first-child',
+ 'solid-display-value'
+ ];
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Job Offer Listing process', () => {
+ let listingTitle,
+ listingDesccription,
+ listingCount;
+ it('should visit the job offers listing screen', () => {
+ cy.visit('/job-offers');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/job-offers');
+ });
+ });
+ it('should get the listing count', () => {
+ cy.get(listingCountQuery.join(' ')).its('length').then(length => listingCount = length);
+ });
+ it('should get the first job offer listing data', () => {
+ cy.get(firstListingQuery.join(' ') + '[name="title"]').invoke('text').then(text => listingTitle = text);
+ cy.get(firstListingQuery.join(' ') + '[name="description"]').invoke('text').then(text => listingDesccription = text);
+ });
+ // TO-DO: Search by title and description
+ /*it('should filter the listing by first name', () => {
+ cy.get(filtersQuery.join(' ') + '[name="title"]').clear().type(listingTitle);
+ cy.get(filtersQuery.join(' ') + '[name="title"]').should('have.value', listingTitle);
+ });
+ it('should get filtered listing count', () => {
+ cy.get(listingCountQuery.join(' ')).its('length').then(length => {
+ expect(length).to.eq(1);
+ });
+ });
+ it('should clear the first name filter', () => {
+ cy.get(filtersQuery.join(' ') + '[name="title"]').clear();
+ cy.get(filtersQuery.join(' ') + '[name="title"]').should('have.value', '');
+ });
+ it('should get previous listing count', () => {
+ cy.get(listingCountQuery.join(' ')).its('length').then(length => {
+ expect(length).to.eq(listingCount);
+ });
+ });
+ it('should filter the listing by first name', () => {
+ cy.get(filtersQuery.join(' ') + '[name="description"]').clear().type(listingDesccription);
+ cy.get(filtersQuery.join(' ') + '[name="description"]').should('have.value', listingDesccription);
+ });
+ it('should get filtered listing count', () => {
+ cy.get(listingCountQuery.join(' ')).its('length').then(length => {
+ expect(length).to.eq(1);
+ });
+ });
+ it('should clear the first name filter', () => {
+ cy.get(filtersQuery.join(' ') + '[name="description"]').clear();
+ cy.get(filtersQuery.join(' ') + '[name="description"]').should('have.value', '');
+ });
+ it('should get previous listing count', () => {
+ cy.get(listingCountQuery.join(' ')).its('length').then(length => {
+ expect(length).to.eq(listingCount);
+ });
+ });*/
+ });
+});
diff --git a/cypress/integration/list-users.spec.js b/cypress/integration/list-users.spec.js
new file mode 100644
index 0000000..ddd848e
--- /dev/null
+++ b/cypress/integration/list-users.spec.js
@@ -0,0 +1,124 @@
+///
+/* globals cy, expect */
+
+context('List Users Browser Testing', () => {
+ let listQuery = 'solid-display#members-list__content',
+ filtersQuery = [
+ listQuery,
+ 'solid-form',
+ 'input'
+ ],
+ listingCountQuery = [
+ listQuery,
+ 'div:first-child',
+ 'span'
+ ],
+ firstListingQuery = [
+ listQuery,
+ 'solid-display:first-child',
+ 'solid-display-value'
+ ];
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screen', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('User Listing process', () => {
+ let listingFirstName,
+ listingLastName,
+ listingJob,
+ listingCity,
+ listingCount;
+ it('should visit the users listing screen', () => {
+ cy.visit('/members');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/members');
+ });
+ });
+ it('should get the listing count', () => {
+ cy.get(listingCountQuery.join(' ')).invoke('text').then(text => listingCount = text);
+ });
+ it('should get the first user listing data', () => {
+ cy.get(firstListingQuery.join(' ') + '[name="first_name"]').invoke('text').then(text => listingFirstName = text);
+ cy.get(firstListingQuery.join(' ') + '[name="last_name"]').invoke('text').then(text => listingLastName = text);
+ cy.get(firstListingQuery.join(' ') + '[name="profile.job"]').invoke('text').then(text => listingJob = text);
+ cy.get(firstListingQuery.join(' ') + '[name="profile.city"]').invoke('text').then(text => listingCity = text);
+ });
+ it('should filter the listing by first name', () => {
+ cy.get(filtersQuery.join(' ') + '[name="name"]').clear().type(listingFirstName);
+ cy.get(filtersQuery.join(' ') + '[name="name"]').should('have.value', listingFirstName);
+ });
+ it('should get filtered listing count', () => {
+ cy.get(listingCountQuery.join(' ')).invoke('text').then(text => {
+ expect(text).to.eq('1 membres');
+ });
+ });
+ it('should clear the first name filter', () => {
+ cy.get(filtersQuery.join(' ') + '[name="name"]').clear();
+ cy.get(filtersQuery.join(' ') + '[name="name"]').should('have.value', '');
+ });
+ it('should get previous listing count', () => {
+ cy.get(listingCountQuery.join(' ')).invoke('text').then(text => {
+ expect(text).to.eq(listingCount);
+ });
+ });
+ it('should filter the listing by last name', () => {
+ cy.get(filtersQuery.join(' ') + '[name="name"]').clear().type(listingLastName);
+ cy.get(filtersQuery.join(' ') + '[name="name"]').should('have.value', listingLastName);
+ });
+ it('should get filtered listing count', () => {
+ cy.get(listingCountQuery.join(' ')).invoke('text').then(text => {
+ expect(text).to.eq('1 membres');
+ });
+ });
+ it('should clear the last name filter', () => {
+ cy.get(filtersQuery.join(' ') + '[name="name"]').clear();
+ cy.get(filtersQuery.join(' ') + '[name="name"]').should('have.value', '');
+ });
+ it('should get previous listing count', () => {
+ cy.get(listingCountQuery.join(' ')).invoke('text').then(text => {
+ expect(text).to.eq(listingCount);
+ });
+ });
+ it('should filter the listing by job description', () => {
+ cy.get(filtersQuery.join(' ') + '[name="member-job"]').clear().type(listingJob);
+ cy.get(filtersQuery.join(' ') + '[name="member-job"]').should('have.value', listingJob);
+ });
+ it('should get filtered listing count', () => {
+ cy.get(listingCountQuery.join(' ')).invoke('text').then(text => {
+ expect(text).to.eq('1 membres');
+ });
+ });
+ it('should clear the job description filter', () => {
+ cy.get(filtersQuery.join(' ') + '[name="member-job"]').clear();
+ cy.get(filtersQuery.join(' ') + '[name="member-job"]').should('have.value', '');
+ });
+ it('should get previous listing count', () => {
+ cy.get(listingCountQuery.join(' ')).invoke('text').then(text => {
+ expect(text).to.eq(listingCount);
+ });
+ });
+ it('should filter the listing by city', () => {
+ cy.get(filtersQuery.join(' ') + '[name="member-city"]').clear().type(listingCity);
+ cy.get(filtersQuery.join(' ') + '[name="member-city"]').should('have.value', listingCity);
+ });
+ it('should get filtered listing count', () => {
+ cy.get(listingCountQuery.join(' ')).invoke('text').then(text => {
+ expect(text).to.eq('1 membres');
+ });
+ });
+ it('should clear the city filter', () => {
+ cy.get(filtersQuery.join(' ') + '[name="member-city"]').clear();
+ cy.get(filtersQuery.join(' ') + '[name="member-city"]').should('have.value', '');
+ });
+ it('should get previous listing count', () => {
+ cy.get(listingCountQuery.join(' ')).invoke('text').then(text => {
+ expect(text).to.eq(listingCount);
+ });
+ });
+ });
+});
diff --git a/cypress/integration/retire-channel.spec.js b/cypress/integration/retire-channel.spec.js
new file mode 100644
index 0000000..6ae42d2
--- /dev/null
+++ b/cypress/integration/retire-channel.spec.js
@@ -0,0 +1,63 @@
+///
+/* globals cy, expect */
+
+context('Retire Channel Browser Testing', () => {
+ let menuQuery = [
+ 'solid-display.circle-tab',
+ 'solid-display:last-child',
+ 'solid-display[order-by="name"]'
+ ],
+ menuCountQuery = [
+ 'solid-display.circle-tab',
+ 'solid-display',
+ 'solid-display[order-by="name"]'
+ ];
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screend', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Channel Retirement process', () => {
+ let channelsLength;
+ it('should visit the channels list screen', () => {
+ cy.visit('/admin');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin');
+ });
+ });
+ it('should visit the last channel edit screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.visit('/circle/@' + id + '/circle-information/circle-edit');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/circle/@' + id + '/circle-information/circle-edit');
+ });
+ }));
+ });
+ it('should count the number of joined channels', () => {
+ cy.get(menuCountQuery.join(' ')).its('length').then(length => channelsLength = length);
+ });
+ it('should click button to retire the channel', () => {
+ cy.get('solid-multiple[name="members"] solid-delete[data-label="Retirer"] button').click();
+ });
+ it('should stay on channel edit screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/circle/@' + id + '/circle-information/circle-edit');
+ });
+ }));
+ });
+ it('should check if chennel was retired', () => {
+ cy.get(menuCountQuery.join(' ')).its('length').should(length => {
+ expect(length).to.eq(channelsLength - 1);
+ });
+ });
+ });
+});
diff --git a/cypress/integration/retire-project.spec.js b/cypress/integration/retire-project.spec.js
new file mode 100644
index 0000000..b54b90d
--- /dev/null
+++ b/cypress/integration/retire-project.spec.js
@@ -0,0 +1,63 @@
+///
+/* globals cy, expect */
+
+context('Retire Project Browser Testing', () => {
+ let menuQuery = [
+ 'solid-display.project-tab',
+ 'solid-display:last-child',
+ 'solid-display[order-by="customer.name"]'
+ ],
+ menuCountQuery = [
+ 'solid-display.project-tab',
+ 'solid-display',
+ 'solid-display[order-by="customer.name"]'
+ ];
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ beforeEach(() => cy.restoreLocalStorage());
+ afterEach(() => cy.saveLocalStorage());
+ it('should visit user login screend', () => cy.userLogin());
+ it('should login', () => cy.login());
+ describe('Project Retirement process', () => {
+ let projectsLength;
+ it('should visit the projects list screen', () => {
+ cy.visit('/admin/admin-projects');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/admin/admin-projects');
+ });
+ });
+ it('should visit the last project edit screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.visit('/project/@' + id + '/project-information/project-edit');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/project/@' + id + '/project-information/project-edit');
+ });
+ }));
+ });
+ it('should count the number of joined projects', () => {
+ cy.get(menuCountQuery.join(' ')).its('length').then(length => projectsLength = length);
+ });
+ it('should click button to retire the project', () => {
+ cy.get('solid-multiple[name="members"] solid-delete[data-label="Retirer"] button').click();
+ });
+ it('should stay on project edit screen', () => {
+ cy.get(menuQuery.join(' '))
+ .invoke('attr', 'data-src')
+ .then(url => cy.encodeUrl(url).then(id => {
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/project/@' + id + '/project-information/project-edit');
+ });
+ }));
+ });
+ it('should check if project was retired', () => {
+ cy.get(menuCountQuery.join(' ')).its('length').should(length => {
+ expect(length).to.eq(projectsLength - 1);
+ });
+ });
+ });
+});
diff --git a/cypress/integration/tests.spec.js b/cypress/integration/signin.spec.js
similarity index 70%
rename from cypress/integration/tests.spec.js
rename to cypress/integration/signin.spec.js
index ba53571..53457ed 100644
--- a/cypress/integration/tests.spec.js
+++ b/cypress/integration/signin.spec.js
@@ -1,43 +1,37 @@
///
-
+/* globals cy, expect */
context('Browser testing', () => {
- before(() => {
- cy.clearLocalStorage({ domain: null});
- cy.clearCookies({ domain: null });
+ before(() => {
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null});
+ cy.clearCookies({ domain: null });
+ });
+ it('should visit user login screen', () => cy.userLogin());
+ describe('Login process', () => {
+ it('should write "admin" on username field and "password" on password field', () => {
+ cy.get('#id_username').type('admin');
+ cy.get('#id_username').should('have.value', 'admin');
+ cy.get('#id_password').type('password');
+ cy.get('#id_password').should('have.value', 'password');
});
- it('visit the homepage', () => {
- cy.visit('/');
+ it('should click on login button', () => {
+ cy.get(':nth-child(1) > .flex-column > [type="submit"]').click();
});
- it('should await for an user login', () => {
+ it('should provide an error, username and password mismatch.', () => {
+ cy.get('.error').should('contain.text', 'Ton nom d\'utilisateur et ton mot de passe ne correspondent pas. Réessaye.');
+ });
+ it('should write "admin" on password field then press the login button', () => {
+ cy.get('#id_password').type('admin');
+ cy.get('#id_password').should('have.value', 'admin');
+ cy.get(':nth-child(1) > .flex-column > [type="submit"]').click();
+ });
+ it('should ask for user permission to access their datas.', () => {
cy.location().should((loc) => {
- expect(loc.pathname).to.eq('/auth/login/');
+ expect(loc.pathname).to.eq('/authorize');
});
+ cy.get('.accept-button').click();
});
- describe('Login process', () => {
- it('should write "admin" on username field and "password" on password field', () => {
- cy.get('#id_username').type('admin');
- cy.get('#id_username').should('have.value', 'admin');
- cy.get('#id_password').type('password');
- cy.get('#id_password').should('have.value', 'password');
- });
- it('should click on login button', () => {
- cy.get(':nth-child(1) > .flex-column > [type="submit"]').click();
- });
- it('should provide an error, username and password mismatch.', () => {
- cy.get('.error').should('contain.text', 'Ton nom d\'utilisateur et ton mot de passe ne correspondent pas. Réessaye.')
- });
- it('should write "admin" on password field then press the login button', () => {
- cy.get('#id_password').type('admin');
- cy.get('#id_password').should('have.value', 'admin');
- cy.get(':nth-child(1) > .flex-column > [type="submit"]').click();
- });
- it('should ask for user permission to access their datas.', () => {
- cy.location().should((loc) => {
- expect(loc.pathname).to.eq('/authorize')
- });
- cy.get('.accept-button').click();
- });
// it('should redirect the user to the app.', () => {
// cy.get('.accept-button').click();
// cy.location().should((loc) => {
@@ -103,6 +97,5 @@ context('Browser testing', () => {
// expect(loc.pathname).to.eq('/auth/login/');
// });
// });
- });
});
-
+});
diff --git a/cypress/integration/signup.spec.js b/cypress/integration/signup.spec.js
new file mode 100644
index 0000000..05ee1b8
--- /dev/null
+++ b/cypress/integration/signup.spec.js
@@ -0,0 +1,61 @@
+///
+/* globals cy */
+
+context('Signup Browser Testing', () => {
+ let username = 'testuser_creation_',
+ email = '',
+ password = 'testpwd';
+ before(() => {
+ cy.randomNum().then(num => {
+ username += num;
+ email = username + '@testemail.com';
+ });
+ cy.clearLocalStorageSnapshot();
+ cy.clearLocalStorage({ domain: null });
+ cy.clearCookies({ domain: null });
+ });
+ it('should visit user login screen', () => cy.userLogin());
+ describe('Signup process', () => {
+ it('should click on signup page link', () => {
+ cy.get('.sib-link.sib-register-link').click();
+ });
+ it('should write incorrect user data', () => {
+ cy.get('#id_username').type('!"#$%&');
+ cy.get('#id_username').should('have.value', '!"#$%&');
+ cy.get('#id_email').type(email.split('.')[0]);
+ cy.get('#id_email').should('have.value', email.split('.')[0]);
+ cy.get('#id_password1').type(password + 'wrong1');
+ cy.get('#id_password1').should('have.value', password + 'wrong1');
+ cy.get('#id_password2').type(password + 'wrong2');
+ cy.get('#id_password2').should('have.value', password + 'wrong2');
+ });
+ it('should click on signup button', () => {
+ cy.get('.sib-registration-btn').click();
+ });
+ it('should provide errors about incorrect user data', () => {
+ cy.get('tbody tr:nth-child(1) ul.errorlist li')
+ .should('contain.text', 'Enter a valid username. This value may contain only letters, numbers, and ./+/-/_ characters.');
+ cy.get('tbody tr:nth-child(2) ul.errorlist li')
+ .should('contain.text', 'Enter a valid email address.');
+ cy.get('tbody tr:nth-child(4) ul.errorlist li')
+ .should('contain.text', 'The two password fields didn\'t match.');
+ });
+ it('should write correct user data', () => {
+ cy.get('#id_username').clear().type(username);
+ cy.get('#id_username').should('have.value', username);
+ cy.get('#id_email').clear().type(email);
+ cy.get('#id_email').should('have.value', email);
+ cy.get('#id_password1').clear().type(password);
+ cy.get('#id_password1').should('have.value', password);
+ cy.get('#id_password2').clear().type(password);
+ cy.get('#id_password2').should('have.value', password);
+ });
+ it('should click on signup button', () => {
+ cy.get('.sib-registration-btn').click();
+ });
+ it('should show email confirmation dialog', () => {
+ cy.contains('h1.text-center', 'Un e-mail d\'activation a été envoyé.').should("exist");
+ cy.contains('p.text-center', 'Vérifie ta boite mail et clique sur le lien pour activer ton compte.').should("exist");
+ });
+ });
+});
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index ca4d256..cff3858 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -23,3 +23,50 @@
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
+
+/* globals Cypress, cy, expect */
+
+import 'cypress-localstorage-commands';
+
+Cypress.Commands.add('login', () => {
+ cy.fixture('admin.json').then(admin => {
+ cy.get('#id_username').type(admin.username);
+ cy.get('#id_username').should('have.value', admin.username);
+ cy.get('#id_password').type(admin.password);
+ cy.get('#id_password').should('have.value', admin.password);
+ cy.get('.connection-btn').click();
+ cy.location('pathname').should('include', '/authorize');
+ cy.get('.accept-button').click();
+ cy.location().should(location => {
+ expect(location.pathname).to.eq('/');
+ });
+ });
+});
+
+Cypress.Commands.add('userLogin', () => {
+ cy.visit('/');
+ cy.location().should((loc) => {
+ expect(loc.pathname).to.eq('/auth/login/');
+ });
+});
+
+Cypress.Commands.add('encodeUrl', url => {
+ const encodeIdReplacement = [
+ ['~', '~~'],
+ ['.', '~!'],
+ [':', '~@'],
+ ['/', '~_'],
+ ];
+ encodeIdReplacement.forEach(([char, repl]) => {
+ url = url.split(char).join(repl);
+ });
+ return url;
+});
+
+Cypress.Commands.add('randomNum', () => {
+ return Math.floor(1000 + Math.random() * 9000);
+});
+
+Cypress.Commands.add('nextYear', increment => {
+ return new Date().getFullYear() + ( increment || 1 );
+});
diff --git a/cypress/support/index.js b/cypress/support/index.js
index 92fa6f5..c1a0001 100644
--- a/cypress/support/index.js
+++ b/cypress/support/index.js
@@ -13,8 +13,10 @@
// https://on.cypress.io/configuration
// ***********************************************************
+/* globals Cypress */
+
// Import commands.js using ES2015 syntax:
-import './commands'
+import './commands';
//require('cypress-terminal-report').installSupport();
@@ -27,4 +29,9 @@ Cypress.on('uncaught:exception', (err, runnable) => {
return false;
});
-Cypress.on('fail', () => Cypress.runner.abort())
+Cypress.on('fail', (error) => {
+ console.log(error);
+ if ( typeof Cypress.runner.abort == 'function' ) {
+ Cypress.runner.abort();
+ }
+});
diff --git a/package-lock.json b/package-lock.json
index 231201a..5ae0403 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1449,6 +1449,12 @@
}
}
},
+ "cypress-localstorage-commands": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/cypress-localstorage-commands/-/cypress-localstorage-commands-1.2.1.tgz",
+ "integrity": "sha512-wWGElZS5fHAQDonZM8xtOA1tM+bTBUdwEMm6XrshLMKjq8Nxw4+Ysbl9/Yc+gZyv66EQe4hPNDLWANnp/zPkcA==",
+ "dev": true
+ },
"cypress-terminal-report": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/cypress-terminal-report/-/cypress-terminal-report-1.2.1.tgz",
diff --git a/package.json b/package.json
index 3792914..5de4183 100644
--- a/package.json
+++ b/package.json
@@ -9,8 +9,8 @@
"scripts": {
"build": "run-p copy:* build:*",
"build:css": "node-sass src/styles/index.scss -o dist/styles/",
- "build:js": "babel 'src/scripts/*.js' -o dist/scripts/index.js",
- "build:jscomponents": "babel 'src/components/*.js' --out-dir dist/components/",
+ "build:js": "babel \"src/scripts/*.js\" -o dist/scripts/index.js",
+ "build:jscomponents": "babel \"src/components/*.js\" --out-dir dist/components/",
"build:html": "pug src/index.pug -o dist/ --obj config.json",
"copy:font": "copyfiles -f src/fonts/* dist/fonts",
"copy:image": "copyfiles -f src/images/* dist/images",
@@ -68,6 +68,7 @@
},
"devDependencies": {
"cypress": "^4.5.0",
+ "cypress-localstorage-commands": "^1.2.1",
"cypress-terminal-report": "^1.2.1"
}
}
diff --git a/src/components/hubl-reactivity.js b/src/components/hubl-reactivity.js
index dce2a6c..443a517 100644
--- a/src/components/hubl-reactivity.js
+++ b/src/components/hubl-reactivity.js
@@ -1,6 +1,6 @@
-import { store } from 'https://unpkg.com/@startinblox/core@0.10';
-import { Sib } from "https://unpkg.com/@startinblox/core@0.10/dist/libs/Sib.js";
-import { StoreMixin } from "https://unpkg.com/@startinblox/core@0.10/dist/mixins/storeMixin.js";
+import { store } from 'https://unpkg.com/@startinblox/core@0.12';
+import { Sib } from "https://unpkg.com/@startinblox/core@0.12/dist/libs/Sib.js";
+import { StoreMixin } from "https://unpkg.com/@startinblox/core@0.12/dist/mixins/storeMixin.js";
export const HublReactivity = {
name: 'hubl-reactivity',
diff --git a/src/components/hubl-search-users.js b/src/components/hubl-search-users.js
index c65e58e..b640f3b 100644
--- a/src/components/hubl-search-users.js
+++ b/src/components/hubl-search-users.js
@@ -1,4 +1,4 @@
-import { widgetFactory } from 'https://unpkg.com/@startinblox/core@0.10/dist/widgets/widget-factory.js';
+import { widgetFactory } from 'https://unpkg.com/@startinblox/core@0.12/dist/widgets/widget-factory.js';
const HublSearchUsers = widgetFactory(
'hubl-search-users',
diff --git a/src/components/hubl-status.js b/src/components/hubl-status.js
index 7a94718..15b4b1f 100644
--- a/src/components/hubl-status.js
+++ b/src/components/hubl-status.js
@@ -1,5 +1,5 @@
-import { widgetFactory } from 'https://unpkg.com/@startinblox/core@0.10/dist/widgets/widget-factory.js';
-import { importCSS } from 'https://unpkg.com/@startinblox/core@0.10/dist/libs/helpers.js';
+import { widgetFactory } from 'https://unpkg.com/@startinblox/core@0.12/dist/widgets/widget-factory.js';
+import { importCSS } from 'https://unpkg.com/@startinblox/core@0.12/dist/libs/helpers.js';
import SlimSelect from 'https://dev.jspm.io/slim-select@1.23';
const HublStatus = widgetFactory(
diff --git a/src/dependencies.pug b/src/dependencies.pug
index 515b158..c0ed340 100644
--- a/src/dependencies.pug
+++ b/src/dependencies.pug
@@ -2,17 +2,17 @@ script(type="module" src="/components/hubl-search-users.js" defer)
script(type="module" src="/components/hubl-status.js" defer)
script(type="module" src="/components/hubl-reactivity.js" defer)
-script(type="module" src="https://unpkg.com/@startinblox/core@0.10" defer)
+script(type="module" src="https://unpkg.com/@startinblox/core@0.12" defer)
//- script(type="module" src="/lib/sib-core/dist/index.js" defer)
-script(type="module" src="https://unpkg.com/@startinblox/oidc@0.9" defer)
-//- script(type="module" src="/lib/sib-oidc/index.js" defer)
+script(type="module" src="https://unpkg.com/@startinblox/oidc@0.10" defer)
+//- script(type="module" src="/lib/sib-auth/index.js" defer)
-script(type="module" src="https://unpkg.com/@startinblox/router@0.8" defer)
- //- script(type="module" src="/lib/solid-router/src/index.js" defer)
+script(type="module" src="https://unpkg.com/@startinblox/router@0.9" defer)
+//- script(type="module" src="/lib/sib-router/src/index.js" defer)
-script(type="module" src="https://unpkg.com/@startinblox/component-notifications@0.6.2" defer)
- //- script(type="module" src="/lib/sib-notifications/index.js" defer)
+script(type="module" src="https://unpkg.com/@startinblox/component-notifications@0.7" defer)
+//- script(type="module" src="/lib/sib-notifications/index.js" defer)
if (endpoints.events || (endpoints.get && endpoints.get.events)) && (endpoints.typeevents || (endpoints.get && endpoints.get.typeevents))
script(type="module" src="https://unpkg.com/@startinblox/component-event@1.1" defer)
@@ -23,19 +23,19 @@ if (endpoints.resources || (endpoints.get && endpoints.get.resources)) && (endpo
//- script(type="module" src="/lib/sib-resource/sib-resource.js" defer)
if endpoints.joboffers || (endpoints.get && endpoints.get.joboffers)
- script(type="module" src="https://unpkg.com/@startinblox/component-job-board@0.6" defer)
+ script(type="module" src="https://unpkg.com/@startinblox/component-job-board@0.8" defer)
//- script(type="module" src="/lib/solid-job-board/dist/index.js" defer)
if (endpoints.uploads || (endpoints.get && endpoints.get.uploads)) && (endpoints.skills || (endpoints.get && endpoints.get.skills)) && (endpoints.users || (endpoints.get && endpoints.get.users))
- script(type="module" src="https://unpkg.com/@startinblox/component-directory@0.7" defer)
+ script(type="module" src="https://unpkg.com/@startinblox/component-directory@0.8" defer)
//- script(type="module" src="/lib/solid-directory/dist/index.js" defer)
if endpoints.dashboards || (endpoints.get && endpoints.get.dashboards)
- script(type="module" src="https://unpkg.com/@startinblox/component-dashboard@0.3" defer)
+ script(type="module" src="https://unpkg.com/@startinblox/component-dashboard@0.5" defer)
//- script(type="module" src="/lib/solid-dashboard/dist/index.js" defer)
if endpoints.users || (endpoints.get && endpoints.get.users)
- script(type="module" src="https://unpkg.com/@startinblox/component-chat@0.8" defer)
+ script(type="module" src="https://unpkg.com/@startinblox/component-chat@1.1" defer)
//- script(type="module" src="/lib/solid-xmpp-chat/dist/index.js" defer)
if endpoints.polls || (endpoints.get && endpoints.get.polls)
diff --git a/src/header.pug b/src/header.pug
index 1320e54..3de936b 100644
--- a/src/header.pug
+++ b/src/header.pug
@@ -8,8 +8,8 @@ solid-notifications.notLoggedIn(
)
//- Templates for notifications from circles and from other users
-include views/circle/page-circle-notifications.pug
-include views/user/page-user-notifications.pug
+include views/notifications/message-circle.pug
+include views/notifications/message-private.pug
include templates/hubl-user-avatar.pug
diff --git a/src/menu-left.pug b/src/menu-left.pug
index e8a3b28..3ac9e55 100644
--- a/src/menu-left.pug
+++ b/src/menu-left.pug
@@ -81,10 +81,12 @@ solid-router#navbar-router(default-route='dashboard')
div.divider
if endpoints.projects || (endpoints.get && endpoints.get.projects)
div
- solid-link(next='admin-project-list')
+ solid-link
+ //- (next='admin-project-list')
div.menu
div.menu-chevron
- div.menu-icon.icon-arrow-right-circle
+ div.menu-icon
+ //- div.menu-icon.icon-arrow-right-circle
div.menu-label Projets
div.menu-icon.icon-folder-alt
solid-route(name='project', rdf-type='hd:project', use-id='', hidden)
@@ -108,10 +110,12 @@ solid-router#navbar-router(default-route='dashboard')
div.divider
if endpoints.circles || (endpoints.get && endpoints.get.circles)
div
- solid-link(next='admin-circle-list')
+ solid-link
+ //- (next='admin-circle-list')
div.menu
div.menu-chevron
- div.menu-icon.icon-arrow-right-circle
+ div.menu-icon
+ //- div.menu-icon.icon-arrow-right-circle
div.menu-label Cercles
div.menu-icon.icon-folder-alt
solid-route(name='circle', rdf-type='hd:circle', use-id='', hidden)
diff --git a/src/page-messages.pug b/src/page-messages.pug
index 21f7c6d..7487d67 100644
--- a/src/page-messages.pug
+++ b/src/page-messages.pug
@@ -17,7 +17,7 @@
solid-xmpp-chat(
data-authentication='login',
data-auto-login='true',
- data-bosh-service-url=`${xmpp}`,
+ data-websocket-url=`${xmppWebsocket || 'wss://jabber.happy-dev.fr/xmpp-websocket'}`,
data-i18n='en',
bind-resources
)
diff --git a/src/page-user-profile.pug b/src/page-user-profile.pug
deleted file mode 100644
index aee271e..0000000
--- a/src/page-user-profile.pug
+++ /dev/null
@@ -1,71 +0,0 @@
-include templates/hubl-groups.pug
-
-.content-box.with-form.user-profile__container
-
- .section.user-bio
-
- solid-display.avatar-display(
- bind-user=''
- fields='account.picture'
- label-account.picture=''
- widget-account.picture='solid-display-img'
- )
-
- solid-display.name-diplay(
- bind-user=''
- fields='user-name-groups(name, groups), username'
-
- class-name='name'
-
- label-groups=''
- multiple-groups=''
- widget-groups='hubl-groups-name'
-
- class-username='username'
- )
-
- solid-form.info-form(
- bind-user=''
- fields='profile.bio, inline-1(profile.city, email), inline-2(profile.phone, profile.website), inline-3(profile.available), account.picture, instruction'
-
- class-profile.bio='form-label is-light'
- label-profile.bio='short description'
-
- class-profile.city='form-label is-light'
- label-profile.city='your cell'
-
- class-email='form-label is-light'
-
- class-profile.phone='form-label is-light'
- label-profile.phone='phone'
-
- class-profile.website='form-label is-light'
- label-profile.website='your website'
-
- class-profile.available='form-label is-light'
- label-profile.available='your availability'
-
- class-account.picture='form-label is-light'
- label-account.picture='your picture'
-
- widget-instruction='hubl-instruction'
- )
-
- .section.user-skills
-
- solid-form(
- bind-user=''
- range-skills=`${endpoints.skills || endpoints.get.skills}`
- fields='skills'
-
- class-skills='form-label is-dark'
- label-skills='Your main skills (4 max.):'
- multiple-skills='solid-multiple-select'
- widget-skills='solid-form-auto-completion'
- )
-
-
- solid-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/menu-toggle.js b/src/scripts/menu-toggle.js
new file mode 100644
index 0000000..8f96670
--- /dev/null
+++ b/src/scripts/menu-toggle.js
@@ -0,0 +1,11 @@
+document.addEventListener("DOMContentLoaded", () => {
+ 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");
+ });
+ });
+});
\ No newline at end of file
diff --git a/src/scripts/unreads-menu.js b/src/scripts/unreads-menu.js
index bd6abc7..ae5dc2c 100644
--- a/src/scripts/unreads-menu.js
+++ b/src/scripts/unreads-menu.js
@@ -1,7 +1,7 @@
document.addEventListener("DOMContentLoaded", function (event) {
window.addEventListener('newMessage', event => {
let jid = event.detail.jid;
- Array.from(document.querySelectorAll('[data-jabberID="'+jid+'"]')).forEach(el => {
+ Array.from(document.querySelectorAll('[data-jabberID="' + jid + '"]')).forEach(el => {
el.parentElement.parentElement.classList.add('unread');
});
});
@@ -9,7 +9,12 @@ document.addEventListener("DOMContentLoaded", function (event) {
window.addEventListener('read', (event) => {
if (event.detail && event.detail.resource && event.detail.resource['@id']) {
const badge = document.querySelector(`solid-badge[data-src="${event.detail.resource['@id']}"]`);
- if (badge) badge.parentElement.parentElement.classList.remove('unread');
+ if (badge) {
+ badge.parentElement.parentElement.classList.remove('unread');
+ const project = badge.parentElement.parentElement.querySelector('.unread');
+ if (project) project.classList.remove('unread');
+ }
+
}
});
});
\ No newline at end of file
diff --git a/src/styles/base/form.scss b/src/styles/base/form.scss
index 9234516..e5f0f12 100644
--- a/src/styles/base/form.scss
+++ b/src/styles/base/form.scss
@@ -1,3 +1,9 @@
+solid-form {
+ [data-id="error"] {
+ display: none !important; // Hide the default core message, english only with a weird message
+ }
+}
+
.form form {
display: block;
height: fit-content;
@@ -41,16 +47,14 @@
.form-label {
/*flex: 1 1 auto;*/
- label {
- display: flex;
- flex-direction: column; /* To align label and input vertically */
- font-weight: 600;
- margin-bottom: 0.8rem;
- margin-top: 1.8rem;
- text-transform: uppercase;
- }
+ display: flex;
+ flex-direction: column; /* To align label and input vertically */
+ font-weight: 600;
+ margin-bottom: 0.8rem;
+ margin-top: 1.8rem;
+ text-transform: uppercase;
- &.is-light label {
+ &.is-light {
color: var(--color-label-light);
}
}
@@ -130,11 +134,14 @@ textarea {
/* WIDGETS SIB (let in .content-box to override default styles) */
-solid-form-auto-completion,
+solid-form-dropdown-autocompletion,
+solid-form-dropdown-autocompletion-label,
+solid-form-multipleselect-autocompletion-label,
hubl-status {
.ss-main {
font-weight: normal;
+ margin-top: 0.8rem;
text-transform: none;
@@ -144,7 +151,6 @@ hubl-status {
border-radius: 0px;
color: var(--color-input-text);
font-weight: normal;
- margin-top: 0.8rem;
min-height: 4.6rem;
padding-left: 1.2rem;
@@ -179,6 +185,7 @@ hubl-status {
display: flex;
flex-direction: row;
margin-bottom: 2.6rem;
+ margin-top: 1.8rem;
}
label {
@@ -199,6 +206,7 @@ hubl-status {
width: 100%;
@include breakpoint(lg) {
+ height: 32px;
margin: auto 0 auto 2.2rem;
width: auto;
}
@@ -288,13 +296,13 @@ solid-form-file {
}
}
-/*solid-multiple-select {
+/*solid-form-multipleselect {
&.select-skills .ss-values .ss-disabled::before {
content: "Select skills";
}
- solid-form-auto-completion > label {
+ solid-form-dropdown-autocompletion-label > label {
display: flex;
flex-direction: column;
@@ -378,7 +386,8 @@ hubl-member-form {
margin-bottom: 1rem;
}
- solid-form-auto-completion {
+ solid-form-dropdown-autocompletion-label,
+ solid-form-multipleselect-autocompletion-label {
float: left;
}
diff --git a/src/styles/base/main.scss b/src/styles/base/main.scss
index ea47ba9..c2e7b3e 100644
--- a/src/styles/base/main.scss
+++ b/src/styles/base/main.scss
@@ -537,6 +537,10 @@ h5 {
text-align: center;
}
+.block {
+ display: block;
+}
+
.flex {
display: flex;
}
@@ -592,14 +596,14 @@ button,
input[type='submit'],
a,
.button {
- background: none;
- border: none;
- cursor: pointer;
- display: inline-block;
- padding: 0;
- &.button {
- padding: 0.55rem 2.5rem;
- border-radius: 100em;
+ background: none;
+ border: none;
+ cursor: pointer;
+ display: inline-block;
+ padding: 0;
+ &.button {
+ padding: 0.55rem 2.5rem;
+ border-radius: 100em;
*,
& {
font-size: 1.4rem;
diff --git a/src/styles/base/menu-left.scss b/src/styles/base/menu-left.scss
index acfdba4..274b647 100644
--- a/src/styles/base/menu-left.scss
+++ b/src/styles/base/menu-left.scss
@@ -1,13 +1,16 @@
#main__menu {
- background-color: var(--color-menu-background);
- color: var(--color-menu-text);
- /*transition: flex-basis 0.5s ease-in-out;*/
- &.open {
- transform: translateX(0);
- }
- .unread {
- font-weight: bolder;
- }
+ background-color: var(--color-menu-background);
+ color: var(--color-menu-text);
+ /*transition: flex-basis 0.5s ease-in-out;*/
+
+ &.open {
+ transform: translateX(0);
+ }
+
+ .unread {
+ font-weight: bolder;
+ }
+
solid-router {
.menu-wrapper {
&.is-closed {
@@ -22,6 +25,28 @@
solid-link {
width: 100%;
}
+ .menu-wrapper {
+ .menu-icon.icon-arrow-up {
+ visibility: hidden;
+ }
+ @include breakpoint(lg) {
+ .menu-icon.icon-arrow-up {
+ visibility: visible;
+ }
+ &.is-closed {
+ .sub-menu {
+ display: none;
+ }
+
+ .menu-chevron {
+ transform: rotate(180deg);
+ }
+ }
+ }
+ }
+ .unread {
+ font-weight: bolder;
+ }
.menu {
cursor: pointer;
display: flex;
diff --git a/src/styles/base/table.scss b/src/styles/base/table.scss
index 6ecc645..c82e4c5 100644
--- a/src/styles/base/table.scss
+++ b/src/styles/base/table.scss
@@ -46,13 +46,14 @@
&>* {
border-bottom: 1px solid var(--color-table-border);
display: table-cell;
+ text-align: center;
vertical-align: middle;
}
}
}
- &>solid-multiple {
- display: contents;
+ /*&>solid-multiple {
+ display: contents;*/
&>div {
display: contents;
@@ -68,7 +69,7 @@
}
}
}
- }
+ /*}*/
}
}
}
@@ -152,6 +153,10 @@
.desktop-btn-margin__left;
}
}
+
+ &.is-spaced {
+ padding: 0.8rem 2.2rem;
+ }
}
.cell-with-name {
@@ -163,23 +168,11 @@
/* Styles of elements inside cells */
-.user-thumb>div,
-[name='user-thumb'] {
- vertical-align: middle;
- text-align: left;
- @extend %user-thumb__grid;
- padding: 0 2.2rem;
-
- >.user-thumb__picture {
- @extend .user-thumb__picture;
- }
-
- >[name='sup'] {
- @extend %user-thumb__grid-sup;
- }
-
- >[name='sub'] {
- @extend %user-thumb__grid-inf;
+.table {
+
+ .user-thumb.is-spaced,
+ [name='user-thumb'] {
+ padding: 0.8rem 2.2rem;
}
}
diff --git a/src/styles/base/user-thumb.scss b/src/styles/base/user-thumb.scss
index 8814efb..4b6f874 100644
--- a/src/styles/base/user-thumb.scss
+++ b/src/styles/base/user-thumb.scss
@@ -35,6 +35,22 @@
color: var(--color-user-thumb-name);
font-weight: 600;
margin-right: 1rem;
+ text-align: left;
+}
+
+.user-thumb__send {
+ position: relative;
+ bottom: 7px;
+ left: -5px;
+
+ solid-link {
+ @include icon('speech');
+
+ &::before {
+ display: inline-block;
+ color: #FF6765;
+ }
+ }
}
.user-thumb__admin:not(:empty) {
@@ -76,10 +92,16 @@
margin-right: 0.50rem;
}
}
+.user-thumb[name="classGroup"] {
+ display: block;
+ margin-top: 15px;
+}
/* Apply the grids to all user-thumbs */
.user-thumb>div,
+.user-thumb>[name='classGrid'],
[name='user-thumb'] {
+
@extend %user-thumb__grid;
>[name='sup'] {
@@ -90,9 +112,3 @@
@extend %user-thumb__grid-inf;
}
}
-
-/* Add extra spaces to user-thumbs that are inside a table */
-.user-thumb.is-spaced>div,
-[name='user-thumb'] {
- padding: 0.8rem 2.2rem;
-}
diff --git a/src/styles/components/comment.scss b/src/styles/components/comment.scss
index 0a4dc94..8efbc01 100644
--- a/src/styles/components/comment.scss
+++ b/src/styles/components/comment.scss
@@ -74,7 +74,7 @@
solid-ac-checker {
border-top: 1px solid $color-210-17-91;
- solid-form-textarea {
+ solid-form-textarea-label {
>label div {
color: $color-210-5-56;
diff --git a/src/templates/hubl-circle-team.pug b/src/templates/hubl-circle-team.pug
deleted file mode 100644
index 2aff831..0000000
--- a/src/templates/hubl-circle-team.pug
+++ /dev/null
@@ -1,20 +0,0 @@
-include hubl-user-avatar.pug
-
-solid-widget(name='hubl-circle-team-template')
- template
- solid-display.user-thumb.is-spaced(
- data-src='${await value.user}'
- fields='account.picture, sup(name, isadmin), sub(profile.city)'
- value-isadmin='${await value.is_admin}'
-
- class-account.picture='avatar user-thumb__picture'
- class-name='user-thumb__name'
- class-isadmin='user-thumb__admin'
- class-profile.city='user-thumb__city'
-
- widget-account.picture='hubl-user-avatar'
- widget-isadmin='hubl-circle-user-admin'
- )
-
-solid-widget(name='hubl-circle-user-admin')
- template ${(await value) != "false" ? "Administrateur" : ""}
diff --git a/src/templates/hubl-project-team.pug b/src/templates/hubl-project-team.pug
deleted file mode 100644
index f8334c7..0000000
--- a/src/templates/hubl-project-team.pug
+++ /dev/null
@@ -1,22 +0,0 @@
-include hubl-user-avatar.pug
-
-solid-widget(name='hubl-project-team')
- template
- solid-display.user-thumb.is-spaced(
- data-src='${await value}'
- fields='user.account.picture, sup(user.name, isadmin), sub(user.profile.city, name)'
- value-isadmin='${await value.is_admin}'
-
- class-user.account.picture='avatar user-thumb__picture'
-
- class-user.name='user-thumb__name'
- class-isadmin='user-thumb__admin'
- class-user.profile.city='user-thumb__city'
- class-name='user-thumb__lead'
-
- widget-user.account.picture='hubl-user-avatar'
- widget-isadmin='hubl-project-user-admin'
- )
-
-solid-widget(name='hubl-project-user-admin')
- template ${(await value) == "false" ? "" : "Administrateur"}
diff --git a/src/views/admin/page-admin-circles-create.pug b/src/views/admin/page-admin-circles-create.pug
index 4ce3474..fcf1334 100644
--- a/src/views/admin/page-admin-circles-create.pug
+++ b/src/views/admin/page-admin-circles-create.pug
@@ -13,6 +13,9 @@ div.content-box__info.flex
data-src=`${endpoints.circles || endpoints.post.circles}`
fields='status, name, description'
+ required-status
+ required-name
+ required-description
loader-id='loader-circles-create'
class-status='form-label is-light is-full-width color'
diff --git a/src/views/admin/page-admin-circles.pug b/src/views/admin/page-admin-circles.pug
index b545c7b..a75f432 100644
--- a/src/views/admin/page-admin-circles.pug
+++ b/src/views/admin/page-admin-circles.pug
@@ -15,7 +15,7 @@
solid-widget(name='hubl-circle-owner')
template
- solid-display.user-thumb.is-spaced(
+ solid-display.user-thumb.block.is-spaced(
data-src='${await value}'
fields='account.picture, sup(name), sub(username)'
@@ -70,7 +70,7 @@
class-circle.name='w280 border cell-with-name'
class-circle.owner='w280 border cell-with-id-card'
- class-leaveButton='w280 border cell-with-buttons'
+ class-leaveButton='w280 border cell-with-buttons is-spaced'
action-leaveButton="joinButton"
widget-leaveButton="hubl-admin-circle-leave-button"
@@ -108,7 +108,7 @@
class-owner='w280 border cell-with-id-card'
widget-owner='hubl-circle-owner'
- class-members='w280 border cell-with-buttons'
+ class-members='w280 border cell-with-buttons is-spaced'
widget-members="hubl-admin-circle-join-button"
order-by="name"
diff --git a/src/views/admin/page-admin-projects-create.pug b/src/views/admin/page-admin-projects-create.pug
index 1bec5c3..202131b 100644
--- a/src/views/admin/page-admin-projects-create.pug
+++ b/src/views/admin/page-admin-projects-create.pug
@@ -24,6 +24,10 @@ div.content-box__info.flex
data-src=`${endpoints.projects || endpoints.post.projects}`
fields='status, line-1(customer.name, name), line-2(captain)'
+ required-status
+ required-customer.name
+ required-name
+ required-captain
loader-id='loader-projects-create'
label-status='Statut du cercle*'
@@ -40,7 +44,7 @@ div.content-box__info.flex
label-captain='Capitaine du projet*'
range-captain=`${endpoints.users || endpoints.get.users}`
class-captain='form-label is-light is-half-width'
- widget-captain='solid-form-auto-completion'
+ widget-captain='solid-form-dropdown-autocompletion-label'
class='input-text-like'
diff --git a/src/views/admin/page-admin-projects.pug b/src/views/admin/page-admin-projects.pug
index c0268b6..d984c27 100644
--- a/src/views/admin/page-admin-projects.pug
+++ b/src/views/admin/page-admin-projects.pug
@@ -46,7 +46,7 @@
solid-widget(name='hubl-project-captain')
template
- solid-display.user-thumb.is-spaced(
+ solid-display.user-thumb.block.is-spaced(
data-src='${await value}'
fields='account.picture, sup(name), sub(username)'
@@ -87,7 +87,7 @@
class-project.name='w280 cell border cell-with-name'
class-project.members='w280 cell border cell-with-id-card'
class-project.captain='w280 cell border cell-with-id-card'
- class-leaveButton='w230 cell border cell-with-buttons'
+ class-leaveButton='w230 cell border cell-with-buttons is-spaced'
action-leaveButton="joinButton"
widget-leaveButton="hubl-admin-project-leave-button"
@@ -127,7 +127,7 @@
class-name='w280 cell border cell-with-name'
class-members='w280 cell border cell-with-id-card'
class-captain='w280 cell border cell-with-id-card'
- class-joinButton='w230 cell border cell-with-buttons'
+ class-joinButton='w230 cell border cell-with-buttons is-spaced'
action-joinButton="joinButton" # Workaround: I need members two times
widget-joinButton="hubl-admin-project-join-button"
diff --git a/src/views/admin/page-admin-users-create.pug b/src/views/admin/page-admin-users-create.pug
index 03b4661..f98c5f9 100644
--- a/src/views/admin/page-admin-users-create.pug
+++ b/src/views/admin/page-admin-users-create.pug
@@ -13,6 +13,10 @@ div.content-box__info.flex
data-src=`${endpoints.users || endpoints.post.users}`
fields='line-1(first_name, last_name), line-2(username, email), line-3(password)'
+ required-first_name
+ required-last_name
+ required-username
+ required-email
loader-id='loader-users-create'
class-first_name='form-label is-light is-half-width input-text-like'
diff --git a/src/views/admin/page-admin-users-edit.pug b/src/views/admin/page-admin-users-edit.pug
index 13a9e9a..af39318 100644
--- a/src/views/admin/page-admin-users-edit.pug
+++ b/src/views/admin/page-admin-users-edit.pug
@@ -20,6 +20,9 @@ div.content-box__info.flex
bind-resources=''
fields='line-1(first_name, last_name), line-2(email)'
+ required-first_name
+ required-last_name
+ required-email
loader-id='loader-users-edit'
class-first_name='form-label is-light is-half-width input-text-like'
diff --git a/src/views/circle/page-circle-chat.pug b/src/views/circle/page-circle-chat.pug
index baee3eb..6431898 100644
--- a/src/views/circle/page-circle-chat.pug
+++ b/src/views/circle/page-circle-chat.pug
@@ -2,7 +2,7 @@
solid-xmpp-chat(
data-authentication='login',
data-auto-login='true',
- data-bosh-service-url=`${xmpp}`,
+ data-websocket-url=`${xmppWebsocket || 'wss://jabber.happy-dev.fr/xmpp-websocket'}`,
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 41e4903..3e7c5e5 100644
--- a/src/views/circle/page-circle-edit.pug
+++ b/src/views/circle/page-circle-edit.pug
@@ -2,45 +2,15 @@ div.content-box__info
include ../../templates/hubl-user-avatar.pug
- solid-widget(name='hubl-user-groups')
- template ${await value.name}
-
- solid-widget(name='hubl-team-template-edit')
+ solid-widget(name="circle-edit-members-delete")
template
- solid-display.user-thumb.is-spaced(
- class='w280 cell border cell-with-id-card user-thumb'
- data-src='${await value.user}'
- fields='account.picture, sup(name, groups), sub(profile.city)'
-
- class-account.picture='user-thumb__picture avatar'
- class-name='user-thumb__name'
- class-groups='user-thumb__groups'
- class-profile.city='user-thumb__city'
-
- widget-account.picture='hubl-user-avatar'
-
- multiple-groups=''
- widget-groups='hubl-user-groups'
- )
-
- solid-ac-checker(
- class='w162 cell border'
- permission="acl:Delete"
- data-src="${value['@id']}"
- )
+ solid-ac-checker(permission="acl:Delete" data-src="${src}")
solid-delete(
class='button text-bold text-uppercase reversed button-secondary bordered with-icon icon-close'
- data-src="${value['@id']}"
+ data-src="${src}"
data-label='Retirer'
)
- //- Only to show the table grid
- solid-ac-checker(
- class='w162 cell border'
- no-permission="acl:Delete"
- data-src="${value['@id']}"
- )
-
solid-link(class="backlink right", bind-resources, next='circle-profile') Retour
solid-ac-checker(permission='acl:Write', bind-resources)
@@ -56,6 +26,10 @@ div.content-box__info
bind-resources
fields='status, line-1(name, owner), description'
+ required-status
+ required-name
+ required-owner
+ required-description
range-owner=`${endpoints.users || endpoints.get.users}`
label-status='Statut du cercle'
@@ -70,7 +44,7 @@ div.content-box__info
class-description='form-label is-light is-full-width input-text-like'
class-status='form-label is-light is-full-width member-select color'
- widget-owner='solid-form-auto-completion'
+ widget-owner='solid-form-dropdown-autocompletion-label'
partial=''
@@ -87,9 +61,8 @@ div.content-box__info
fields='user'
range-user=`${endpoints.users || endpoints.get.users}`
- class-user='team form-label is-light'
- label-user=''
- widget-user='solid-form-auto-completion'
+ class-user='team'
+ widget-user='solid-form-dropdown-autocompletion'
submit-button='Ajouter un membre'
)
@@ -100,14 +73,28 @@ div.content-box__info
div.w280 Nom
div.w162 Accès
- //-class='table-body'
solid-display(
class='table-body'
bind-resources
- fields='members'
+ nested-field='members'
+ fields='classGroup(classGrid(user.account.picture, sup(user.name, user.groups), sub(user.profile.city))), self'
loader-id='loader-circle-edit'
- multiple-members=''
- widget-members='hubl-team-template-edit'
+ class-classGroup='w280 cell border cell-with-id-card user-thumb is-spaced'
+ class-user.account.picture='user-thumb__picture avatar'
+ class-user.name='user-thumb__name'
+ class-user.groups='user-thumb__groups'
+ class-user.profile.city='user-thumb__city'
+
+ widget-user.account.picture='hubl-user-avatar'
+
+ multiple-user.groups
+ multiple-user.groups-fields='name'
+
+ action-self='self'
+ widget-self='circle-edit-members-delete'
)
+ //- Only to show the table grid
+ div.w162.cell.border
+
diff --git a/src/views/circle/page-circle-profile.pug b/src/views/circle/page-circle-profile.pug
index 3a699ed..892ba4e 100644
--- a/src/views/circle/page-circle-profile.pug
+++ b/src/views/circle/page-circle-profile.pug
@@ -3,7 +3,6 @@ solid-router(default-route='circle-profile', hidden)
solid-route(name='circle-edit')
#circle-profile(hidden)
- include ../../templates/hubl-circle-team.pug
.content-box__info.flex
@@ -23,7 +22,7 @@ solid-router(default-route='circle-profile', hidden)
value-title='Date de création : '
- widget-creationDate='solid-display-date'
+ widget-creationDate='solid-display-value-date'
)
solid-ac-checker(permission='acl:Append', bind-resources, nested-field='members')
solid-ac-checker(permission='acl:Delete', bind-resources)
@@ -38,6 +37,7 @@ solid-router(default-route='circle-profile', hidden)
class='button mobile-full-width text-bold text-uppercase button-primary bordered with-icon icon-trash'
bind-resources
data-label='Supprimer le cercle'
+ next='admin-circles'
)
solid-widget(name='hubl-circle-leave-button')
@@ -80,14 +80,26 @@ solid-router(default-route='circle-profile', hidden)
h2 Membres :
+ solid-widget(name='hubl-circle-user-admin')
+ template ${value ? "Administrateur" : ""}
+
solid-display.block(
bind-resources
- fields='members'
+ nested-field='members'
loader-id='loader-circle-profile'
+ fields='classGroup(user.account.picture, sup(user.name, is_admin), sub(user.profile.city))'
- multiple-members=''
- widget-members='hubl-circle-team-template'
+ class-classGroup='user-thumb is-spaced'
+ class-user.account.picture='avatar user-thumb__picture'
+ class-user.name='user-thumb__name'
+ class-is_admin='user-thumb__admin'
+ class-user.profile.city='user-thumb__city'
+
+ widget-classGroup='solid-set-div'
+ widget-user.account.picture='hubl-user-avatar'
+ widget-is_admin='hubl-circle-user-admin'
)
+
#circle-edit.content-box__height(hidden)
include page-circle-edit.pug
diff --git a/src/views/job-offer/page-job-offer-create.pug b/src/views/job-offer/page-job-offer-create.pug
deleted file mode 100644
index 113c06b..0000000
--- a/src/views/job-offer/page-job-offer-create.pug
+++ /dev/null
@@ -1,27 +0,0 @@
-.content-box.with-padding.with-form
- h1 Post a new job offer
-
- solid-form(
- data-src=`${endpoints.joboffers || endpoints.post.joboffers}`
- range-skills=`${endpoints.skills || endpoints.get.skills}`
-
- fields='title, description, skills, closingDate'
-
- class-title='field form-label is-light is-expanded'
- label-title='Title*'
-
- class-description='field form-label is-light is-expanded'
- label-description='Description*'
- widget-description='solid-form-textarea'
-
- class-skills='form-label is-dark select-skills'
- label-skills='The required skills for this mission:*'
- multiple-skills='solid-multiple-select'
- widget-skills='solid-form-auto-completion'
-
- class-closingDate='form-label is-dark'
- label-closingDate='Publication end date:*'
- widget-closingDate='solid-form-date'
-
- next='job-offers'
- )
diff --git a/src/views/job-offer/page-job-offer-edit.pug b/src/views/job-offer/page-job-offer-edit.pug
deleted file mode 100644
index 5693c91..0000000
--- a/src/views/job-offer/page-job-offer-edit.pug
+++ /dev/null
@@ -1,27 +0,0 @@
-.content-box.with-padding.with-form
- h1 Edit your job offer
-
- solid-form(
- bind-resources
- range-skills=`${endpoints.skills || endpoints.get.skills}`
-
- fields='title, description, skills, closingDate'
-
- class-title='field form-label is-light is-expanded'
- label-title='Title*'
-
- class-description='field form-label is-light is-expanded'
- label-description='Description*'
- widget-description='solid-form-textarea'
-
- class-skills='form-label is-dark select-skills'
- label-skills='The required skills for this mission:*'
- multiple-skills='solid-multiple-select'
- widget-skills='solid-form-auto-completion'
-
- class-closingDate='form-label is-dark'
- label-closingDate='Publication end date:*'
- widget-closingDate='solid-form-date'
-
- next='job-offers'
- )
diff --git a/src/views/circle/page-circle-notifications.pug b/src/views/notifications/message-circle.pug
similarity index 100%
rename from src/views/circle/page-circle-notifications.pug
rename to src/views/notifications/message-circle.pug
diff --git a/src/views/user/page-user-notifications.pug b/src/views/notifications/message-private.pug
similarity index 100%
rename from src/views/user/page-user-notifications.pug
rename to src/views/notifications/message-private.pug
diff --git a/src/views/project/page-project-chat.pug b/src/views/project/page-project-chat.pug
index add91ab..01a10e6 100644
--- a/src/views/project/page-project-chat.pug
+++ b/src/views/project/page-project-chat.pug
@@ -2,7 +2,7 @@
solid-xmpp-chat(
data-authentication='login',
data-auto-login='true',
- data-bosh-service-url=`${xmpp}`,
+ data-websocket-url=`${xmppWebsocket || 'wss://jabber.happy-dev.fr/xmpp-websocket'}`,
data-i18n='en',
bind-resources
)
diff --git a/src/views/project/page-project-edit.pug b/src/views/project/page-project-edit.pug
index 82a6c1a..e054570 100644
--- a/src/views/project/page-project-edit.pug
+++ b/src/views/project/page-project-edit.pug
@@ -1,6 +1,15 @@
div.content-box__info
include ../../templates/hubl-user-avatar.pug
+
+ solid-widget(name="project-edit-members-delete")
+ template
+ solid-ac-checker(permission="acl:Delete" data-src="${src}")
+ solid-delete(
+ class='button text-bold text-uppercase reversed button-secondary bordered with-icon icon-close'
+ data-src="${src}"
+ data-label='Retirer'
+ )
solid-link(class='backlink right', bind-resources, next='project-profile') Retour
@@ -17,6 +26,8 @@ div.content-box__info
bind-resources
fields='line-1(customer.name, name)'
+ required-customer.name
+ required-name
label-name='Nom du projet*'
@@ -40,9 +51,9 @@ div.content-box__info
fields='user'
range-user=`${endpoints.users || endpoints.get.users}`
- class-user='team form-label is-light'
+ class-user='team'
label-user=''
- widget-user='solid-form-auto-completion'
+ widget-user='solid-form-dropdown-autocompletion'
submit-button='Ajouter un membre'
)
@@ -57,9 +68,21 @@ div.content-box__info
solid-display(
class='table-body'
bind-resources
- fields='members'
+ nested-field='members'
+ fields='classGroup(classGrid(user.account.picture, sup(user.name, user.groups), sub(user.profile.city))), self'
loader-id='loader-project-edit'
- multiple-members=''
- widget-members='hubl-team-template-edit'
+ class-classGroup='w280 cell border cell-with-id-card user-thumb is-spaced'
+ class-user.account.picture='user-thumb__picture avatar'
+ class-user.name='user-thumb__name'
+ class-user.groups='user-thumb__groups'
+ class-user.profile.city='user-thumb__city'
+
+ widget-user.account.picture='hubl-user-avatar'
+
+ multiple-user.groups
+ multiple-user.groups-fields='name'
+
+ action-self='self'
+ widget-self='project-edit-members-delete'
)
diff --git a/src/views/project/page-project-profile.pug b/src/views/project/page-project-profile.pug
index a81fd3e..30d39f2 100644
--- a/src/views/project/page-project-profile.pug
+++ b/src/views/project/page-project-profile.pug
@@ -4,7 +4,6 @@ solid-router(default-route='project-profile', hidden)
#project-profile(hidden)
include ../../templates/hubl-captain.pug
- include ../../templates/hubl-project-team.pug
.content-box__info.flex
@@ -24,7 +23,7 @@ solid-router(default-route='project-profile', hidden)
value-title='Date de création : '
- widget-creationDate='solid-display-date'
+ widget-creationDate='solid-display-value-date'
)
solid-ac-checker(permission='acl:Append', bind-resources, nested-field='members')
solid-ac-checker(permission='acl:Delete', bind-resources)
@@ -38,6 +37,7 @@ solid-router(default-route='project-profile', hidden)
class='button mobile-full-width text-bold text-uppercase button-primary bordered with-icon icon-trash'
bind-resources
data-label='Supprimer le projet'
+ next='admin-projects'
)
solid-widget(name='hubl-project-leave-button')
@@ -79,12 +79,24 @@ solid-router(default-route='project-profile', hidden)
h2 Equipe :
+ solid-widget(name='hubl-project-user-admin')
+ template ${value ? "Administrateur" : ""}
+
solid-display.block(
bind-resources
- fields='members'
+ nested-field='members'
+ fields='classGroup(user.account.picture, sup(user.name, is_admin), sub(user.profile.city, name))'
- multiple-members
- widget-members='hubl-project-team'
+ class-classGroup='user-thumb is-spaced'
+ class-user.account.picture='avatar user-thumb__picture'
+ class-user.name='user-thumb__name'
+ class-is_admin='user-thumb__admin'
+ class-user.profile.city='user-thumb__city'
+ class-name='user-thumb__lead'
+
+ widget-classGroup='solid-set-div'
+ widget-user.account.picture='hubl-user-avatar'
+ widget-is_admin='hubl-project-user-admin'
)
#project-edit.content-box__height(hidden)