Skip to content

Commit

Permalink
Merge pull request #907 from nextcloud-libraries/backport/chore/clean…
Browse files Browse the repository at this point in the history
…up-filepicker-fix-types

fix(FilePicker): Fix exported typings and cleanup file picker files
  • Loading branch information
susnux committed Aug 17, 2023
2 parents 2390ecf + fcefe62 commit ab8808c
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 40 deletions.
8 changes: 4 additions & 4 deletions l10n/messages.pot
Expand Up @@ -30,11 +30,11 @@ msgstr ""
msgid "Copy"
msgstr ""

#: lib/components/FilePicker/FilePicker.vue:214
#: lib/components/FilePicker/FilePicker.vue:210
msgid "Could not create the new folder"
msgstr ""

#: lib/components/FilePicker/FilePicker.vue:137
#: lib/components/FilePicker/FilePicker.vue:133
#: lib/components/FilePicker/FilePickerNavigation.vue:65
msgid "Favorites"
msgstr ""
Expand All @@ -55,7 +55,7 @@ msgstr ""
msgid "Name"
msgstr ""

#: lib/components/FilePicker/FilePicker.vue:137
#: lib/components/FilePicker/FilePicker.vue:133
#: lib/components/FilePicker/FilePickerNavigation.vue:61
msgid "Recent"
msgstr ""
Expand All @@ -78,7 +78,7 @@ msgstr ""
msgid "Size"
msgstr ""

#: lib/toast.ts:228
#: lib/toast.ts:229
msgid "Undo"
msgstr ""

Expand Down
18 changes: 10 additions & 8 deletions lib/components/DialogButton.vue
Expand Up @@ -8,17 +8,19 @@
</template>

