Skip to content

Commit

Permalink
wip: Move KAction to action folder #850
Browse files Browse the repository at this point in the history
  • Loading branch information
cnouguier committed May 4, 2024
1 parent 6e766ac commit 1ccfc33
Show file tree
Hide file tree
Showing 27 changed files with 339 additions and 30 deletions.
2 changes: 1 addition & 1 deletion core/client/components/KBlock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
</template>

<script>
import KAction from './KAction.vue'
import KAction from './action/KAction.vue'
export default {
components: {
Expand Down
2 changes: 1 addition & 1 deletion core/client/components/KContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function getComponents (content, mode) {
// Then create component objects
_.forEach(components, component => {
// Get the component and add the required props
component.name = _.get(component, 'component', 'KAction')
component.name = _.get(component, 'component', 'action/KAction')
component.uid = uid()
processedComponents.push(component)
})
Expand Down
2 changes: 1 addition & 1 deletion core/client/components/KSponsor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@
</template>

<script setup>
import KAction from './KAction.vue'
import KAction from './action/KAction.vue'
</script>
2 changes: 1 addition & 1 deletion core/client/components/account/KDeleteAccountManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import _ from 'lodash'
import { useRouter } from 'vue-router'
import { Dialog } from 'quasar'
import { Store, i18n, api } from '../..'
import KAction from '../KAction.vue'
import KAction from '../action/KAction.vue'
// Data
const router = useRouter()
Expand Down
2 changes: 1 addition & 1 deletion core/client/components/account/KPasswordManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { ref } from 'vue'
import { Notify } from 'quasar'
import { Store, i18n, utils } from '../..'
import KForm from '../form/KForm.vue'
import KAction from '../KAction.vue'
import KAction from '../action/KAction.vue'
// Data
const formRef = ref(null)
Expand Down
294 changes: 294 additions & 0 deletions core/client/components/action/KAction.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
<template>
<!--
Button renderer
-->
<q-btn v-if="renderer === 'button'"
:id="id"
no-caps
no-wrap
:color="computedColor"
:icon="!iconRight ? computedIcon : undefined"
:icon-right="iconRight ? computedIcon : undefined"
:size="size"
flat
:round="label === null"
:rounded="label !== null"
:stack="stack"
:dense="dense"
:disable="computedDisabled"
v-close-popup="closePopup"
@click="onClicked">
<!-- label -->
<div v-if="computedLabel" :class="{ 'ellipsis q-pr-md': iconRight, 'ellipsis q-pl-md': !iconRight }">
{{ computedLabel }}
</div>
<!-- tooltip -->
<q-tooltip v-if="computedTooltip">
{{ computedTooltip }}
</q-tooltip>
<!-- badge -->
<q-badge v-if="badge" v-bind="badge" :label="computedBadgeLabel">
<q-icon v-if="badge.icon" v-bind="badge.icon" />
</q-badge>
<!-- extra content -->
<slot>
</slot>
</q-btn>
<!--
Form button renderer
-->
<q-btn v-else-if="renderer === 'form-button'"
:id="id"
no-wrap
color="primary"
:outline="outline"
:size="size"
:disable="computedDisabled"
:loading="loading"
v-close-popup="closePopup"
@click="onClicked">
<div class="ellipsis">
{{ computedLabel }}
</div>
</q-btn>
<!--
Item renderer
-->
<q-item v-else-if="renderer === 'item'"
:id="id"
class="full-width"
clickable
:dense="dense"
:disable="computedDisabled"
v-close-popup="closePopup"
@click="onClicked">
<q-item-section v-if="computedIcon || badge" avatar>
<q-icon v-if="computedIcon" :name="computedIcon" :color="computedColor" :dense="dense" />
<!-- badge -->
<q-badge v-if="badge" v-bind="badge" :label="computedBadgeLabel">
<q-icon v-if="badge.icon" v-bind="badge.icon" />
</q-badge>
</q-item-section>
<q-item-section :class="'text-' + computedColor" no-wrap>
<q-item-label :lines="1">{{ computedLabel }}</q-item-label>
</q-item-section>
</q-item>
<!--
Fab renderer
-->
<q-btn v-else-if="renderer === 'fab'"
:id="id"
class="k-action-fab"
:icon="computedIcon"
:color="computedColor"
:size="size"
:round="true"
:dense="dense"
:disable="computedDisabled"
@click="onClicked">
<!-- tooltip -->
<q-tooltip v-if="computedTooltip" anchor="top middle" self="bottom right">
{{ computedTooltip }}
</q-tooltip>
<!-- badge -->
<q-badge v-if="badge" v-bind="badge" :label="computedBadgeLabel">
<q-icon v-if="badge.icon" v-bind="badge.icon" />
</q-badge>
</q-btn>
<!--
Fab action renderer
-->
<q-fab-action v-else-if="renderer === 'fab-action'"
:id="id"
class="k-action-fab-action"
no-caps
:icon="computedIcon"
:color="computedColor"
:label="computedLabel"
square
external-label
:label-position="iconRight ? 'left' : 'right'"
label-class="bg-primary text-white text-caption k-fab-action"
:disable="computedDisabled"
@click="onClicked">
<!-- badge -->
<q-badge v-if="badge" v-bind="badge">
<q-icon v-if="badge.icon" v-bind="badge.icon" />
</q-badge>
</q-fab-action>
<!--
Tab renderer
-->
<q-btn v-else-if="renderer === 'tab'"
:class="{'k-action-tab-active': isToggled }"
:id="id"
no-caps
no-wrap
:label="computedLabel"
:color="computedColor"
:size="size"
flat
square
:dense="dense"
:disable="computedDisabled"
@click="onClicked">
<!-- tooltip -->
<q-tooltip v-if="computedTooltip">
{{ computedTooltip }}
</q-tooltip>
<!-- badge -->
<q-badge v-if="badge" v-bind="badge" :label="computedBadgeLabel">
<q-icon v-if="badge.icon" v-bind="badge.icon" />
</q-badge>
<!-- extra content -->
<slot>
</slot>
</q-btn>
</template>

<script>
// use normal <script> to declare options
// TODO: need to updated when switch to vue > 3.3
export default {
inheritAttrs: false
}
</script>

<script setup>
import _ from 'lodash'
import { ref, toRef, computed, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useQuasar, openURL } from 'quasar'
import { i18n } from '../../i18n.js'
import { actionProps } from '../../utils/utils.actions'
import { bindParams } from '../../utils/utils.content.js'
// Data
const route = useRoute()
const router = useRouter()
const $q = useQuasar()
const props = defineProps(actionProps)
const isToggled = _.has(props, 'toggle.value') ? toRef(props.toggle, 'value') : ref(props.toggled)
// Emit
const emit = defineEmits(['triggered', 'toggled', 'dialog-confirmed', 'dialog-canceled'])
// Computed
const computedLabel = computed(() => {
// Check also for translation key or already translated message
if (isToggled.value && _.has(props.toggle, 'label')) return i18n.tie(props.toggle.label)
return i18n.tie(props.label)
})
const computedIcon = computed(() => {
if (isToggled.value && _.has(props.toggle, 'icon')) return props.toggle.icon
return props.icon
})
const computedColor = computed(() => {
if (isToggled.value) return _.get(props.toggle, 'color', 'accent')
return props.color
})
const computedDisabled = computed(() => {
if (!props.disabled) return false
if (typeof props.disabled === 'function') return props.disabled()
return props.disabled
})
const computedTooltip = computed(() => {
if (computedDisabled.value) return
// Check also for translation key or already translated message
if (isToggled.value && _.has(props.toggle, 'tooltip')) return i18n.tie(props.toggle.tooltip)
return i18n.tie(props.tooltip)
})
const computedBadgeLabel = computed(() => {
// Check also for translation key or already translated message
if (props.badge && _.has(props.badge, 'label')) return i18n.tie(props.badge.label)
// Take care that changing this to null or '' breaks the display in Quasar
return undefined
})
const dense = computed(() => {
return $q.screen.lt.sm
})
// Functions
function toggle () {
isToggled.value = !isToggled.value
emit('toggled', props.context, isToggled.value)
}
function bindRouteParams (path) {
// When action is created from code we can directly inject the params.
// However, when created from the config we need to manage dynamic values.
// A parameter like ':xxx' in config means xxx is a dynamic property of
// the current route or the context object, not a static value.
// We bind the target params object to both possible context.
const currentParams = _.get(route, path, {})
const targetParams = _.get(props.route, path, {})
const routeParams = bindParams(targetParams, currentParams)
const contextParams = bindParams(targetParams, props.context)
return _.merge(routeParams, contextParams)
}
async function onClicked (event) {
if (!props.propagate) event.stopPropagation()
// handle the toggle if needed
if (props.toggle) toggle()
// handle the URL case
if (props.url) openURL(props.url)
// handle the callback case
if (props.handler) {
try {
await props.handler(props.context, isToggled.value)
} catch (error) {
// in case an error is raised we assume toggling has failed
if (props.toggle) toggle()
throw error
}
return
}
// handle the route case
if (props.route) {
// allow to directly call a given URL, eg OAuth callback
if (props.route.url) {
location.href = props.route.url
} else {
// process route params
router.push(Object.assign({
query: bindRouteParams('query'),
params: bindRouteParams('params')
}, _.omit(props.route, ['query', 'params']))).catch(() => {})
}
return
}
// handle the dialog case
if (props.dialog) {
let dialog = props.dialog
const component = _.get(props.dialog, 'component')
if (component) {
dialog = {
component: 'KDialog',
componentProps: _.clone(dialog)
}
}
$q.dialog(dialog)
.onOk((result) => {
emit('dialog-confirmed', props.context, result)
})
.onCancel((result) => {
emit('dialog-canceled', props.context, result)
})
}
// notify listeners
emit('triggered', props.context, isToggled.value)
}
// Watch
watch(() => props.toggled, (value) => {
if (isToggled.value !== value) isToggled.value = value
})
</script>

<style lang="scss" scoped>
.k-action-fab, .k-action-fab-action {
border: 2px solid var(--q-secondary);
}
.k-action-tab-active {
border-bottom: solid 2px;
}
</style>
9 changes: 5 additions & 4 deletions core/client/components/action/KBugReportAction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ import config from 'config'
import { ref } from 'vue'
import { i18n } from '../../i18n'
import { getPlatform } from '../../utils/utils.platform'
import { props as actionProps } from '../../utils/utils.actions'
import { actionProps } from '../../utils/utils.actions'
import { useVersion } from '../../composables'
import KAction from '../KAction.vue'
import KAction from './/KAction.vue'
// Data
const props = defineProps(_.pick(actionProps, ['id', 'icon', 'label', 'stack']))
const props = defineProps(_.omit(actionProps, ['toggle', 'url', 'handler', 'route', 'dialog']))
const { clientVersionName, apiVersionName } = useVersion()
const platform = getPlatform()
// bug report
// Setup bug report info
const bugReport = {
address: _.get(config, 'publisherContact'),
subject: i18n.t('KAbout.BUG_REPORT_SUBJECT', {
Expand Down
7 changes: 7 additions & 0 deletions core/client/components/action/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import KAction from './KAction.vue'
import KBugReportAction from './KBugReportAction.vue'

export {
KAction,
KBugReportAction
}
2 changes: 1 addition & 1 deletion core/client/components/app/KPlatform.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import { useQuasar, copyToClipboard } from 'quasar'
import { i18n } from '../../i18n.js'
import { getPlatform } from '../../utils/utils.platform'
import KAction from '../KAction.vue'
import KAction from '../action/KAction.vue'
// data
const $q = useQuasar()
Expand Down
2 changes: 1 addition & 1 deletion core/client/components/app/KWelcome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ import { openURL, useQuasar } from 'quasar'
import { Store, api } from '../..'
import { loadComponent } from '../../utils'
import { LocalStorage } from '../../local-storage.js'
import KAction from '../KAction.vue'
import KAction from '../action/KAction.vue'
// Data
const $q = useQuasar()
Expand Down
2 changes: 1 addition & 1 deletion core/client/components/collection/KCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@

<script>
import _ from 'lodash'
import KAction from '../KAction.vue'
import KAction from '../action/KAction.vue'
import KPanel from '../KPanel.vue'
import KTextArea from '../KTextArea.vue'
import KAvatar from '../KAvatar.vue'
Expand Down
Loading

0 comments on commit 1ccfc33

Please sign in to comment.