quasar-ui-danx 0.0.44 → 0.0.45
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +1 -1
- package/src/components/AuditHistory/AuditHistoryItem.vue +54 -0
- package/src/components/AuditHistory/AuditHistoryItemValue.vue +60 -0
- package/src/components/AuditHistory/index.ts +2 -0
- package/src/components/PanelsDrawer/PanelsDrawer.vue +64 -0
- package/src/components/PanelsDrawer/PanelsDrawerPanels.vue +25 -0
- package/src/components/PanelsDrawer/PanelsDrawerTabs.vue +65 -0
- package/src/components/PanelsDrawer/index.ts +3 -0
- package/src/components/Utility/Controls/PreviousNextControls.vue +28 -0
- package/src/components/Utility/Controls/index.ts +1 -0
- package/src/components/Utility/Tabs/BadgeTab.vue +32 -0
- package/src/components/Utility/Tabs/IndicatorTab.vue +40 -0
- package/src/components/Utility/Tabs/index.ts +2 -0
- package/src/components/Utility/index.ts +2 -0
- package/src/components/index.ts +3 -1
- package/src/svg/SkipNextIcon.svg +5 -0
- package/src/svg/SkipPreviousIcon.svg +5 -0
- package/src/svg/WarningIcon.svg +5 -0
- package/src/svg/index.ts +3 -0
package/package.json
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="text-gray-shadow flex items-stretch flex-nowrap p-4">
|
3
|
+
<div class="flex-grow text-sm w-3/5 overflow-auto">
|
4
|
+
<h5>{{ change.label }} ({{ change.name }})</h5>
|
5
|
+
<div class="flex flex-nowrap items-center mt-4">
|
6
|
+
<div class="bg-red-light line-through p-2">
|
7
|
+
<AdHistoryItemValue
|
8
|
+
:type="change.type"
|
9
|
+
:value="change.oldValue"
|
10
|
+
/>
|
11
|
+
</div>
|
12
|
+
<div class="bg-green-plus-4 ml-2.5 p-2">
|
13
|
+
<AdHistoryItemValue
|
14
|
+
:type="change.type"
|
15
|
+
:value="change.newValue"
|
16
|
+
/>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
<div class="ml-4 text-sm w-2/5">
|
21
|
+
<template v-if="item.user">
|
22
|
+
<div>{{ item.user.name }}</div>
|
23
|
+
<div>{{ item.user.email }}</div>
|
24
|
+
</template>
|
25
|
+
<div>{{ item.account }}</div>
|
26
|
+
<div>
|
27
|
+
<a v-if="item.audit_request_id" :href="novaUrl" target="_blank">{{ fLocalizedDateTime(item.timestamp) }}</a>
|
28
|
+
<template v-else>{{ fLocalizedDateTime(item.timestamp) }}</template>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
</template>
|
33
|
+
<script setup>
|
34
|
+
import { computed } from 'vue';
|
35
|
+
import { fLocalizedDateTime } from '../../helpers';
|
36
|
+
import AdHistoryItemValue from './AuditHistoryItemValue';
|
37
|
+
|
38
|
+
const props = defineProps({
|
39
|
+
item: {
|
40
|
+
type: Object,
|
41
|
+
required: true
|
42
|
+
},
|
43
|
+
change: {
|
44
|
+
type: Object,
|
45
|
+
required: true
|
46
|
+
},
|
47
|
+
novaUrl: {
|
48
|
+
type: String,
|
49
|
+
default: '/nova'
|
50
|
+
}
|
51
|
+
});
|
52
|
+
|
53
|
+
const novaUrl = computed(() => props.novaUrl + `/resources/audit-requests/${props.item.audit_request_id}`);
|
54
|
+
</script>
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="flex space-x-2">
|
3
|
+
<template v-if="type === 'SINGLE_FILE'">
|
4
|
+
<FilePreview
|
5
|
+
:image="value"
|
6
|
+
class="w-24"
|
7
|
+
/>
|
8
|
+
</template>
|
9
|
+
<template v-else-if="type === 'MULTI_FILE'">
|
10
|
+
<FilePreview
|
11
|
+
v-for="file in value"
|
12
|
+
:key="'file-' + file.id"
|
13
|
+
:image="file"
|
14
|
+
class="w-24 mb-2"
|
15
|
+
/>
|
16
|
+
</template>
|
17
|
+
<template v-else-if="type === 'WYSIWYG'">
|
18
|
+
<div v-html="value" />
|
19
|
+
</template>
|
20
|
+
<template v-else>
|
21
|
+
{{ format(value) }}
|
22
|
+
</template>
|
23
|
+
</div>
|
24
|
+
</template>
|
25
|
+
<script setup>
|
26
|
+
import { fCurrency, fDate, fLocalizedDateTime, fNumber } from '../../helpers';
|
27
|
+
import { FilePreview } from '../Utility';
|
28
|
+
|
29
|
+
const props = defineProps({
|
30
|
+
type: {
|
31
|
+
type: String,
|
32
|
+
required: true
|
33
|
+
},
|
34
|
+
value: {
|
35
|
+
type: [Number, String, Array, Object, Boolean],
|
36
|
+
default: null
|
37
|
+
}
|
38
|
+
});
|
39
|
+
|
40
|
+
function format(value) {
|
41
|
+
if (value === null || value === '' || value === undefined) {
|
42
|
+
return '';
|
43
|
+
}
|
44
|
+
|
45
|
+
switch (props.type) {
|
46
|
+
case 'NUMBER':
|
47
|
+
return fNumber(value);
|
48
|
+
case 'CURRENCY':
|
49
|
+
return fCurrency(value);
|
50
|
+
case 'DATE':
|
51
|
+
return fDate(value);
|
52
|
+
case 'DATETIME':
|
53
|
+
return fLocalizedDateTime(value);
|
54
|
+
case 'BOOLEAN':
|
55
|
+
return value ? 'Yes' : 'No';
|
56
|
+
}
|
57
|
+
|
58
|
+
return value;
|
59
|
+
}
|
60
|
+
</script>
|
@@ -0,0 +1,64 @@
|
|
1
|
+
<template>
|
2
|
+
<ContentDrawer
|
3
|
+
position="right"
|
4
|
+
:show="true"
|
5
|
+
overlay
|
6
|
+
content-class="h-full"
|
7
|
+
title=""
|
8
|
+
@update:show="$emit('close')"
|
9
|
+
>
|
10
|
+
<div class="flex flex-col flex-nowrap h-full">
|
11
|
+
<div class="flex items-center px-6 py-4 border-b">
|
12
|
+
<div class="flex-grow">
|
13
|
+
<slot name="header" />
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div>
|
17
|
+
<QBtn @click="$emit('close')">
|
18
|
+
<CloseIcon class="w-4" />
|
19
|
+
</QBtn>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<div class="flex-grow overflow-hidden h-full">
|
23
|
+
<div class="flex items-stretch flex-nowrap h-full">
|
24
|
+
<div class="border-r w-[13.5em] overflow-y-auto">
|
25
|
+
<PanelsDrawerTabs
|
26
|
+
v-model="activePanel"
|
27
|
+
:panels="panels"
|
28
|
+
@update:model-value="$emit('update:model-value', $event)"
|
29
|
+
/>
|
30
|
+
</div>
|
31
|
+
<PanelsDrawerPanels :panels="panels" :active-panel="activePanel" :class="panelsClass" />
|
32
|
+
<div v-if="$slots['right-sidebar']" class="border-l overflow-y-auto">
|
33
|
+
<slot name="right-sidebar" />
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
</ContentDrawer>
|
39
|
+
</template>
|
40
|
+
<script setup>
|
41
|
+
import { ref, watch } from 'vue';
|
42
|
+
import { XIcon as CloseIcon } from '../../svg';
|
43
|
+
import { ContentDrawer } from '../Utility';
|
44
|
+
import { PanelsDrawerPanels, PanelsDrawerTabs } from './index';
|
45
|
+
|
46
|
+
defineEmits(['update:model-value', 'close']);
|
47
|
+
const props = defineProps({
|
48
|
+
modelValue: {
|
49
|
+
type: String,
|
50
|
+
default: null
|
51
|
+
},
|
52
|
+
panelsClass: {
|
53
|
+
type: [Object, String],
|
54
|
+
default: 'w-[35.5rem]'
|
55
|
+
},
|
56
|
+
panels: {
|
57
|
+
type: Array,
|
58
|
+
required: true
|
59
|
+
}
|
60
|
+
});
|
61
|
+
|
62
|
+
const activePanel = ref(props.modelValue);
|
63
|
+
watch(() => props.modelValue, (value) => activePanel.value = value);
|
64
|
+
</script>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<template>
|
2
|
+
<QTabPanels
|
3
|
+
:model-value="activePanel"
|
4
|
+
class="overflow-y-auto bg-neutral-plus-7 h-full transition-all"
|
5
|
+
>
|
6
|
+
<QTabPanel v-for="panel in panels" :key="panel.name" :name="panel.name">
|
7
|
+
<RenderVnode v-if="panel.vnode" :vnode="panel.vnode" />
|
8
|
+
</QTabPanel>
|
9
|
+
</QTabPanels>
|
10
|
+
</template>
|
11
|
+
|
12
|
+
<script setup>
|
13
|
+
import { RenderVnode } from "quasar-ui-danx";
|
14
|
+
|
15
|
+
defineProps({
|
16
|
+
activePanel: {
|
17
|
+
type: String,
|
18
|
+
required: true
|
19
|
+
},
|
20
|
+
panels: {
|
21
|
+
type: Array,
|
22
|
+
required: true
|
23
|
+
}
|
24
|
+
});
|
25
|
+
</script>
|
@@ -0,0 +1,65 @@
|
|
1
|
+
<template>
|
2
|
+
<QTabs
|
3
|
+
:model-value="modelValue"
|
4
|
+
vertical
|
5
|
+
align="left"
|
6
|
+
class="panel-tabs p-4 h-auto"
|
7
|
+
no-caps
|
8
|
+
@update:model-value="$emit('update:model-value', $event)"
|
9
|
+
>
|
10
|
+
<template v-for="panel in panels">
|
11
|
+
<template v-if="panel.enabled !== false">
|
12
|
+
<RenderVnode
|
13
|
+
v-if="panel.tabVnode"
|
14
|
+
:key="panel.name"
|
15
|
+
:vnode="panel.tabVnode"
|
16
|
+
:is-active="modelValue === panel.name"
|
17
|
+
:name="panel.name"
|
18
|
+
:label="panel.label"
|
19
|
+
/>
|
20
|
+
<QTab v-else :key="panel.name" :name="panel.name" :label="panel.label" />
|
21
|
+
</template>
|
22
|
+
</template>
|
23
|
+
</QTabs>
|
24
|
+
</template>
|
25
|
+
<script setup>
|
26
|
+
import { QTab } from "quasar";
|
27
|
+
import { RenderVnode } from "quasar-ui-danx";
|
28
|
+
|
29
|
+
defineEmits(["update:model-value"]);
|
30
|
+
defineProps({
|
31
|
+
modelValue: {
|
32
|
+
type: String,
|
33
|
+
default: "general"
|
34
|
+
},
|
35
|
+
panels: {
|
36
|
+
type: Array,
|
37
|
+
required: true
|
38
|
+
}
|
39
|
+
});
|
40
|
+
</script>
|
41
|
+
|
42
|
+
<style
|
43
|
+
lang="scss"
|
44
|
+
scoped
|
45
|
+
>
|
46
|
+
.panel-tabs {
|
47
|
+
:deep(.q-tab) {
|
48
|
+
justify-content: start !important;
|
49
|
+
padding: 0;
|
50
|
+
@apply text-left py-2.5 px-2 rounded-lg hover:bg-neutral-plus-6;
|
51
|
+
|
52
|
+
.q-focus-helper, .q-tab__indicator {
|
53
|
+
display: none;
|
54
|
+
}
|
55
|
+
|
56
|
+
.q-tab__content {
|
57
|
+
@apply p-0;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
:deep(.q-tab.q-tab--active) {
|
62
|
+
@apply text-white bg-blue-base;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
</style>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="previous-next-controls">
|
3
|
+
<QBtn
|
4
|
+
class="bg-neutral-plus-6 border-neutral-plus-4 border border-solid !rounded-r-none !p-2 !min-w-0"
|
5
|
+
:disable="isLoading"
|
6
|
+
:loading="isLoading"
|
7
|
+
@click="$emit('next', -1)"
|
8
|
+
>
|
9
|
+
<SkipPreviousIcon class="w-6" />
|
10
|
+
</QBtn>
|
11
|
+
<QBtn
|
12
|
+
class="bg-neutral-plus-6 border-neutral-plus-4 border border-solid border-l-0 !rounded-l-none !p-2 !min-w-0"
|
13
|
+
:disable="isLoading"
|
14
|
+
:loading="isLoading"
|
15
|
+
@click="$emit('next', 1)"
|
16
|
+
>
|
17
|
+
<SkipNextIcon class="w-6" />
|
18
|
+
</QBtn>
|
19
|
+
</div>
|
20
|
+
</template>
|
21
|
+
<script setup>
|
22
|
+
import { SkipNextIcon, SkipPreviousIcon } from '../../../svg';
|
23
|
+
|
24
|
+
defineEmits(['next']);
|
25
|
+
defineProps({
|
26
|
+
isLoading: Boolean
|
27
|
+
});
|
28
|
+
</script>
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default as PreviousNextControls } from "./PreviousNextControls.vue";
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<template>
|
2
|
+
<q-tab
|
3
|
+
:name="name"
|
4
|
+
class="w-full"
|
5
|
+
content-class="w-full"
|
6
|
+
>
|
7
|
+
<div class="flex items-center w-full">
|
8
|
+
<div class="flex-grow text-sm">{{ label }}</div>
|
9
|
+
<q-badge
|
10
|
+
color="gray-base"
|
11
|
+
:label="count"
|
12
|
+
rounded
|
13
|
+
/>
|
14
|
+
</div>
|
15
|
+
</q-tab>
|
16
|
+
</template>
|
17
|
+
<script setup>
|
18
|
+
defineProps({
|
19
|
+
name: {
|
20
|
+
type: String,
|
21
|
+
required: true
|
22
|
+
},
|
23
|
+
label: {
|
24
|
+
type: String,
|
25
|
+
required: true
|
26
|
+
},
|
27
|
+
count: {
|
28
|
+
type: [String, Number],
|
29
|
+
default: ''
|
30
|
+
}
|
31
|
+
});
|
32
|
+
</script>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<template>
|
2
|
+
<q-tab
|
3
|
+
:name="name"
|
4
|
+
class="w-full"
|
5
|
+
content-class="w-full"
|
6
|
+
>
|
7
|
+
<div class="flex items-center w-full">
|
8
|
+
<div class="flex-grow text-sm">{{ label }}</div>
|
9
|
+
<div>
|
10
|
+
<OverdueIcon
|
11
|
+
v-if="overdue"
|
12
|
+
class="w-5 ml-2"
|
13
|
+
:class="isActive ? 'text-white' : 'text-red-danger'"
|
14
|
+
/>
|
15
|
+
<WarningIcon
|
16
|
+
v-else-if="warning"
|
17
|
+
class="text-yellow-warning w-5"
|
18
|
+
/>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</q-tab>
|
22
|
+
</template>
|
23
|
+
<script setup>
|
24
|
+
import { ExclamationCircleIcon as OverdueIcon } from '@heroicons/vue/solid';
|
25
|
+
import { WarningIcon } from '../../../svg';
|
26
|
+
|
27
|
+
defineProps({
|
28
|
+
name: {
|
29
|
+
type: String,
|
30
|
+
required: true
|
31
|
+
},
|
32
|
+
label: {
|
33
|
+
type: String,
|
34
|
+
required: true
|
35
|
+
},
|
36
|
+
overdue: Boolean,
|
37
|
+
warning: Boolean,
|
38
|
+
isActive: Boolean
|
39
|
+
});
|
40
|
+
</script>
|
@@ -1,8 +1,10 @@
|
|
1
1
|
export * from "./Buttons";
|
2
|
+
export * from "./Controls";
|
2
3
|
export * from "./Dialogs";
|
3
4
|
export * from "./Files";
|
4
5
|
export * from "./Formats";
|
5
6
|
export * from "./Layouts";
|
6
7
|
export * from "./Popovers";
|
8
|
+
export * from "./Tabs";
|
7
9
|
export * from "./Tools";
|
8
10
|
export * from "./Transitions";
|
package/src/components/index.ts
CHANGED
@@ -0,0 +1,5 @@
|
|
1
|
+
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<path
|
3
|
+
d="M0 18.2727L10 1L20 18.2727H0ZM3.13636 16.4545H16.8636L10 4.63636L3.13636 16.4545ZM10 15.5455C10.2576 15.5455 10.4736 15.4582 10.6482 15.2836C10.8221 15.1097 10.9091 14.8939 10.9091 14.6364C10.9091 14.3788 10.8221 14.163 10.6482 13.9891C10.4736 13.8145 10.2576 13.7273 10 13.7273C9.74242 13.7273 9.52667 13.8145 9.35273 13.9891C9.17818 14.163 9.09091 14.3788 9.09091 14.6364C9.09091 14.8939 9.17818 15.1097 9.35273 15.2836C9.52667 15.4582 9.74242 15.5455 10 15.5455ZM9.09091 12.8182H10.9091V8.27273H9.09091V12.8182Z"
|
4
|
+
fill="currentColor"/>
|
5
|
+
</svg>
|
package/src/svg/index.ts
CHANGED
@@ -4,5 +4,8 @@ export { default as FilterIcon } from "./FilterIcon.svg";
|
|
4
4
|
export { default as ImageIcon } from "./ImageIcon.svg";
|
5
5
|
export { default as PdfIcon } from "./PdfIcon.svg";
|
6
6
|
export { default as PercentIcon } from "./PercentIcon.svg";
|
7
|
+
export { default as SkipNextIcon } from "./SkipNextIcon.svg";
|
8
|
+
export { default as SkipPreviousIcon } from "./SkipPreviousIcon.svg";
|
7
9
|
export { default as TrashIcon } from "./TrashIcon.svg";
|
10
|
+
export { default as WarningIcon } from "./WarningIcon.svg";
|
8
11
|
export { default as XIcon } from "./XIcon.svg";
|