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

Max quota follow up #8571

Merged
merged 4 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog/unreleased/enhnacement-respect-max-quota
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ Enhancement: Respect max quota
We've updated the quota-select component, so that values higher than max quota set on the server side won't be shown.

https://github.com/owncloud/web/pull/8489
https://github.com/owncloud/web/pull/8571
https://github.com/owncloud/web/issues/8490
https://github.com/owncloud/web/issues/8536
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export default defineComponent({
const isLoginInputDisabled = computed(() => currentUser.uuid === (props.user as User).id)
return {
maxQaxQuota: useCapabilitySpacesMaxQuota(),
maxQuota: useCapabilitySpacesMaxQuota(),
isLoginInputDisabled,
editUser,
formData,
Expand Down
82 changes: 41 additions & 41 deletions packages/web-pkg/src/components/QuotaSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,15 @@
:label="title"
@update:model-value="onUpdate"
>
<template #selected-option="{ displayValue, displayUnit }">
<span>{{ displayValue }}</span>
<span v-if="displayUnit" class="oc-ml-s">{{ displayUnit }}</span>
<template #selected-option="{ displayValue }">
<span v-text="displayValue" />
</template>
<template #search="{ attributes, events }">
<input class="vs__search" v-bind="attributes" v-on="events" />
</template>
<template #option="{ displayValue, displayUnit, error }">
<template #option="{ displayValue, error }">
<div class="oc-flex oc-flex-between">
<div>{{ displayValue }}</div>
<div v-if="displayUnit">{{ displayUnit }}</div>
<span v-text="displayValue" />
</div>
<div v-if="error" class="oc-text-input-danger">{{ error }}</div>
</template>
Expand All @@ -36,6 +34,8 @@
</template>

<script lang="ts">
import { formatFileSize } from 'web-pkg'

export default {
name: 'QuotaSelect',
props: {
Expand All @@ -60,41 +60,37 @@ export default {
}
},
computed: {
quotaLimit() {
return this.maxQuota || 1e15
},
DEFAULT_OPTIONS() {
return [
{
displayValue: '1',
displayUnit: 'GB',
value: Math.pow(10, 9)
value: Math.pow(10, 9),
displayValue: this.getFormattedFileSize(Math.pow(10, 9))
},
{
displayValue: '2',
displayUnit: 'GB',
value: 2 * Math.pow(10, 9)
value: 2 * Math.pow(10, 9),
displayValue: this.getFormattedFileSize(2 * Math.pow(10, 9))
},
{
displayValue: '5',
displayUnit: 'GB',
value: 5 * Math.pow(10, 9)
value: 5 * Math.pow(10, 9),
displayValue: this.getFormattedFileSize(5 * Math.pow(10, 9))
},
{
displayValue: '10',
displayUnit: 'GB',
value: 10 * Math.pow(10, 9)
value: 10 * Math.pow(10, 9),
displayValue: this.getFormattedFileSize(10 * Math.pow(10, 9))
},
{
displayValue: '50',
displayUnit: 'GB',
value: 50 * Math.pow(10, 9)
value: 50 * Math.pow(10, 9),
displayValue: this.getFormattedFileSize(50 * Math.pow(10, 9))
},
{
displayValue: '100',
displayUnit: 'GB',
value: 100 * Math.pow(10, 9)
value: 100 * Math.pow(10, 9),
displayValue: this.getFormattedFileSize(100 * Math.pow(10, 9))
},
{
displayValue: this.$gettext('No restriction'),
displayUnit: '',
value: 0
}
]
Expand All @@ -120,34 +116,38 @@ export default {
optionSelectable(option) {
return option.selectable !== false
},
isValueValidNumber(value) {
const optionIsNumberRegex = /^[0-9]\d*(([.,])\d+)?$/g
return optionIsNumberRegex.test(value) && value > 0
},
createOption(option) {
option = option.replace(',', '.')
const optionIsNumberRegex = /^[0-9]\d*(([.,])\d+)?$/g
if (option === '0' || !optionIsNumberRegex.test(option)) {

if (!this.isValueValidNumber(option)) {
return {
displayValue: option,
value: option,
error: this.$gettext('Please enter only numbers'),
selectable: false
}
}
const value = parseFloat(option) * Math.pow(10, 9)
const displayValue = parseFloat(option).toFixed(2).replace('.00', '')
if (this.maxQuota && value > this.maxQuota) {

if (value > this.quotaLimit) {
return {
value,
displayValue,
displayUnit: 'GB',
error: this.$gettext('Please enter a value equal or less than %{ maxQuota } GB', {
maxQuota: this.maxQuota * Math.pow(10, -9)
displayValue: this.getFormattedFileSize(value),
error: this.$gettext('Please enter a value equal to or less than %{ quotaLimit }', {
quotaLimit: this.getFormattedFileSize(this.quotaLimit)
}),

selectable: false
}
}

return {
value,
displayValue,
displayUnit: 'GB'
displayValue: this.getFormattedFileSize(value)
}
},
setOptions() {
Expand All @@ -169,13 +169,9 @@ export default {

if (!selectedQuotaInOptions) {
availableOptions.push({
displayValue: (this.totalQuota * Math.pow(10, -9))
.toFixed(2)
.toString()
.replace('.00', ''),
displayUnit: 'GB',
displayValue: this.getFormattedFileSize(this.totalQuota),
value: this.totalQuota,
selectable: !(this.maxQuota && this.totalQuota > this.maxQuota)
selectable: this.totalQuota <= this.quotaLimit
})
}

Expand All @@ -185,6 +181,10 @@ export default {
...availableOptions.filter((o) => !o.value)
]
this.options = availableOptions
},
getFormattedFileSize(value) {
const formattedFilesize = formatFileSize(value, this.$language.current)
return !this.isValueValidNumber(value) ? value : formattedFilesize
}
}
}
Expand Down
27 changes: 9 additions & 18 deletions packages/web-pkg/tests/unit/components/QuotaSelect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@ describe('QuotaSelect', () => {
expect((wrapper.vm as any).optionSelectable({ selectable: true })).toBeTruthy()
expect((wrapper.vm as any).optionSelectable({})).toBeTruthy()
})
it('should return true while option selectable property is false', () => {
it('should return false while option selectable property is false', () => {
const { wrapper } = getWrapper()
expect((wrapper.vm as any).optionSelectable({ unlimited: true })).toBeTruthy()
expect((wrapper.vm as any).optionSelectable({ selectable: false })).toBeFalsy()
})
})
describe('method "createOption"', () => {
it('should create option', () => {
const { wrapper } = getWrapper()
expect((wrapper.vm as any).createOption('3')).toEqual({
displayValue: '3',
displayUnit: 'GB',
displayValue: '3 GB',
value: 3 * Math.pow(10, 9)
})
})
Expand Down Expand Up @@ -48,8 +47,7 @@ describe('QuotaSelect', () => {
expect.arrayContaining([
...(wrapper.vm as any).DEFAULT_OPTIONS,
{
displayValue: '45',
displayUnit: 'GB',
displayValue: '45 GB',
value: 45 * Math.pow(10, 9),
selectable: true
}
Expand All @@ -65,13 +63,11 @@ describe('QuotaSelect', () => {
expect((wrapper.vm as any).options).toEqual(
expect.arrayContaining([
{
displayValue: '1',
displayUnit: 'GB',
displayValue: '1 GB',
value: Math.pow(10, 9)
},
{
displayValue: '2',
displayUnit: 'GB',
displayValue: '2 GB',
value: 2 * Math.pow(10, 9)
}
])
Expand All @@ -86,18 +82,15 @@ describe('QuotaSelect', () => {
expect((wrapper.vm as any).options).toEqual(
expect.arrayContaining([
{
displayValue: '1',
displayUnit: 'GB',
displayValue: '1 GB',
value: Math.pow(10, 9)
},
{
displayValue: '2',
displayUnit: 'GB',
displayValue: '2 GB',
value: 2 * Math.pow(10, 9)
},
{
displayValue: '100',
displayUnit: 'GB',
displayValue: '100 GB',
value: 100 * Math.pow(10, 9),
selectable: false
}
Expand All @@ -113,8 +106,6 @@ function getWrapper({ totalQuota = 10 * Math.pow(10, 9), maxQuota = 0 } = {}) {
data: () => {
return {
selectedOption: {
displayValue: '10',
displayUnit: 'GB',
value: 10 * Math.pow(10, 9)
},
options: []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const changeSpaceQuota = async (args: {
const searchLocator = await page.locator(spacesQuotaSearchField)
await searchLocator.fill(value)
await page.waitForSelector(selectedQuotaValueField)
await page.locator(util.format(quotaValueDropDown, value)).click()
await page.locator(util.format(quotaValueDropDown, `${value} GB`)).click()

await Promise.all([
page.waitForResponse(
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/support/objects/app-admin-settings/users/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const changeQuota = async (args: {
await page.locator(util.format(userIdSelector, uuid)).click()
await page.locator(`.context-menu`).locator(editActionBtn).click()
await page.locator(quotaInput).fill(value)
await page.locator(util.format(quotaValueDropDown, value)).click()
await page.locator(util.format(quotaValueDropDown, `${value} GB`)).click()

await Promise.all([
page.waitForResponse(
Expand Down Expand Up @@ -83,7 +83,7 @@ export const changeQuotaUsingBatchAction = async (args: {
const { page, value } = args
await page.locator(editQuotaBtn).click()
await page.locator(quotaInputBatchAction).fill(value)
await page.locator(util.format(quotaValueDropDown, value)).click()
await page.locator(util.format(quotaValueDropDown, `${value} GB`)).click()

await Promise.all([
page.waitForResponse((resp) => resp.status() === 200 && resp.request().method() === 'PATCH'),
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/support/objects/app-files/spaces/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export const changeQuota = async (args: {
const searchLocator = await page.locator(spacesQuotaSearchField)
await searchLocator.fill(value)
await page.waitForSelector(selectedQuotaValueField)
await page.locator(util.format(quotaValueDropDown, value)).click()
await page.locator(util.format(quotaValueDropDown, `${value} GB`)).click()

await Promise.all([
page.waitForResponse(
Expand Down