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

[full-ci] Move language selection to the account page and kill settings app #8294

Merged
merged 6 commits into from
Jan 24, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Move language selection to user account page

The language selection has been moved from the settings app to the personal account page.
The settings app has been removed from the default configs because we don't need it currently.

https://github.com/owncloud/web/pull/8294
6 changes: 0 additions & 6 deletions config/config.json.sample-ocis
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@
"external",
"admin-settings"
],
"external_apps": [
{
"id": "settings",
"path": "https://localhost:9200/settings.js"
}
],
"options" : {
"previewFileMimeTypes" : [
"image/gif",
Expand Down
5 changes: 5 additions & 0 deletions config/vite_oc10/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
"authUrl": "http://host.docker.internal:8080/index.php/apps/oauth2/authorize",
"logoutUrl": "http://host.docker.internal:8080/index.php/logout"
},
"options": {
"accountEditLink": {
"href": "http://host.docker.internal:8080/index.php/settings/personal"
}
},
"apps": [
"files",
"text-editor",
Expand Down
4 changes: 0 additions & 4 deletions config/vite_ocis/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@
"config": {
"mimeTypes": ["image/tiff","image/bmp","image/x-ms-bmp"]
}
},
{
"id": "settings",
"path": "/settings.js"
}
]
}
10 changes: 0 additions & 10 deletions dev/docker/oc10.web.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,6 @@
},
"icon": "swap-box",
"url": "http://host.docker.internal:8080/index.php/apps/files"
},
{
"icon": "settings-4",
"menu": "user",
"target": "_self",
"title": {
"de": "Einstellungen",
"en": "Settings"
},
"url": "http://host.docker.internal:8080/index.php/settings/personal"
}
]
}
4 changes: 0 additions & 4 deletions dev/docker/ocis.web.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@
"mimeTypes": ["image/tiff","image/bmp","image/x-ms-bmp"]
}
},
{
"id": "settings",
"path": "/settings.js"
},
{
"id": "draw-io",
"path": "web-app-draw-io",
Expand Down
2 changes: 2 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ substring of a value of the authenticated user. Examples are `/Shares`, `/{{.Id}
- `options.disablePreviews` Set this option to `true` to disable previews in all the different file listing views. The only list view that is not affected
by this is the trash bin, as that doesn't allow showing previews at all.
- `options.previewFileMimeTypes` Specifies which mimeTypes will be previewed in the ui. For example to only preview jpg and text files set this option to `["image/jpeg", "text/plain"]`.
- `options.accountEditLink` This accepts an object with the following optional fields to have a link on the account page:
- `options.accountEditLink.href` Set a different target URL for the edit link. Make sure to prepend it with `http(s)://`.
- `options.disableFeedbackLink` Set this option to `true` to disable the feedback link in the topbar. Keeping it enabled (value `false` or absence of the option)
allows ownCloud to get feedback from your user base through a dedicated survey website.
- `options.feedbackLink` This accepts an object with the following optional fields to customize the feedback link in the topbar:
Expand Down
20 changes: 20 additions & 0 deletions packages/web-integration-oc10/lib/Controller/ConfigController.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public function getConfig(): JSONResponse {
$configContent = \file_get_contents($configFile);
$configAssoc = \json_decode($configContent, true);
$extendedConfig = $this->addOC10AppsToConfig($configAssoc);
$extendedConfig = $this->addAccountEditLinkToConfig($extendedConfig);
$response = new JSONResponse($extendedConfig);
$response->addHeader('Cache-Control', 'max-age=0, no-cache, no-store, must-revalidate');
$response->addHeader('Pragma', 'no-cache');
Expand Down Expand Up @@ -124,4 +125,23 @@ private function addOC10AppsToConfig(array $config): array {
$config['applications'] = $apps;
return $config;
}

/**
* Add an account edit link to the config.
*
* @param array $config
* @return array
*/
private function addAccountEditLinkToConfig(array $config): array {
$options = $config['options'] ?? [];
if (isset($options['accountEditLink'])) {
return $config;
}
$serverUrl = $this->request->getServerProtocol() . '://' . $this->request->getServerHost();
$options['accountEditLink'] = [
Copy link
Contributor

Choose a reason for hiding this comment

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

This should only be done if the config.json loaded from disk didn't specify it on its own. I.e. if acountEditLink already exists you can return early.

Copy link
Contributor

@kulmann kulmann Jan 23, 2023

Choose a reason for hiding this comment

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

see 36cc027

'href' => $serverUrl . '/index.php/settings/personal'
];
$config['options'] = $options;
return $config;
}
}
183 changes: 137 additions & 46 deletions packages/web-runtime/src/pages/account.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,16 @@
<span v-text="$gettext('Change Password')" />
</oc-button>
<oc-button
v-if="editUrl"
v-if="accountEditLink"
variation="primary"
type="a"
:href="editUrl"
:href="accountEditLink.href"
target="_blank"
data-testid="account-page-edit-url-btn"
>
<oc-icon name="edit" />
<span v-text="$gettext('Edit')" />
</oc-button>
<oc-button
v-else-if="editRoute"
variation="primary"
type="router-link"
:to="editRoute"
data-testid="account-page-edit-route-btn"
>
<oc-icon name="edit" />
<span v-text="$gettext('Edit')" />
</oc-button>
</div>
</div>
<h2 v-translate class="oc-text-bold oc-mb">Account Information</h2>
Expand Down Expand Up @@ -75,26 +66,154 @@
>
</dd>
</div>
<div v-if="isLanguageSupported" class="account-page-info-language oc-mb oc-width-1-2@s">
<dt v-translate class="oc-text-normal oc-text-muted">Language</dt>
<dd data-testid="language">
<oc-select
v-if="languageOptions"
:model-value="selectedLanguageOption"
:clearable="false"
:options="languageOptions"
@update:modelValue="updateSelectedLanguage"
/>
</dd>
</div>
</dl>
</main>
</template>

<script lang="ts">
import { mapActions, mapGetters } from 'vuex'
import { mapActions } from 'vuex'
import EditPasswordModal from '../components/EditPasswordModal.vue'
import { defineComponent } from 'vue'
import { useGraphClient } from 'web-pkg/src/composables'
import { urlJoin } from 'web-client/src/utils'
import { configurationManager } from 'web-pkg/src/configuration'
import { computed, defineComponent, onMounted, unref } from 'vue'
import {
useAccessToken,
useCapabilitySpacesEnabled,
useGraphClient,
useStore
} from 'web-pkg/src/composables'
import { useTask } from 'vue-concurrency'
import axios from 'axios'
import { v4 as uuidV4 } from 'uuid'

export default defineComponent({
name: 'Personal',
components: {
EditPasswordModal
},
setup() {
const store = useStore()
const accessToken = useAccessToken({ store })

// FIXME: Use graph capability when we have it
const isLanguageSupported = useCapabilitySpacesEnabled()
const isChangePasswordEnabled = useCapabilitySpacesEnabled()
const user = computed(() => {
return store.getters.user
})

const loadAccountBundleTask = useTask(function* () {
try {
const {
data: { bundles }
} = yield axios.post(
'/api/v0/settings/bundles-list',
{},
{
headers: {
authorization: `Bearer ${unref(accessToken)}`,
'X-Request-ID': uuidV4()
}
}
)
return bundles.find((b) => b.extension === 'ocis-accounts')
} catch (e) {
console.error(e)
return []
}
}).restartable()

const accountSettingIdentifier = {
extension: 'ocis-accounts',
bundle: 'profile',
setting: 'language'
}
const languageSetting = computed(() => {
return store.getters.getSettingsValue(accountSettingIdentifier)
})
const languageOptions = computed(() => {
const languageOptions = loadAccountBundleTask.last?.value?.settings.find(
(s) => s.name === 'language'
)?.singleChoiceValue.options
return languageOptions?.map((l) => ({
label: l.displayValue,
value: l.value.stringValue,
default: l.default
}))
})
const selectedLanguageOption = computed(() => {
const current = unref(languageSetting)?.listValue.values[0].stringValue
if (!current) {
return unref(languageOptions).find((o) => o.default)
}
return unref(languageOptions).find((o) => o.value === current)
})
const updateSelectedLanguage = (option) => {
const bundle = loadAccountBundleTask.last?.value
const value = {
bundleId: bundle?.id,
settingId: bundle?.settings.find((s) => s.name === 'language')?.id,
resource: { type: 'TYPE_USER' },
listValue: { values: [{ stringValue: option.value }] },
...(unref(languageSetting) && { id: unref(languageSetting).id })
}

axios.post(
'/api/v0/settings/values-save',
{ value: { ...value, accountUuid: 'me' } },
{
headers: {
authorization: `Bearer ${unref(accessToken)}`,
'X-Request-ID': uuidV4()
}
}
)

store.commit('SET_SETTINGS_VALUE', {
identifier: accountSettingIdentifier,
value
})
}
const accountEditLink = computed(() => {
return store.getters.configuration?.options?.accountEditLink
})

const groupNames = computed(() => {
if (unref(useCapabilitySpacesEnabled())) {
return unref(user)
.groups.map((group) => group.displayName)
.join(', ')
}

return unref(user).groups.join(', ')
})

onMounted(() => {
if (unref(isLanguageSupported)) {
loadAccountBundleTask.perform()
}
})

return {
...useGraphClient()
...useGraphClient(),
languageOptions,
selectedLanguageOption,
updateSelectedLanguage,
accountEditLink,
isChangePasswordEnabled,
isLanguageSupported,
groupNames,
user
}
},
data() {
Expand All @@ -103,36 +222,8 @@ export default defineComponent({
}
},
computed: {
...mapGetters(['user', 'getNavItemsByExtension', 'apps', 'capabilities']),
isAccountEditingEnabled() {
return !this.apps.settings
},
isChangePasswordEnabled() {
// FIXME: spaces capability is not correct here, we need to retrieve an appropriate capability
return this.capabilities.spaces?.enabled
},
pageTitle() {
return this.$gettext(this.$route.meta.title)
},
editUrl() {
if (!this.isAccountEditingEnabled) {
return null
}
return urlJoin(configurationManager.serverUrl, '/index.php/settings/personal')
},
editRoute() {
const navItems = this.getNavItemsByExtension('settings')
if (navItems.length > 0) {
return navItems[0].route || {}
}
return null
},
groupNames() {
if (this.capabilities.spaces?.enabled) {
return this.user.groups.map((group) => group.displayName).join(', ')
}

return this.user.groups.join(', ')
}
},
methods: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ exports[`account page account information displays basic user information 1`] =
<span data-current-language="en" data-msgid="You are not part of any group">You are not part of any group</span>
</dd>
</div>
<!--v-if-->
</dl>
`;

Expand All @@ -32,6 +33,4 @@ exports[`account page account information group membership displays group names
</dd>
`;

exports[`account page header section edit buttons edit route button should be displayed if running with ocis and has navItems 1`] = `<oc-button-stub to="some-route" type="router-link" variation="primary"></oc-button-stub>`;

exports[`account page header section edit buttons edit url button should be displayed if not running with ocis 1`] = `<oc-button-stub href="/index.php/settings/personal" type="a" variation="primary"></oc-button-stub>`;
exports[`account page header section edit url button should be displayed if defined via config 1`] = `<oc-button-stub href="/" target="_blank" type="a" variation="primary"></oc-button-stub>`;
Loading