Giter Club home page Giter Club logo

algoreafrontend's People

Contributors

ayerls avatar dependabot[bot] avatar gabrielvidal1 avatar gustavomorenomena avatar iloveall avatar inotite avatar mathias-hiron avatar mblockelet avatar ostrogo avatar smadbe avatar thomasjuster avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

256taras

algoreafrontend's Issues

Item progress tab: log view (first version)

Overview

In the progress page (for instance http://dev.algorea.org/en/#/activities/by-id/4702;parentAttempId=0;path=/details/progress), display a list (table) of latest activities of the current user on this item. (as bit as drafted at the bottom of this design , but with more relevant content)

Details

  • In ItemLogViewComponent (existing component):
    • add a table to display the result of state.data (check MemberListComponent for an example of table)
    • this table should have the following columns:
      • "Action", which values which could be (see (API for the service for explanation of the input) "Submission" (if "submission" with score undefined), "Submission (score: )" (if "submission" with score given), "Activity started" (if "result_started") or "Activity validated" (if "result_validated")
      • "Content", which is the "title" of the item with a link to that item
      • Time with minute precision (check MemberListComponent for an example)
  • May require to update a bit the ActivityLog interface returned by the service. (API for the service used)
  • No need to support any sort for now.

Item details: header

Start the item page with (according to designs)

  • the title
  • the subtitle (if any)
  • a tab "content" with a "description" section if type === 'Chapter'

Group pages and tabs

For the group pages:

  • use the route /groups/:id for group page (overview content by default) (no need for "managed" in it as the page is the same for management or not)
  • if the user is not a manager (use group.current_user_is_manager info), as only the "overview" tab is relevant, do not display the tab bar at all (so display the content of the overview tab, without tab bar)
  • only display the "admin" and "settings" tab if group.current_user_can_manage=="memberships_and_group"
  • "composition" tab, on /groups/:id/members, check that the group.current_user_is_manager is true, otherwise display that the user does not have the permissions to see this content
  • "admin" tab, on /groups/:id/managers, check that the group.current_user_is_manager is true AND group.current_user_can_manage=="memberships_and_group", otherwise display that the user does not have the permissions to see this content
  • "settings" tab, on /groups/:id/settings, check that the group.current_user_is_manager is true AND group.current_user_can_manage=="memberships_and_group", otherwise display that the user does not have the permissions to see this content

Pending request: change the loading behavior

Change the way the blue panel "pending request" is displayed:

  • always display the "pending request" panel when displaying a group IF the group has is_public=true.
  • keep the blue panel collapsed by default
  • while loading, grey-out the "this-group/subgroups" switch and display a loading spinner
  • when loaded, re-enable the switch and:
    • if loading error: display an error message in place of the table
    • if empty: display a message that it is empty in place of the table
    • otherwise, display the table and un-collapse the panel

"Groups you manage" page, step 1: pending requests

As you can see on http://dev.algorea.org/branch/design/, when clicking on "groups you managed" without selecting any group, there is a page which summarizes everything on group you manage.

Step 1:

  • create a page: /groups/managed that can be accessed through the left menu
  • add title/subtitle
  • include the pending request component to display requests for all groups (may require slight changes)

"Group you manage" page: the group list

As you can see on http://dev.algorea.org/branch/design/, when clicking on "groups you managed" without selecting any group, there is a page which summarizes everything on group you manage.

  • implement the service fetching the groups the user manages (https://france-ioi.github.io/algorea-devdoc/api/#operation/managedGroupsView)
  • list the groups in a grid with as columns: name, type, can_manage, can_watch_members,can_grant_group_access
  • you can get inspired by the group you joined (/groups/joined) and manager list (/groups/by-id/:id/details/managers) pages
  • while loading, display a loader on the grid
  • if the user does not manage any group, display a message "You do not manage any group".
  • only display the "direct children", do not include the "direct children / all descendants" on top.
  • clicking on a group name navigates to this group page

Add i18n

From Ivan:

I am going to use `ngx-translate` module for internationalization.
We can translate the text inside the html files using the translate pipe or directive.
It supports the translation inside ts files using `TranslateService`.
The translation files can be stored at assets/i18n/{lang} or other locations we prefer in json format.
eg. en.json, fr.json, ...

Group management page integration

  • We want to be able to work on the "final" designs with all features and in parallel on the integration with the backend which only includes a subset of the components and features. In order to achieve that goal, create two "home pages" which will use different components. Some (sub)components will be common, some will differ (while not fully implemented). The idea is to have the "design" sub-site which includes latest version of the designs, and the "integration" sub-site which is "fully" functional on a limited a set of functionalities. Both should be available at "the same time".

  • in the menu, "groups you manage", add 2 groups: "group 50" and "group 51", with "blue arrow" linking respectively to /groups/managed/50 and /groups/managed/51

  • page /groups/managed/:id shows:

    • on the right pane (page excluding the left menu and the breadcrumb), only display components which can be implemented and show correct information.
    • header: group name (so no link/img/url/address)
    • between header and tabs: the "pending requests" for this group:
      • list requests (GET /groups/50/requests), only keep those with action=="join_request_created"
      • if the list is empty, do not display the blue panel at all
      • remove picture, long text
      • if "grade" is not null for the joining_user, display "Grade: " where "Terminale" is displayed in the designs
      • Hide "this group only"/"all subgroups"
      • add sorting to this list (backend-side, cfr the sort in the API)
      • implement actions accept/reject :
        • call POST /groups/{parent_group_id}/join-requests/accept and /reject), for one or several users
        • while the action is in progress (backend not received), display a spinner instead of the pressed button icon, grey out the other button. (for instance, if "accept" is pressed, a spinner replaces the checkmark and "decline X" is greyed out (and not allowed)), grey out the selection boxes and "select all" button.
        • on success, if all ids are "success" or "unchanged", display a green toast "X request(s) have been accepted" (or "declined") [updated]
        • on success, if all accept/reject are in error (not "success" or "unchanged"), display a red toast "Unable to accept/reject the selected request(s)." [updated]
        • on success, if there are some errors (not "success" or "unchanged"), display "X request(s) have been accepted (or declined), Y could not be executed" in an orange toast [updated]
        • on 4xx/5xx, display a red toast, "The action cannot be executed. If the problem persists, contact us."
        • the accept/decline buttons are greyed out while there are no selected requests
        • Adapt the UI correctly (reload the list and reset the spinner/greyed state) after getting the service response. he selected row(s) should be consistent with what was before
    • Overview tab:
      • "Presentation": put "description" if given, otherwise do not put it (add one to group 50: update `groups` set description = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vitae imperdiet ligula. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In et dignissim ipsums ' where id = 50;)
      • For "Recently solved tasks":
        • Load /groups/{group_id}/recent_activity
        • If the list in empty, display a lorem ipsum instead of the table (like here)
        • Use item.string.title as "Task" column
        • Use created_at (date + time) as "Time" column
        • Use "user.firstname user.lastname (user.login)" as "User" column
        • Display the usual score circle to display the score and the validation state
    • Composition/administration/settings tabs: left empty for now
  • For all:

    • on failure when loading data (>< actions): display a red toast "Unable to list the requested information. If the problem persists, contact us."
    • Wheel button of tables: "personnaliser" -> "Customize", remove"Epreuves", column names capitalized
    • handle sort on columns for which the backend supports sorting

Pending request: add this group only / all subgroups switch, step 3: adapt acceptation/rejection

As it is done in the design branch (http://dev.algorea.org/branch/design/), add to the "pending request" box the switch "group only / all subgroups".

Step3:
Create a new pseudo service with accept or reject several requests even if they are related to different groups. Handle with rxJS the call to the multiple services and aggregate the results at the end.

For the user it should be transparent that it is one or several services.

Task integration : backend communication

Overview

This issue pertains to the communication between the frontend and the backend to make task integration work with real data.

Depends on : #176 and other aspects around items (result / attempt management, ...).

Subtasks

  • Use actual item URL and get tokens
  • Load current answer / save new answer
  • Save grades

Group composition. 1. simple user list

Motivations

List composition of a group like in https://france-ioi.github.io/algorea-designs/01.Groups_02.Composition

Subtasks

  • In existing composition tab under "Current Composition"
  • For now ignore the filters on top (children/descendants, users/teams/...)
  • As you'll have to handle the filter soon, put your user table in a different component than the more global "Current Composition" component
  • List users of the group (using https://france-ioi.github.io/algorea-devdoc/api/#operation/groupsMembersView)
  • As columns, use:
    • name (i.e., firstname+lastname)
    • login
    • member since
  • no selection box, no actions below

Auth todos

List of todos for authentication and session management:

  • test/setup auto-refresh of token
  • repetition of Authorization: `Bearer ${token}`,
  • if changing token, should cancel ongoing requests

Group administration page: v1 - readonly

In the group "administration" tabs: (based on /design implementation)

  • rename the tab to "Managers"
  • title: "Managers of this group"
  • columns:
    • name (useless to display the column caption (as it is now))
    • level: which can be "read-only", "memberships", or "full", + the blue "bubble" level (from "none", "memberships" and "memberships_and_group" received from backend)
    • "can grant group access": green "check-circle" if true, red "times-circle" if false
    • "can watch members": green "check-circle" if true, red "times-circle" if false
  • content obtained from groupManagerView service
  • don't handle selection / select all for now
  • allow sort by name actually, not possible as there are no column header on name

Bug: "Pending request" not filtered correctly

The "pending requests" shown on a manager's groups seem not to be filtered by group id. As a consequence, the reject/accept request are sent on the wrong group.

Fix this by filtering on the group. Check if the service supports it (https://france-ioi.github.io/algorea-devdoc/api/), if not it should probably be done in the service.

To reproduce, use "devapi" with "token20" you'll see you have the same requests for both groups (while there are only for group 50 in the db), (as a consequence, the requests on group 51 fail)

Item details: children (part 1)

Objective

Display children as shown here.

Details

  • Do a separate component which is only visible for chapters (item.type 'Chapter') and with can_view >= content
  • Add the "To validate this chapter, solve at least all tasks with Validation type " with the same style as designs
  • Use the usual loading/error/ready state for fetching children data (https://france-ioi.github.io/algorea-devdoc/api/#operation/itemChildrenView)
  • just display the "ready" string when the data is loaded, we'll do the display in another issue

Fix router warning

Fix "A router outlet has not been instantiated during routes activation. "

Pending request: add this group only / all subgroups switch, step 2: adapt table display

As it is done in the design branch (http://dev.algorea.org/branch/design/), add to the "pending request" box the switch "group only / all subgroups".

Step2:
This parameter is now supported by the backend (see API) and has to be added in the service.
When "include subgroups" switch is enabled or disabled:

  • redisplay the loading (done in #85) spinner, grey out the switch while processing
  • use the same error/empty behavior when response is received
  • if "including subgroups" is enabled, display an additional column (first) with the group name (group that the user wants to join)

Make sure you do not break any of the current behaviors.

Manager permission change modal

Overview

Allow to change permissions of other managers.

Acceptance criteria

  • if the current user has management permission on the group < 'memberships_and_group', do not display the pencil describe below
  • if the current user hasmanagement permission on the group = memberships_and_group:
    • add a pencil logo on the right column Screenshot 2021-08-13 at 16 15 50
    • when clicking on the pencil open a modal similar to permissions edit dialog but for group managers. Should look like that: Screenshot 2021-08-13 at 16 25 42
    • title: "<group page name>: manager access given to <receiver group/user name>"
    • instead of lorem ipsum: "This panel lets you select what you allow the selected user or group of users to do on the current group and its descendants.
    • do not make the sections "collapsible", they are short enough
    • "Management level"
      • subtitle "The permissions that the user(s) has on this group"
      • "Read-only" "Can list the members"
      • "Membership": "Can manage (add, remove, invite, ...) members.
      • "Full": Can manage members, managers, and change group settings
      • For the left "bubbles", don't put any "checks" or "locks" in the blue bubbles except a "check" in the last one (the largest blue)
    • "Can grant access"
      • no subtitle
      • toggle text: "User(s) can give and revoke members access to some content"
    • "Can watch members"
      • no subtitle
      • toggle text: "User(s) can watch the members' activity on some content "
    • no "can edit personal data" section
    • pressing "Proceed" :
      • calls groupManagerEdit.
      • put a spinner on "Proceed" while processing
      • disable all toggles/buttons (except the "x") while processing
      • if "x" is pressed during processing, response must be handled normally (not cancelled)
      • display a toast on response (error or success) and close the modal
    • "Cancel" or "x" should close the modal, ignoring the changes.
    • the manager table should be refreshed after a change

Group administration page: allow removal

Overview

Allow removal of managers.

Acceptance criteria

In the group manager page:

  • add selection, including a "select all". It should work like in "composition" tab
  • removal button like in "composition" tab (button should be greyed out if not selection)
  • require the current user to have "memberships_and_group" management level on the current group to see this button
  • removal management like in composition tab:
    • UI frozen while fetching,
    • error/success result shown in a toast
    • refresh of data after a change

Beware that for now managers cannot be re-added. You should probably add some using the service directly (in curl) when testing

Group composition page: join by code

In the "composition" tab of the group page (on a route ".../<group_id>/members"):

  • title "Current Composition"
  • add the section "Other ways to add new members to this group" (as done on #/design), only display this section if `group.current_user_can_manage is "memberships" or "memberships_and_group". In this section, only add the "Invitation code" part.
  • replace the on-off toggle by a way to expand/hide the panel. Collapsed by default if code is null.
  • for every button below, while processing, put a spinner in the button and disable all the other button of this join-by-code "component"
  • "code"
    • case 1: there is no code (code attribute in the group info)
      • the current code+refresh field are replace by a (same size) "Generate" blue button.
      • pressing it call groupCodeCreate (with a spinner), the new code is returned by the service. Display the toast with success/failure.
    • case 2: there is a code
    • when a new code is set or removed, you can assume the code_lifetime is not changed and code_expires_at is set to null (no need to refetch)
  • validity:
    • code_lifetime attribute of groups
    • the validation button (blue "V" on the right of the input) is only enabled when the value is different from the "backend" value
    • pressing the validation button (when its value has been changed) calls the groupUpdate service (just providing the code_lifetime in the format "838:59:59").
      • When updated, fetch the group for getting the new code_lifetime and code_expires_at.
      • When updated, display the toast with success/failure.
  • If code_expires_at is not null, display:
    • if > now(): "This code was first used at dd/mm/yy hh:mm and is now disabled", where dd/mm/yy hh:mm is code_expires_at - code_lifetime.
    • otherwise "This code was first used at dd/mm/yy hh:mm and is valid until dd/mm/yy hh:mm",
  • make sure to handle correctly timezone in the input date/time (display time in the browser TZ)
  • no "security", no "Automatically create user account"

Group edition, step 1: empty edit page

Motivations

Be able to edit groups (similarly to items)

Subtasks

  • on group page, when user is allowed to manage "group and memberships". Display the edit button icon in the header. When clicking on it, move to edit page.
  • on the empty edit page, clicking on "cancel" returns on the group page

Item edition. step 5. Children reordering. c: reordering

Motivations

Item edition as shown in https://france-ioi.github.io/algorea-designs/03.Activities_Edit_05.Edit-chapter-content and http://dev.algorea.org/branch/design/.

Subtasks

  • Add reordering to ItemChildrenEditComponent
  • let the user re-order the children
  • on save (! handle the case when the list of children is not loaded yet or in error), save the children so only the item_id and order attributes.
  • if possible only update children if there were a change

Group composition. 3. different kind of groups list

Motivations

List composition of a group like in https://france-ioi.github.io/algorea-designs/01.Groups_02.Composition

Subtasks

  • Add a first filter (probably a specific component) for Groups / Teams/ Users / Sessions as in the design.
  • Groups/Teams/Sessions can probably shared a same component
  • Use service https://france-ioi.github.io/algorea-devdoc/api/#operation/groupChildrenView . For "Groups", filter out users, teams and sessions.
  • Use as columns:
    • name
    • for "Group" only show "type"
    • user count
  • allow sort by name

Task integration : task-frontend communication

Overview

Integrate tasks (and courses) into the frontend. It requires implementing communication between the frontend and the task, and also implementing the backend calls related to items.

This issue only includes tasks directly tied to communication between the frontend and a task : loading, displaying of a task and current answer management. It doesn't include getting actual data (#177), or other actions around tasks (results or attempt management, etc.).

Subtasks

  • Basic frontend-task communication, with mock data and test buttons
    • Make item-task component with iframe
    • Get dependencies (jschannel, task-xd-pr, ...?)
    • task load
    • task views management
    • task answer/state (load/save, from task into memory)
    • task unload
  • Design integration
    • Normal iframe dimensions (iframe height adjusts to the task as is usually done on other platforms)
    • Responsive mode (iframe stays in the visible window)
    • Use proper tabs for the views

This list might not be exhaustive.

Item edition. 2. Update title

Description

Item edition as shown in https://france-ioi.github.io/algorea-designs/03.Activities_Edit_05.Edit-chapter-content and http://dev.algorea.org/branch/design/.

Details

  • On save (from the current content component), update the current title of the group.
  • During the save, block the UI (form) and block the header (use the 'editing-noaction' state for the header).
  • Call the group update service (check API) and display the result in a toast.
  • In case of success, navigate to the item detail page.

Handle correctly unsubscription

Subscriptions to observables which do not have a pre-defined completion (such as services) have to be unsubscribed "by hand", otherwise it stays subscribed for life, which creates a memory leak.

Item details: children (part 2)

Objective

Display children as shown here.

Details

  • First check that you do not need to rework/import other component for the rest. If so, do specific PR for them.
  • To list the children: (if it takes >4h, split it in several PR)
    • only keep those which are of type "Chapter", "Task" or "Course"
    • for the score ring, use "best_score" as grey ring and as main ring the score_computed of the result with the most recent latest_activity_at . If the "validated" state is implemented on the score ring (a green "v" in the center or something similar), use the "validated" of the the result with the most recent latest_activity_at
    • display the child.string.title as title (if not null)
    • display the "lock" icon and text in grey if the user has can_view <= content on the child
    • display the right widget (discovery, validation, ...) depending on the "category" attribute
    • make a link to the item, with the appropriate path and as attempt_id the one from the result with the most recent latest_activity_at .

Handle correctly loading

When loading something, if the user input something else, the website can find itself in a "loaded" state when it is in fact not.

For exemple : you can have a "change" to "B" during the loading of "A", so you should not put "A" as "loaded", but instead wait for "B" to be loaded.

User info when the user is temporary

Motivations

Implement what was defined in the designs: https://france-ioi.github.io/algorea-designs/00.Global_06.Navigation-panel_g.Login-profile

Subtasks

  • Display the login button (on the top right of the menu) indicated in the design. Do not display the button is the user is temp.
  • If the user is temp, do not display the white user zone. Display instead the yellow "connexion" button on the dark background (should be somewhere in the design branch), with the appropriate action.

Group invitations

In group composition tab, from "invite users" as done in "/design":

  • Remove the toggle, it is misleading (there is nothing to disable)
  • While there is no login in the login, disable the "invite" button.
  • While there is > 100 logins, display a message "You cannot invite more than 100 users at once" in red with a bell in front. (no cross to hide the message) And disable the "invite" button.
  • On "invite":
    • call groupInvitationsCreate
    • block "invite" and form field while processing, add spinner to the button
    • clear the previous message under the box if any
  • handle the response, displaying the result under the box (as it is now):
    • if >0 success: display "x user(s) invited successfully" in green with a "check" symbol in front
    • if >0 unchanged: display "x user(s) have not invited as they have been already previously" in blue with a " pi-exclamation-circle" symbol in front
    • if >0 invalid: display "x user(s) have not invited as they are already member of the group " in blue with a " pi-exclamation-circle" symbol in front
    • if >0 not_found: display "x user login(s) not found: <list of logins, coma separated>" in red, with a pi pi-exclamation-triangle in front.
    • if > 0 other states: "x user login(s) could not be invited: <list of logins, coma separated>" in red, with a pi pi-exclamation-triangle in front.
    • in case of not 2xx response, use the classic toast
    • clear the form

Group chapter progress: user version

Motivations

Implement a page which lists the results of all user descendants on a chapter.
Example:

Subtasks

  • Import the table of the design but very simplified just for the need of this issue.
  • Only display "chapter view" tab if the current user is watching a group and the current item is a chapter
  • No filter, no user/team/groups tab
  • No interaction when clicking on a cell
  • Load (in parallel):
  • Display in row headers, the item titles
  • Display in column headers the users' name
  • Display in each cell, matching group_id and item_id, display
    • the score as score ring
    • as background
      • green if validated
      • orange if score > 0
      • red if score == 0 and time_spent > 0
      • white if time_spent == 0
  • no settings (compact mode should be "on" as we do not have more info to display)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.