From ae2974967048a6bbbba65df79591a1dcff970064 Mon Sep 17 00:00:00 2001 From: seraph Date: Tue, 12 May 2020 19:16:23 +0200 Subject: [PATCH] add json-server + refacto --- .eslintrc.js | 35 +- .gitlab-ci.yml | 2 +- README.md | 46 +- angular.json | 3 +- mocks/db.json | 234 ++ mocks/routes.json | 8 + package.json | 36 +- proxy.conf.json | 11 + src/app/app-routing.module.ts | 4 + src/app/app.component.ts | 2 +- src/app/app.module.ts | 13 +- .../components/header/header.component.html | 30 +- .../components/header/header.component.ts | 17 +- .../navigation/navigation.component.html | 8 +- .../navigation/navigation.component.ts | 10 +- ...response.enum.ts => response-type.enum.ts} | 2 +- src/app/core/models/answer.model.ts | 6 - src/app/core/models/choice.model.ts | 37 +- src/app/core/models/comment.model.ts | 12 +- src/app/core/models/configuration.model.ts | 20 +- .../core/models/poll-user-answers.model.ts | 6 + src/app/core/models/poll.model.ts | 84 +- src/app/core/models/user.model.ts | 8 +- src/app/core/services/api.service.ts | 163 +- src/app/core/services/comment.service.spec.ts | 16 - src/app/core/services/comment.service.ts | 15 - src/app/core/services/mocking.service.ts | 17 +- src/app/core/services/modal.service.ts | 11 + src/app/core/services/poll.service.ts | 67 +- src/app/core/services/url.service.ts | 7 +- src/app/core/services/user.service.ts | 8 +- src/app/core/services/vote.service.spec.ts | 16 - src/app/core/services/vote.service.ts | 17 - src/app/core/utils/date-utils.service.ts | 10 +- .../edit-description.component.ts | 6 +- .../poll-edit/poll-edit.component.ts | 6 +- .../profile/profile.component.html | 6 +- .../consultation-routing.module.ts | 17 + .../consultation/consultation.component.html | 62 + .../consultation.component.scss} | 0 .../consultation.component.spec.ts | 24 + .../consultation/consultation.component.ts | 40 + .../consultation/consultation.module.ts | 15 + .../poll-results-compact.component.html | 19 + .../poll-results-compact.component.scss} | 0 .../poll-results-compact.component.spec.ts | 24 + .../poll-results-compact.component.ts | 28 + .../poll-results-detailed.component.html | 35 + .../poll-results-detailed.component.scss} | 0 .../poll-results-detailed.component.spec.ts | 24 + .../poll-results-detailed.component.ts | 16 + .../{ => features/old-stuff}/mocks/choice.ts | 0 .../mocks/comment-same-text-error.json | 0 .../mocks/comment-too-fast-error.json | 0 .../mocks/config-poll-dessins-animes.json | 0 .../old-stuff}/mocks/created-comment.json | 0 .../old-stuff}/mocks/mock-comments.ts | 0 .../old-stuff}/mocks/mock-graph.ts | 0 .../old-stuff}/mocks/mock-poll3.ts | 0 .../old-stuff}/mocks/mock-success-vote.ts | 0 .../old-stuff}/mocks/mockmypolls.ts | 0 .../old-stuff}/mocks/votestack-success.json | 0 .../pages/answers/answers.component.html | 6 +- .../create-or-retrieve.component.html | 8 +- .../pages/dates/dates.component.html | 24 +- .../end-confirmation.component.html | 2 +- .../old-stuff/pages/home/home.component.html | 4 +- .../poll-display/poll-display.component.html | 6 +- .../poll-display/poll-display.component.ts | 4 +- .../poll-graphic/poll-graphic.component.ts | 4 +- .../pages/resume/resume.component.html | 8 +- .../visibility/visibility.component.html | 6 +- .../choices-list/choices-list.component.html | 4 +- .../comments-list.component.html | 6 +- .../voting-choice.component.html | 17 +- .../voting-choice.component.spec.ts | 4 +- .../voting-comment.component.ts | 2 +- .../voting-navigation.component.html | 4 +- .../voting-summary.component.html | 28 +- .../voting-summary.component.ts | 2 +- .../old-stuff/services/config.service.ts | 6 +- .../ui/copy-text/copy-text.component.html | 2 +- .../erasable-input.component.html | 2 +- .../add-answer/add-answer.component.html | 41 + .../add-answer/add-answer.component.scss | 0 .../add-answer/add-answer.component.spec.ts} | 12 +- .../add-answer/add-answer.component.ts | 30 + .../add-comment/add-comment.component.html | 26 + .../add-comment/add-comment.component.scss | 0 .../add-comment.component.spec.ts} | 12 +- .../add-comment/add-comment.component.ts | 21 + .../answers/answers.component.html | 1 + .../answers/answers.component.scss | 0 .../answers.component.spec.ts} | 12 +- .../answers/answers.component.ts | 18 + .../participation-routing.module.ts | 2 - .../participation.component.html | 25 +- .../participation/participation.component.ts | 2 + .../participation/participation.module.ts | 7 +- .../poll-comment/poll-comment.component.html | 1 - .../poll-comment/poll-comment.component.ts | 12 - .../participation/poll/poll.component.html | 6 - .../choice-details.component.html | 36 + .../choice-details.component.scss | 0 .../choice-details.component.spec.ts | 24 + .../choice-details.component.ts | 25 + .../comments/comments.component.html | 9 + .../comments/comments.component.scss | 0 .../comments/comments.component.spec.ts | 24 + .../comments/comments.component.ts} | 12 +- .../components/feedback/feedback.component.ts | 3 +- .../poll-page/poll-page.component.html | 1 - .../poll-page/poll-page.component.ts | 12 - .../language-selector.component.html | 6 +- .../theme-selector.component.html | 12 +- .../theme-selector.component.ts | 2 +- .../settings/settings.component.html | 16 +- .../components/settings/settings.component.ts | 2 +- src/app/shared/shared.module.ts | 8 +- ...otant-pas-sur.svg => icon_voter_MAYBE.svg} | 0 .../{votant-sur.svg => icon_voter_YES.svg} | 0 src/environments/environment.prod.ts | 25 +- src/environments/environment.ts | 16 +- tsconfig.json | 41 +- yarn.lock | 2853 ++++++++++------- 125 files changed, 3086 insertions(+), 1721 deletions(-) create mode 100644 mocks/db.json create mode 100644 mocks/routes.json create mode 100644 proxy.conf.json rename src/app/core/enums/{response.enum.ts => response-type.enum.ts} (63%) delete mode 100644 src/app/core/models/answer.model.ts create mode 100644 src/app/core/models/poll-user-answers.model.ts delete mode 100644 src/app/core/services/comment.service.spec.ts delete mode 100644 src/app/core/services/comment.service.ts delete mode 100644 src/app/core/services/vote.service.spec.ts delete mode 100644 src/app/core/services/vote.service.ts create mode 100644 src/app/features/consultation/consultation-routing.module.ts create mode 100644 src/app/features/consultation/consultation.component.html rename src/app/features/{participation/poll-comment/poll-comment.component.scss => consultation/consultation.component.scss} (100%) create mode 100644 src/app/features/consultation/consultation.component.spec.ts create mode 100644 src/app/features/consultation/consultation.component.ts create mode 100644 src/app/features/consultation/consultation.module.ts create mode 100644 src/app/features/consultation/poll-results-compact/poll-results-compact.component.html rename src/app/features/{participation/poll/poll.component.scss => consultation/poll-results-compact/poll-results-compact.component.scss} (100%) create mode 100644 src/app/features/consultation/poll-results-compact/poll-results-compact.component.spec.ts create mode 100644 src/app/features/consultation/poll-results-compact/poll-results-compact.component.ts create mode 100644 src/app/features/consultation/poll-results-detailed/poll-results-detailed.component.html rename src/app/{shared/components/poll-page/poll-page.component.scss => features/consultation/poll-results-detailed/poll-results-detailed.component.scss} (100%) create mode 100644 src/app/features/consultation/poll-results-detailed/poll-results-detailed.component.spec.ts create mode 100644 src/app/features/consultation/poll-results-detailed/poll-results-detailed.component.ts rename src/app/{ => features/old-stuff}/mocks/choice.ts (100%) rename src/app/{ => features/old-stuff}/mocks/comment-same-text-error.json (100%) rename src/app/{ => features/old-stuff}/mocks/comment-too-fast-error.json (100%) rename src/app/{ => features/old-stuff}/mocks/config-poll-dessins-animes.json (100%) rename src/app/{ => features/old-stuff}/mocks/created-comment.json (100%) rename src/app/{ => features/old-stuff}/mocks/mock-comments.ts (100%) rename src/app/{ => features/old-stuff}/mocks/mock-graph.ts (100%) rename src/app/{ => features/old-stuff}/mocks/mock-poll3.ts (100%) rename src/app/{ => features/old-stuff}/mocks/mock-success-vote.ts (100%) rename src/app/{ => features/old-stuff}/mocks/mockmypolls.ts (100%) rename src/app/{ => features/old-stuff}/mocks/votestack-success.json (100%) create mode 100644 src/app/features/participation/add-answer/add-answer.component.html create mode 100644 src/app/features/participation/add-answer/add-answer.component.scss rename src/app/{shared/components/poll-page/poll-page.component.spec.ts => features/participation/add-answer/add-answer.component.spec.ts} (54%) create mode 100644 src/app/features/participation/add-answer/add-answer.component.ts create mode 100644 src/app/features/participation/add-comment/add-comment.component.html create mode 100644 src/app/features/participation/add-comment/add-comment.component.scss rename src/app/features/participation/{poll-comment/poll-comment.component.spec.ts => add-comment/add-comment.component.spec.ts} (53%) create mode 100644 src/app/features/participation/add-comment/add-comment.component.ts create mode 100644 src/app/features/participation/answers/answers.component.html create mode 100644 src/app/features/participation/answers/answers.component.scss rename src/app/features/participation/{poll/poll.component.spec.ts => answers/answers.component.spec.ts} (55%) create mode 100644 src/app/features/participation/answers/answers.component.ts delete mode 100644 src/app/features/participation/poll-comment/poll-comment.component.html delete mode 100644 src/app/features/participation/poll-comment/poll-comment.component.ts delete mode 100644 src/app/features/participation/poll/poll.component.html create mode 100644 src/app/shared/components/choice-details/choice-details.component.html create mode 100644 src/app/shared/components/choice-details/choice-details.component.scss create mode 100644 src/app/shared/components/choice-details/choice-details.component.spec.ts create mode 100644 src/app/shared/components/choice-details/choice-details.component.ts create mode 100644 src/app/shared/components/comments/comments.component.html create mode 100644 src/app/shared/components/comments/comments.component.scss create mode 100644 src/app/shared/components/comments/comments.component.spec.ts rename src/app/{features/participation/poll/poll.component.ts => shared/components/comments/comments.component.ts} (56%) delete mode 100644 src/app/shared/components/poll-page/poll-page.component.html delete mode 100644 src/app/shared/components/poll-page/poll-page.component.ts rename src/assets/img/{votant-pas-sur.svg => icon_voter_MAYBE.svg} (100%) rename src/assets/img/{votant-sur.svg => icon_voter_YES.svg} (100%) diff --git a/.eslintrc.js b/.eslintrc.js index 5e52571..904bcc1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,19 +1,20 @@ module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 2018, - sourceType: 'module', - project: './tsconfig.json', - tsconfigRootDir: __dirname, - }, - plugins: ['@typescript-eslint'], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/eslint-recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - 'prettier/@typescript-eslint', - 'plugin:prettier/recommended', - ], - rules: {}, + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:prettier/recommended', + 'prettier/@typescript-eslint', + ], + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + project: './tsconfig.json', + tsconfigRootDir: __dirname, + }, + rules: { + '@typescript-eslint/unbound-method': ['error', { ignoreStatic: true }], + }, }; diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 96b90df..974e908 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,7 +13,7 @@ pages: stage: pages script: - yarn install --pure-lockfile - - npx ng build --base-href=/framadate/funky-framadate-front/ + - yarn build - mv dist/framadate/ public/ artifacts: paths: diff --git a/README.md b/README.md index b4d32f1..8430f0b 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,29 @@ ## LIBRARIES USED -| status | lib name | usage | -| --------------- | -------------------------------------------------------------- | ---------------------------------------- | -| | [axios](https://github.com/axios/axios) | http client | -| | [bulma](https://bulma.io/) | CSS framework | -| | [chart.js](https://www.chartjs.org/) | Display graphs. (Comes with MomentJS) | -| | [compodoc](https://compodoc.app/) | Generate technic documentation | -| | ESlint, Prettier, Lint-staged | Format & lint code | -| | [fork-awesome](https://forkaweso.me) | Icons collection | -| | [fullcalendar](https://fullcalendar.io/docs/initialize-es6) | Manage & display calendars | -| | [husky](https://www.npmjs.com/package/husky) | Hook actions on commit | -| | [jest](https://jestjs.io/) | test engine | -| removed | [locale-enum](https://www.npmjs.com/package/locale-enum) | enum of all locales | -| | [momentJS](https://momentjs.com/) | manipulate dates. (chartJS’s dependency) | -| to be installed | [ng2-charts](https://valor-software.com/ng2-charts/) | Manipulate graphs along with chart.js | -| | [ngx-clipboard](https://www.npmjs.com/package/ngx-clipboard) | Handle clipboard | -| | [ngx-markdown](https://www.npmjs.com/package/ngx-markdown) | markdown parser | -| | [ngx-webstorage](https://www.npmjs.com/package/ngx-webstorage) | handle localStorage & webStorage | -| | [primeNG](https://www.primefaces.org/primeng/) | UI components collection | -| | [quill](https://www.npmjs.com/package/quill) | powerful rich text editor. WYSIWYG. | -| removed | [storybook](https://storybook.js.org/) | StyleGuide UI | -| | [ts-mockito](https://www.npmjs.com/package/ts-mockito) | Mocks for testing. | -| | [uuid](https://www.npmjs.com/package/uuid) | handle client-side generation of uuids | +| status | lib name | usage | +| :-------------: | -------------------------------------------------------------- | --------------------------------------------------------- | +| | [axios](https://github.com/axios/axios) | http client | +| | [bulma](https://bulma.io/) | CSS framework | +| | [chart.js](https://www.chartjs.org/) | PrimeNG solution for graphs. (Chart.js installs MomentJS) | +| | [compodoc](https://compodoc.app/) | Generate technic documentation | +| | ESlint, Prettier, Lint-staged | Format & lint code | +| | [fork-awesome](https://forkaweso.me) | Icons collection | +| | [fullcalendar](https://fullcalendar.io/docs/initialize-es6) | PrimeNG solution to manage & display calendars | +| | [husky](https://www.npmjs.com/package/husky) | Hook actions on commit | +| | [jest](https://jestjs.io/) | test engine | +| | [json-server](https://www.npmjs.com/package/json-server) | local server for mocking data backend | +| removed | [locale-enum](https://www.npmjs.com/package/locale-enum) | enum of all locales | +| | [momentJS](https://momentjs.com/) | manipulate dates. (chartJS’s dependency) | +| to be installed | [ng2-charts](https://valor-software.com/ng2-charts/) | Manipulate graphs along with chart.js | +| | [ngx-clipboard](https://www.npmjs.com/package/ngx-clipboard) | Handle clipboard | +| | [ngx-markdown](https://www.npmjs.com/package/ngx-markdown) | markdown parser | +| | [ngx-webstorage](https://www.npmjs.com/package/ngx-webstorage) | handle localStorage & webStorage | +| | [primeNG](https://www.primefaces.org/primeng/) | UI components collection | +| | [quill](https://www.npmjs.com/package/quill) | powerful rich text editor. WYSIWYG. | +| to be installed | [short-uuid](https://www.npmjs.com/package/short-uuid) | generate uuid | +| removed | [storybook](https://storybook.js.org/) | StyleGuide UI | +| | [ts-mockito](https://www.npmjs.com/package/ts-mockito) | Mocks for testing. | +| to be removed | [uuid](https://www.npmjs.com/package/uuid) | generate uuid | --- This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.1. diff --git a/angular.json b/angular.json index 8864f04..a9606a6 100644 --- a/angular.json +++ b/angular.json @@ -25,10 +25,9 @@ "assets": ["src/favicon.ico", "src/assets"], "styles": [ "node_modules/fork-awesome/css/fork-awesome.min.css", - "node_modules/primeicons/primeicons.css", "node_modules/primeng/resources/themes/nova-light/theme.css", "node_modules/primeng/resources/primeng.min.css", - "node_modules/primeflex/primeflex.css", + "node_modules/bulma-switch/dist/css/bulma-switch.min.css", "src/styles.scss" ], "scripts": [ diff --git a/mocks/db.json b/mocks/db.json new file mode 100644 index 0000000..eef2dd9 --- /dev/null +++ b/mocks/db.json @@ -0,0 +1,234 @@ +{ + "owners": [ + { "id": 1, "email": "toto@gafam.com", "pseudo": "TOTO" }, + { "id": 2, "email": "titi@gafam.com", "pseudo": "TITI" } + ], + "voters": [{ "pseudo": "TOTO", "polls": [] }], + "polls": [ + { + "id": 1, + "slug": "picnic", + "configuration": { + "isAboutDate": true, + "isProtectedByPassword": false, + "isOwnerNotifiedByEmailOnNewVote": false, + "isOwnerNotifiedByEmailOnNewComment": false, + "isMaybeAnswerAvailable": true, + "areResultsPublic": true, + "dateCreated": "2020-05-17", + "expires": "2020-06-17" + }, + "ownerId": 1, + "question": "Quelle date pour le picnic ?", + "description": "Gros badass picnic en plein air ! Come on !", + "answersByChoiceByParticipant": { + "TOTO": { "samedi": "YES", "dimanche": "NO" }, + "TATA": { "samedi": "NO", "dimanche": null }, + "TITI": { "samedi": "MAYBE", "dimanche": "NO" } + }, + "answers": [ + { + "pseudo": "TOTO", + "token": "TOTO-TOKEN", + "responsesByChoices": [ + { "choice": { "label": "samedi", "imagePath": null }, "responseType": "YES" }, + { "choice": { "label": "dimanche", "imagePath": null }, "responseType": "NO" } + ] + }, + { + "pseudo": "TATA", + "token": "TATA-TOKEN", + "responsesByChoices": [ + { "choice": { "label": "samedi", "imagePath": null }, "responseType": "NO" }, + { "choice": { "label": "dimanche", "imagePath": null }, "responseType": "NO" } + ] + }, + { + "pseudo": "TITI", + "token": "TITI-TOKEN", + "responsesByChoices": [ + { "choice": { "label": "samedi", "imagePath": null }, "responseType": "NO" }, + { "choice": { "label": "dimanche", "imagePath": null }, "responseType": "YES" } + ] + }, + { + "pseudo": "TETE", + "token": "TETE-TOKEN", + "responsesByChoices": [ + { "choice": { "label": "samedi", "imagePath": null }, "responseType": "YES" }, + { "choice": { "label": "dimanche", "imagePath": null }, "responseType": "NO" } + ] + } + ] + }, + { + "id": 2, + "slug": "vacances", + "configuration": { + "isAboutDate": true, + "isProtectedByPassword": false, + "isOwnerNotifiedByEmailOnNewVote": false, + "isOwnerNotifiedByEmailOnNewComment": false, + "isMaybeAnswerAvailable": true, + "areResultsPublic": true, + "dateCreated": "2020-05-17", + "expires": "2020-06-17" + }, + "ownerId": 2, + "question": "On fait quoi pendant les vacances ?", + "description": "Vacances en famille", + "answersByChoiceByParticipant": { + "TOTO": { "bateau": "YES", "montagne": "NO", "quad": "MAYBE" }, + "TATA": { "bateau": "NO", "montagne": null, "quad": "YES" }, + "TITI": { "bateau": "MAYBE", "montagne": "NO", "quad": null } + }, + "answers": [ + { + "pseudo": "TOTO", + "token": "TOTO-TOKEN", + "responsesByChoices": [ + { "choice": { "label": "bateau", "imagePath": null }, "responseType": "YES" }, + { "choice": { "label": "montagne", "imagePath": null }, "responseType": "NO" }, + { "choice": { "label": "quad", "imagePath": null }, "responseType": "NO" } + ] + }, + { + "pseudo": "TATA", + "token": "TATA-TOKEN", + "responsesByChoices": [ + { "choice": { "label": "bateau", "imagePath": null }, "responseType": "NO" }, + { "choice": { "label": "montagne", "imagePath": null }, "responseType": "NO" }, + { "choice": { "label": "quad", "imagePath": null }, "responseType": "NO" } + ] + }, + { + "pseudo": "TITI", + "token": "TITI-TOKEN", + "responsesByChoices": [ + { "choice": { "label": "bateau", "imagePath": null }, "responseType": "NO" }, + { "choice": { "label": "montagne", "imagePath": null }, "responseType": "YES" }, + { "choice": { "label": "quad", "imagePath": null }, "responseType": "NO" } + ] + }, + { + "pseudo": "TETE", + "token": "TETE-TOKEN", + "responsesByChoices": [ + { "choice": { "label": "bateau", "imagePath": null }, "responseType": "YES" }, + { "choice": { "label": "montagne", "imagePath": null }, "responseType": "NO" }, + { "choice": { "label": "quad", "imagePath": null }, "responseType": "NO" } + ] + } + ] + } + ], + "choices": [ + { + "id": 1, + "pollId": 1, + "pollSlug": "picnic", + "label": "samedi", + "participants": [ + ["YES", ["TOTO", "TITI"]], + ["NO", ["TETE"]], + ["MAYBE", ["TATA"]] + ] + }, + { + "id": 2, + "pollId": 1, + "pollSlug": "picnic", + "label": "dimanche", + "participants": [ + ["YES", ["TOTO", "TITI"]], + ["NO", ["TETE"]], + ["MAYBE", ["TATA"]] + ] + }, + { + "id": 3, + "pollId": 2, + "pollSlug": "vacances", + "label": "bateau", + "participants": [ + ["YES", ["TOTO", "TITI"]], + ["NO", ["TETE"]], + ["MAYBE", ["TATA"]] + ] + }, + { + "id": 4, + "pollId": 2, + "pollSlug": "vacances", + "label": "montagne", + "participants": [ + ["YES", ["TOTO", "TITI"]], + ["NO", ["TETE"]], + ["MAYBE", ["TATA"]] + ] + }, + { + "id": 5, + "pollId": 2, + "pollSlug": "vacances", + "label": "quad", + "participants": [ + ["YES", ["TOTO", "TITI"]], + ["NO", ["TETE"]], + ["MAYBE", ["TATA"]] + ] + } + ], + "answers": [ + { "choiceId": 1, "pseudo": "TOTO", "response": "YES", "token": "TOTO-TOKEN" }, + { "choiceId": 1, "pseudo": "TATA", "response": "NO", "token": "TATA-TOKEN" }, + { "choiceId": 1, "pseudo": "TITI", "response": "MAYBE", "token": "TITI-TOKEN" }, + { "choiceId": 2, "pseudo": "TOTO", "response": "YES", "token": "TOTO-TOKEN" }, + { "choiceId": 2, "pseudo": "TATA", "response": "NO", "token": "TATA-TOKEN" }, + { "choiceId": 2, "pseudo": "TITI", "response": "MAYBE", "token": "TITI-TOKEN" }, + { "choiceId": 2, "pseudo": "EVA", "response": null, "token": "EVA-TOKEN" }, + { "choiceId": 3, "pseudo": "TOTO", "response": "YES", "token": "TOTO-TOKEN" }, + { "choiceId": 3, "pseudo": "TATA", "response": "NO", "token": "TATA-TOKEN" }, + { "choiceId": 3, "pseudo": "TITI", "response": "MAYBE", "token": "TITI-TOKEN" }, + { "choiceId": 4, "pseudo": "TOTO", "response": "YES", "token": "TOTO-TOKEN" }, + { "choiceId": 4, "pseudo": "TATA", "response": "NO", "token": "TATA-TOKEN" }, + { "choiceId": 4, "pseudo": "TITI", "response": "MAYBE", "token": "TITI-TOKEN" }, + { "choiceId": 5, "pseudo": "TOTO", "response": "YES", "token": "TOTO-TOKEN" }, + { "choiceId": 5, "pseudo": "TATA", "response": "NO", "token": "TATA-TOKEN" }, + { "choiceId": 5, "pseudo": "TITI", "response": "MAYBE", "token": "TITI-TOKEN" } + ], + "comments": [ + { + "id": 1, + "pollId": 1, + "pollSlug": "picnic", + "content": "Les picnics, c’est trop bien, j’adore!", + "author": "TATA", + "dateCreated": 1589111111111 + }, + { + "id": 2, + "pollId": 1, + "pollSlug": "picnic", + "content": "Oué, grave!", + "author": "TETE", + "dateCreated": 1589222222222 + }, + { + "id": 3, + "pollId": 2, + "pollSlug": "vacances", + "content": "Désolé je pourrai pas être là, mais je penserai bien à vous. Mamie", + "author": "MAMIE", + "dateCreated": 1589333333333 + }, + { + "id": 4, + "pollId": 2, + "pollSlug": "vacances", + "content": "Arf, trop dommage.", + "author": "Tom", + "dateCreated": 1589444444444 + } + ] +} diff --git a/mocks/routes.json b/mocks/routes.json new file mode 100644 index 0000000..45524ed --- /dev/null +++ b/mocks/routes.json @@ -0,0 +1,8 @@ +{ + "/api/v1/*": "/$1", + "/owners/:email/": "/owners?email=:email", + "/choices": "/choices?_embed=answers", + "/polls/:slug": "/polls?slug=:slug&_expand=owner&_embed=choices&_embed=comments", + "/polls/:slug/choices": "/choices?pollSlug=:slug&_embed=answers", + "/polls/:slug/comments": "/comments?pollSlug=:slug" +} diff --git a/package.json b/package.json index 3bcda40..ec19d7f 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,15 @@ "test": "jest", "test:watch": "jest --watch", "test:ci": "jest --runInBand", - "lint": "ng lint", + "lint": "prettier --write \"src/**/*.{js,jsx,ts,tsx,md,html,css,scss}\"", "e2e": "ng e2e", "format:check": "prettier --list-different \"src/{app,environments,assets}/**/*{.ts,.js,.json,.css,.scss}\"", "format:all": "prettier --write \"src/**/*.{js,jsx,ts,tsx,md,html,css,scss}\"", "trans": "ng xi18n --output-path=src/locale --i18n-locale=fr", - "compodoc": "compodoc -p tsconfig.app.json" + "compodoc": "compodoc -p tsconfig.app.json", + "mock:server": "json-server --port 8000 --watch ./mocks/db.json --routes ./mocks/routes.json", + "start:proxy": "ng serve --proxy-config proxy.conf.json", + "start:proxymock": "concurrently --kill-others \"yarn mock:server\" \"yarn start:proxy\"" }, "private": false, "dependencies": { @@ -36,20 +39,19 @@ "@ngx-translate/http-loader": "^4.0.0", "angular-date-value-accessor": "^1.0.2", "axios": "^0.19.2", - "bulma": "^0.8.2", + "bulma": "^0.9.0", + "bulma-switch": "^2.0.0", "chart.js": "^2.9.3", "fork-awesome": "^1.1.7", "ng2-charts": "^2.3.0", "ngx-clipboard": "^13.0.0", "ngx-markdown": "^9.0.0", "ngx-webstorage": "^5.0.0", - "primeflex": "^1.0.0", - "primeicons": "^2.0.0", "primeng": "^9.0.6", "quill": "^1.3.7", "rxjs": "^6.5.5", "rxjs-compat": "^6.5.5", - "tslib": "^1.11.1", + "tslib": "<2.0.0", "uuid": "^8.0.0", "zone.js": "^0.10.3" }, @@ -64,22 +66,24 @@ "@babel/preset-typescript": "^7.9.0", "@compodoc/compodoc": "^1.1.11", "@types/jest": "^25.2.1", - "@types/node": "^13.13.2", - "@types/uuid": "^7.0.2", - "@typescript-eslint/eslint-plugin": "^2.27.0", - "@typescript-eslint/parser": "^2.27.0", + "@types/node": "^14.0.1", + "@types/uuid": "^8.0.0", + "@typescript-eslint/eslint-plugin": "^3.0.0", + "@typescript-eslint/parser": "^3.0.0", "babel-jest": "^26.0.0", - "eslint": "^6.8.0", + "concurrently": "^5.2.0", + "eslint": "^7.0.0", "eslint-config-prettier": "^6.11.0", "eslint-plugin-prettier": "^3.1.3", "husky": "^4.2.5", "jest": "^26.0.0", "jest-environment-jsdom-sixteen": "^1.0.3", "jest-preset-angular": "^8.1.3", + "json-server": "^0.16.1", "lint-staged": "^10.1.7", "prettier": "^2.0.5", - "protractor": "~5.4.3", - "ts-jest": "^25.4.0", + "protractor": "~7.0.0", + "ts-jest": "^26.0.0", "ts-mockito": "^2.5.0", "ts-node": "^8.10.1", "typescript": "~3.8.3" @@ -90,11 +94,13 @@ } }, "lint-staged": { - "src/{app,environments,assets}/**/*.{js,jsx,ts,tsx,md,html,css,scss}": [ + "src/**/*.{js,jsx,ts,tsx,md,html,css,scss}": [ "prettier --write", "git add" ], - "*.js": "eslint --cache --fix" + "*.js": [ + "prettier --write" + ] }, "jest": { "preset": "jest-preset-angular", diff --git a/proxy.conf.json b/proxy.conf.json new file mode 100644 index 0000000..220da25 --- /dev/null +++ b/proxy.conf.json @@ -0,0 +1,11 @@ +{ + "/api/v1/*": { + "target": "http://localhost:8000", + "secure": false, + "pathRewrite": { + "^/api/v1": "" + }, + "changeOrigin": false, + "logLevel": "debug" + } +} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index ca478a7..1694a96 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -11,6 +11,10 @@ const routes: Routes = [ loadChildren: () => import('./features/administration/administration.module').then((m) => m.AdministrationModule), }, + { + path: 'consultation', + loadChildren: () => import('./features/consultation/consultation.module').then((m) => m.ConsultationModule), + }, { path: 'participation', loadChildren: () => import('./features/participation/participation.module').then((m) => m.ParticipationModule), diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 0059d36..c9586d9 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -32,7 +32,7 @@ export class AppComponent implements OnInit, OnDestroy { if (!environment.production) { this.appTitle += ' [DEV]'; // TODO: to be removed - this.mockingService.loadUser(new User('TOTO', 'toto@gafam.com', UserRole.REGISTERED, false)); + this.mockingService.loadUser(new User('TOTO', 'toto@gafam.com', UserRole.REGISTERED)); } this.titleService.setTitle(this.appTitle); this.languageService.configureAndInitTranslations(); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 71defe5..9667d07 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,5 +1,7 @@ -import { CommonModule } from '@angular/common'; +import { APP_BASE_HREF, CommonModule, registerLocaleData } from '@angular/common'; import { HttpClient, HttpClientModule } from '@angular/common/http'; +import localeEn from '@angular/common/locales/en'; +import localeFr from '@angular/common/locales/fr'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { BrowserModule, Title } from '@angular/platform-browser'; @@ -21,8 +23,9 @@ import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { CoreModule } from './core/core.module'; import { SharedModule } from './shared/shared.module'; -import { ParticipationModule } from './features/participation/participation.module'; -import { AdministrationModule } from './features/administration/administration.module'; + +registerLocaleData(localeEn, 'en-EN'); +registerLocaleData(localeFr, 'fr-FR'); export class MyMissingTranslationHandler implements MissingTranslationHandler { public handle(params: MissingTranslationHandlerParams): string { @@ -38,7 +41,6 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader { declarations: [AppComponent], imports: [ AppRoutingModule, - AdministrationModule, BrowserAnimationsModule, BrowserModule, ClipboardModule, @@ -61,9 +63,8 @@ export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader { }, useDefaultLang: false, }), - ParticipationModule, ], - providers: [Title, TranslateService], + providers: [{ provide: APP_BASE_HREF, useValue: environment.baseHref }, Title, TranslateService], bootstrap: [AppComponent], }) export class AppModule {} diff --git a/src/app/core/components/header/header.component.html b/src/app/core/components/header/header.component.html index ffc6548..432ec7e 100644 --- a/src/app/core/components/header/header.component.html +++ b/src/app/core/components/header/header.component.html @@ -37,18 +37,30 @@ + @@ -57,11 +69,11 @@ diff --git a/src/app/core/components/header/header.component.ts b/src/app/core/components/header/header.component.ts index c6f9f4c..ad2de52 100644 --- a/src/app/core/components/header/header.component.ts +++ b/src/app/core/components/header/header.component.ts @@ -1,7 +1,8 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Observable } from 'rxjs'; import { User } from '../../models/user.model'; +import { ApiService } from '../../services/api.service'; import { ModalService } from '../../services/modal.service'; import { UserService } from '../../services/user.service'; @@ -10,13 +11,23 @@ import { UserService } from '../../services/user.service'; templateUrl: './header.component.html', styleUrls: ['./header.component.scss'], }) -export class HeaderComponent { +export class HeaderComponent implements OnInit { @Input() isSidebarOpened: boolean; @Output() toggleSidebarEE = new EventEmitter(); public _user: Observable = this.userService.user; - constructor(private userService: UserService, private modalService: ModalService) {} + public slugsAvailables: string[] = []; + + constructor(private userService: UserService, private modalService: ModalService, private apiService: ApiService) {} + + public ngOnInit(): void { + this.getSlugs(); + } + + public async getSlugs(): Promise { + this.slugsAvailables = await this.apiService.getAllPollsSlugs(); + } public openDialog(): void { this.modalService.openSettingsComponent(); diff --git a/src/app/core/components/sibebar/navigation/navigation.component.html b/src/app/core/components/sibebar/navigation/navigation.component.html index 54c8767..ccfc3f6 100644 --- a/src/app/core/components/sibebar/navigation/navigation.component.html +++ b/src/app/core/components/sibebar/navigation/navigation.component.html @@ -1,11 +1,7 @@