Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added functionality to create new facility on existing kolibri #11197

Conversation

Jaspreet-singh-1032
Copy link
Contributor

Summary

closes #10826
Added functionality to create a new facility on the existing Kolibri

  • Added a modal to create new facility
  • Implemented backend APIs to create facility
  • screenshots

image

image

image


Testing checklist

  • Contributor has fully tested the PR manually
  • If there are any front-end changes, before/after screenshots are included
  • Critical user journeys are covered by Gherkin stories
  • Critical and brittle code paths are covered by unit tests

PR process

  • PR has the correct target branch and milestone
  • PR has 'needs review' or 'work-in-progress' label
  • If PR is ready for review, a reviewer has been added. (Don't use 'Assignees')
  • If this is an important user-facing change, PR or related issue has a 'changelog' label
  • If this includes an internal dependency change, a link to the diff is provided

Reviewer checklist

  • Automated test coverage is satisfactory
  • PR is fully functional
  • PR has been tested for accessibility regressions
  • External dependency files were updated if necessary (yarn and pip)
  • Documentation is updated
  • Contributor is in AUTHORS.md

@github-actions github-actions bot added DEV: backend Python, databases, networking, filesystem... APP: Device Re: Device App (content import/export, facility-syncing, user permissions, etc.) SIZE: medium labels Sep 5, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Sep 5, 2023

Build Artifacts

export const Presets = Object.freeze({
FORMAL: 'formal',
NONFORMAL: 'nonformal',
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaspreet-singh-1032. There looks to be similar constants in kolibri/plugins/setup_wizard/assets/src/constants.js, so I think its better to use them instead for maintenance purposes!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can always move this to a more central location to eliminate the deep paths(ie ../../../../../)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @akolson, I have made some changes. Have a look and let me know if it needs any other changes.
Thanks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a clean up of this? Looks like Presets has been moved to kolibri/core/assets/src/constants.js so nolonger necessary in here

@github-actions github-actions bot added the APP: Setup Wizard Re: Setup Wizard (facility import, superuser creation, settings, etc.) label Sep 7, 2023
Copy link
Member

@pcenov pcenov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaspreet-singh-1032 and @rtibbles, this is implemented exactly as specified in #10826 however I can see the following potential issues with this implementation:

  1. The user is presented with an option to choose between a non-formal and formal facility however since the rest of the steps from the setup wizard are missing the created facility is actually created with all the facility settings set to true regardless of the option I've selected. Thus the default Settings of a formal facility look like this:

2023-09-12_14-42-17

  1. For the above mentioned reason there is no admin user in the created facility so that user has to be added separately if one wants to be able to import it on another device.
  2. The 'Add facility' button and the 'Create a new learning facility' modal are not yet localized in other languages.

value: 'create_new_facility',
},
];
},
Copy link
Member

@akolson akolson Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think label fields should be translated. Is this a temporal measure? cc @rtibbles

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would also be good to add the value fields as constants in kolibri/plugins/device/assets/src/constants.js as they seem specific to the device plugin

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the label values should be translated strings.