<script setup lang="ts">
import type { AsyncComponent, Component } from 'vue'
import type { IDialogButton } from './types'
import { NcButton } from '@nextcloud/vue'
export interface IDialogButton {
label: string,
icon?: Component | AsyncComponent,
callback: () => void,
type?: 'primary' | 'secondary' | 'error' | 'warning' | 'success'
}
// with vue 3.3:
// const props = defineProps<IDialogButton>()
const props = defineProps<{
callback: IDialogButton['callback'],
label: IDialogButton['label'],
icon: IDialogButton['icon'],
type: IDialogButton['type'],
}>()
const props = defineProps<IDialogButton>()
const emit = defineEmits<(e: 'click', event: MouseEvent) => void>()
const handleClick = (e: MouseEvent) => {
Expand Down
2 changes: 1 addition & 1 deletion lib/components/FilePicker/FileList.vue
Expand Up @@ -66,7 +66,7 @@ import type { Node } from '@nextcloud/files'
import { getCanonicalLocale } from '@nextcloud/l10n'
import { NcButton, NcCheckboxRadioSwitch } from '@nextcloud/vue'
import { join } from 'path'
import { t } from '../../l10n'
import { t } from '../../utils/l10n'
import { computed, ref, type Ref } from 'vue'
import IconSortAscending from 'vue-material-design-icons/MenuDown.vue'
Expand Down
2 changes: 1 addition & 1 deletion lib/components/FilePicker/FileListRow.vue
Expand Up @@ -27,7 +27,7 @@
import { type Node, formatFileSize } from '@nextcloud/files'
import { NcCheckboxRadioSwitch } from '@nextcloud/vue'
import { computed } from 'vue'
import { t } from '../../l10n'
import { t } from '../../utils/l10n'
import NcDatetime from './NcDatetime.vue'
Expand Down
10 changes: 3 additions & 7 deletions lib/components/FilePicker/FilePicker.vue
Expand Up @@ -28,25 +28,21 @@
</template>

<script setup lang="ts">
import type { IDialogButton } from '../DialogButton.vue'
import type { IFilePickerButton } from '../types'
import { davRootPath, type Node } from '@nextcloud/files'
import DialogBase from '../DialogBase.vue'
import FileList from './FileList.vue'
import FilePickerBreadcrumbs from './FilePickerBreadcrumbs.vue'
import FilePickerNavigation from './FilePickerNavigation.vue'
import { t } from '../../l10n'
import { t } from '../../utils/l10n'
import { join } from 'path'
import { computed, onMounted, ref, toRef } from 'vue'
import { useDAVFiles } from '../../usables/dav'
import { useMimeFilter } from '../../usables/mime'
import { showError } from '../../toast'
export interface IFilePickerButton extends Omit<IDialogButton, 'callback'> {
callback: (nodes: Node[]) => void
}
const props = withDefaults(defineProps<{
/** Buttons to be displayed */
buttons: IFilePickerButton[]
Expand All @@ -69,7 +65,7 @@ const props = withDefaults(defineProps<{
/**
* Custom filter function used to filter pickable files
*/
filterFn?: (node: Node) => boolean
filterFn?: (node: Node) => boolean
/**
* List of allowed mime types
Expand Down
2 changes: 1 addition & 1 deletion lib/components/FilePicker/FilePickerBreadcrumbs.vue
Expand Up @@ -48,7 +48,7 @@ import IconPlus from 'vue-material-design-icons/Plus.vue'
import { NcActions, NcActionInput, NcBreadcrumbs, NcBreadcrumb } from '@nextcloud/vue'
import { computed, ref } from 'vue'
import { t } from '../../l10n'
import { t } from '../../utils/l10n'
const props = defineProps<{
/** Current path to display */
Expand Down
2 changes: 1 addition & 1 deletion lib/components/FilePicker/FilePickerNavigation.vue
Expand Up @@ -48,7 +48,7 @@ import IconMagnify from 'vue-material-design-icons/Magnify.vue'
import IconStar from 'vue-material-design-icons/Star.vue'
import { NcButton, NcSelect, NcTextField } from '@nextcloud/vue'
import { t } from '../../l10n'
import { t } from '../../utils/l10n'
import { computed } from 'vue'
import { Fragment } from 'vue-frag'
Expand Down
2 changes: 1 addition & 1 deletion lib/components/FilePicker/NcDatetime.vue
Expand Up @@ -27,7 +27,7 @@

<script lang="ts">
import { getCanonicalLocale } from '@nextcloud/l10n'
import { t } from '../../l10n.js'
import { t } from '../../utils/l10n.js'
import { defineComponent, type PropType } from 'vue'
const FEW_SECONDS_AGO = {
Expand Down
29 changes: 29 additions & 0 deletions lib/components/FilePicker/index.ts
@@ -0,0 +1,29 @@
/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

import { defineAsyncComponent, type AsyncComponent } from 'vue'
import type { DefaultComputed, DefaultData, DefaultMethods } from 'vue/types/options.js'

export type IFilePicker = typeof import('./FilePicker.vue').default

// Async import for module splitting (treeshaking)
export const FilePickerVue = defineAsyncComponent(() => import('./FilePicker.vue')) as AsyncComponent<DefaultData<never>, DefaultMethods<never>, DefaultComputed, IFilePicker['props']>
35 changes: 35 additions & 0 deletions lib/components/types.ts
@@ -0,0 +1,35 @@
/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

import type { Node } from '@nextcloud/files'
import type { AsyncComponent, Component } from 'vue'

export interface IDialogButton {
label: string,
icon?: Component | AsyncComponent,
callback: () => void,
type?: 'primary' | 'secondary' | 'error' | 'warning' | 'success'
}

export interface IFilePickerButton extends Omit<IDialogButton, 'callback'> {
callback: (nodes: Node[]) => void
}
5 changes: 2 additions & 3 deletions lib/index.ts
@@ -1,8 +1,7 @@
import { defineAsyncComponent } from 'vue'

export { FilePicker, FilePickerType, FilePickerBuilder, getFilePickerBuilder } from './filepicker.js'
export { TOAST_UNDO_TIMEOUT, TOAST_DEFAULT_TIMEOUT, TOAST_PERMANENT_TIMEOUT } from './toast.js'
export { TOAST_ARIA_LIVE_OFF, TOAST_ARIA_LIVE_POLITE, TOAST_ARIA_LIVE_ASSERTIVE } from './toast.js'
export { showMessage, showSuccess, showWarning, showInfo, showError, showUndo } from './toast.js'

export const FilePickerVue = defineAsyncComponent(() => import('./components/FilePicker/FilePicker.vue'))
export { spawnDialog } from './utils/dialogs.js'
export { FilePickerVue } from './components/FilePicker/index.js'
11 changes: 0 additions & 11 deletions lib/l10n.ts

This file was deleted.

2 changes: 1 addition & 1 deletion lib/legacy.ts
Expand Up @@ -29,7 +29,7 @@ import type { IFilePickerButton } from './components/FilePicker/FilePicker.vue'
import type { Node } from '@nextcloud/files'
import type { AsyncComponent, Component } from 'vue'

import { t } from './l10n'
import { t } from './utils/l10n'
import { FilePickerVue, FilePickerType } from '.'
import DialogBase from './components/DialogBase.vue'
import Vue from 'vue'
Expand Down
3 changes: 2 additions & 1 deletion lib/toast.ts
Expand Up @@ -23,11 +23,12 @@
///<reference types="toastify-js" />

import Toastify from 'toastify-js'
import { t } from './l10n.js'
import { t } from './utils/l10n.js'

import '../styles/toast.scss'

class ToastType {

static readonly ERROR = 'toast-error';
static readonly WARNING = 'toast-warning';
static readonly INFO = 'toast-info';
Expand Down
53 changes: 53 additions & 0 deletions lib/utils/dialogs.ts
@@ -0,0 +1,53 @@
/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import type { AsyncComponent, Component } from 'vue'

import Vue from 'vue'

/**
* Helper to spawn a Vue dialog without having to mount it from a component
*
* @param dialog The dialog component to spawn
* @param props Properties to pass to the dialog
* @param onClose Callback when the dialog is closed
*/
export const spawnDialog = (dialog: Component | AsyncComponent, props: any, onClose: () => void = () => {}) => {
const el = document.createElement('div')

const container: HTMLElement = document.querySelector(props?.container) || document.body
container.appendChild(el)

const vue = new Vue({
el,
name: 'VueDialogHelper',
render: (h) =>
h(dialog, {
props,
on: {
close: () => {
onClose()
vue.$destroy()
},
},
}),
})
}
34 changes: 34 additions & 0 deletions lib/utils/l10n.ts
@@ -0,0 +1,34 @@
/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

import { getGettextBuilder } from '@nextcloud/l10n/gettext'

const gtBuilder = getGettextBuilder()
.detectLocale()

__TRANSLATIONS__.map(data => gtBuilder.addTranslation(data.locale, data.json))

const gt = gtBuilder.build()

export const n = gt.ngettext.bind(gt) as typeof gt.ngettext
export const t = gt.gettext.bind(gt) as typeof gt.gettext

0 comments on commit ab8808c

Please sign in to comment.