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

Gives indication of user having permission to join the facility not showing the devices that don't have sign up enabled. #10703

Merged
merged 14 commits into from
Jun 9, 2023
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
:key="idx"
v-model="selectedDeviceId"
class="radio-button"
:value="d.id"
:value="canLearnerSignUp(d.id) ? d.id : false"
:label="d.nickname"
:description="d.base_url"
:disabled="formDisabled || !isDeviceAvailable(d.id)"
:disabled="canLearnerSignUp(d.id) || formDisabled || !isDeviceAvailable(d.id)"
/>
<KButton
:key="`forget-${idx}`"
Expand All @@ -65,10 +65,13 @@
:key="d.id"
v-model="selectedDeviceId"
class="radio-button"
:value="d.instance_id"
:value="canLearnerSignUp(d.id) ? d.instance_id : false"
:label="formatNameAndId(d.device_name, d.id)"
:description="formatBaseDevice(d)"
:disabled="formDisabled || fetchFailed || !isDeviceAvailable(d.id)"
:disabled="!canLearnerSignUp(d.id)
|| formDisabled
|| fetchFailed
|| !isDeviceAvailable(d.id)"
/>
</div>
</template>
Expand Down Expand Up @@ -123,8 +126,9 @@

<script>

import { computed } from 'kolibri.lib.vueCompositionApi';
import { useLocalStorage, get } from '@vueuse/core';
import { NetworkLocationResource } from 'kolibri.resources';
import { computed, ref } from 'kolibri.lib.vueCompositionApi';
import { useLocalStorage, get, useMemoize, computedAsync } from '@vueuse/core';
import find from 'lodash/find';
import UiAlert from 'kolibri-design-system/lib/keen/UiAlert';
import commonCoreStrings from 'kolibri.coreVue.mixins.commonCoreStrings';
Expand Down Expand Up @@ -186,6 +190,74 @@
const discoveredDevices = computed(() => get(devices).filter(d => d.dynamic));
const savedDevices = computed(() => get(devices).filter(d => !d.dynamic));

const fetchDeviceFacilities = useMemoize(
async device => {
try {
const { facilities } = await NetworkLocationResource.fetchFacilities(device.id);

return facilities.map(facility => {
return {
id: facility.id,
name: facility.name,
base_url: device.base_url,
address_id: device.id,
learner_can_sign_up: facility.learner_can_sign_up,
learner_can_login_with_no_password: facility.learner_can_login_with_no_password,
kolibri_version: device.kolibri_version,
};
});
} catch (e) {
return [];
}
nucleogenesis marked this conversation as resolved.
Show resolved Hide resolved
},
{
getKey: device => device.id,
}
);

const isLoading = ref(false);
Copy link
Member

Choose a reason for hiding this comment

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

@Wck-iipi

Is it okay to show "There are no devices yet" when there are devices but there are none that can sign up or should I use another string?

I'm not seeing anywhere that this ref's value is being read back. This could be used to conditionally put a <KCircularLoader /> component (which is globally available, no need to import it from anywhere) in place of where either the data or the "no data" message should go?


const availableAddressIds = computed(() =>
get(devices)
.filter(d => d.available)
.map(d => d.id)
);

const availableFacilities = computedAsync(
async () => {
// Extract available devices, and sort to most recently accessed so when we dedupe
// facilities across two+ devices, the most recently connected device's facility is shown
const _devices = get(devices)
.filter(d => get(availableAddressIds).includes(d.id))
.sort((deviceA, deviceB) => deviceA.since_last_accessed - deviceB.since_last_accessed);
const facilitiesFromDevices = await Promise.all(
_devices.map(d => fetchDeviceFacilities(d))
);
const facilities = {};
// Promise.all will resolve with an array of arrays
for (const deviceFacilities of facilitiesFromDevices) {
for (const facility of deviceFacilities) {
// deduplicate the same facility across more than one device
if (!facility[facility.id]) {
facilities[facility.id] = facility;
}
}
}
// Sort alphabetically for predictable ordering
return Object.values(facilities).sort((facilityA, facilityB) => {
if (facilityA.name < facilityB.name) {
return -1;
}
if (facilityA.name > facilityB.name) {
return 1;
}
return 0;
});
},
[],
isLoading
);

return {
// useDevices
devices,
Expand All @@ -205,6 +277,7 @@
discoveredDevices,
savedDevices,
storageDeviceId,
availableFacilities,
};
},
props: {
Expand Down Expand Up @@ -356,6 +429,14 @@
this.$emit('removed_address');
});
},
canLearnerSignUp(id) {
for (const facility of this.availableFacilities) {
if (facility.address_id === id) {
return facility.learner_can_sign_up;
}
}
return false;
},
Wck-iipi marked this conversation as resolved.
Show resolved Hide resolved
},
$trs: {
deletingFailedText: {
Expand Down