data() {
return {
facilityName: '',
preset: 'nonformal',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to now use the Presets.NONFORMAL here instead of hardcoded nonformal string.

@@ -389,6 +420,13 @@
this.$emit('failure');
});
},
handleSelect(option) {
if (option.value == 'import_facility') {
Copy link
Member

@akolson akolson Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comments on value fields above

Copy link
Member

@akolson akolson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally code looks good, thanks @Jaspreet-singh-1032. There's is just a few clean up tasks to do and we should be good. Its probably good to hold off any further approvals in light of @pcenov's comments.

@rtibbles
Copy link
Member

For @pcenov's points:

  1. We need to make the presets actually do something, otherwise giving this choice to the user is meaningless, so there's a bit of work to do here to ensure the presets are applied and the proper settings are handled.

  2. I think we can stomach not creating an admin during this workflow, as the user creating this facility has to be a superadmin - so they can use the facility tooling to manage the users.

  3. We should be internationalizing all user interface text, as noted by @akolson above as well - it seems this has now been done!

So - to get this merged, I would say we need to address 1.


class Meta:
model = Facility
fields = ("id", "name", "preset")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are taking the preset here, but not doing anything with it.

See here for an example of how the preset data is used in a serializer in order to set the settings appropriately: https://github.com/learningequality/kolibri/blob/release-v0.16.x/kolibri/core/device/serializers.py#L139

This would require adding a create method to this serializer to implement this custom logic.

@pcenov
Copy link
Member

pcenov commented Sep 18, 2023

Hi @Jaspreet-singh-1032 please let me know when this one is ready for another round of manual testing. Thanks!

@Jaspreet-singh-1032
Copy link
Contributor Author

Hi @pcenov, this is ready for testing.

@pcenov pcenov self-requested a review September 19, 2023 08:10
Copy link
Member

@pcenov pcenov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed - the presets for Formal and Non-formal facility are implemented correctly now. Good to go!

Copy link
Member

@akolson akolson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Jaspreet-singh-1032! Please see some additional thoughts here, that I think would be the final piece for the merge. Unless @rtibbles has any other thoughts, we should be good after this.

)
facility.dataset.reset_to_default_settings(validated_data.get("preset"))
return facility

Copy link
Member

@akolson akolson Sep 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jaspreet-singh-1032 thanks for adding the create method. However, here are a few more comments to further make the code more robust;

  • You could set the preset and name fields as variables instead eg.
    • preset = validated_data.get("preset")
  • Then add some validation checks to these variables before proceeding to use them. You can alternatively use the validate method within the serializer class if you like
  • It's also a good idea to wrap the code around a try..catch block just in case any of the transactions fail

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @akolson, I've made the changes you suggested by setting preset and name fields as variables. However, I have not added additional validation to these variables because I believe the data is already being validated at this point. if there are specific scenarios or edge cases where you think further validation is needed, please let me know, and I'll be happy to implement it accordingly. And I have also added the try-catch block.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the name is being validated on the frontend, it's probably good to add this validation on the backend too. But, I could be lacking a bit of context overall so I am happy to proceed with the merge(Changes look good, thanks :)) as long as @rtibbles is happy with the changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default the serializer will do introspection of the Django model, so that should be doing some validation to ensure it doesn't exceed the maximum length of the name attribute, and that it is a string, so I think Django REST Framework magic is probably doing the leg work for us here!

Copy link
Member

@akolson akolson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @Jaspreet-singh-1032!

@@ -621,6 +622,13 @@ def annotate_queryset(self, queryset):
)
)

@decorators.action(methods=["post"], detail=False)
def create_facility(self, request):
serializer = CreateFacilitySerializer(data=request.data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the only thing that this is missing is a permissions check here - we should require that request.user.is_superuser is True otherwise, we should raise a permissions error before doing anything else here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent - yes using the permission classes in the decorator is a very neat way to do this!

Copy link
Member

@akolson akolson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a little blocker here in light of Richards comment on adding a permission check to the serializer. . We should be good for a merge once this check added.

@rtibbles rtibbles dismissed akolson’s stale review September 25, 2023 23:41

Changes addressed!

@rtibbles
Copy link
Member

Build breakage is caused by erroneous merge to develop, not by this PR. Merging! Great work @Jaspreet-singh-1032, this is really nicely done!

@rtibbles rtibbles merged commit 4b7239b into learningequality:develop Sep 25, 2023
33 of 34 checks passed
@Jaspreet-singh-1032
Copy link
Contributor Author

Thanks @pcenov @akolson and @rtibbles for your support during this PR :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
APP: Device Re: Device App (content import/export, facility-syncing, user permissions, etc.) APP: Setup Wizard Re: Setup Wizard (facility import, superuser creation, settings, etc.) DEV: backend Python, databases, networking, filesystem... SIZE: medium
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants