@tekkare/auriga 0.2.194 → 0.2.198
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/runtime/components/argAccordionMenu.vue +154 -0
- package/dist/runtime/components/argAccordionMenu.vue.d.ts +48 -0
- package/dist/runtime/components/argDashboardSection.vue +74 -0
- package/dist/runtime/components/argDrawer.vue +53 -0
- package/dist/runtime/components/argDrawer.vue.d.ts +38 -0
- package/dist/runtime/components/argFooter.vue +1 -1
- package/dist/runtime/components/argLoginPage.vue +107 -0
- package/dist/runtime/components/argModal.vue +17 -7
- package/dist/runtime/components/argModal.vue.d.ts +4 -2
- package/dist/runtime/components/argNoLicense.vue +75 -0
- package/dist/runtime/components/argProfilePage.vue +360 -0
- package/dist/runtime/components/argProjectDashboard.vue +631 -0
- package/dist/runtime/components/argResourceCard.vue +109 -0
- package/dist/runtime/components/argResourceTable.vue +302 -0
- package/package.json +2 -1
package/dist/module.json
CHANGED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="arg_accordion_menu">
|
|
3
|
+
<div
|
|
4
|
+
v-for="(section, sIndex) in menu"
|
|
5
|
+
:key="sIndex"
|
|
6
|
+
class="arg_accordion_section"
|
|
7
|
+
>
|
|
8
|
+
<!-- Section Header -->
|
|
9
|
+
<div
|
|
10
|
+
class="arg_accordion_header"
|
|
11
|
+
:class="{ active: openSections[sIndex] }"
|
|
12
|
+
@click="toggleSection(sIndex)"
|
|
13
|
+
>
|
|
14
|
+
<span class="arg_accordion_title">{{ section.title }}</span>
|
|
15
|
+
<div
|
|
16
|
+
class="arg_accordion_chevron"
|
|
17
|
+
:class="{ rotated: openSections[sIndex] }"
|
|
18
|
+
>
|
|
19
|
+
<arg-icon name="CaretDown" size="16" color="var(--medium)" />
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<!-- Section Content -->
|
|
24
|
+
<div
|
|
25
|
+
class="arg_accordion_content"
|
|
26
|
+
:class="{ open: openSections[sIndex] }"
|
|
27
|
+
>
|
|
28
|
+
<!-- Direct items -->
|
|
29
|
+
<template v-if="section.items">
|
|
30
|
+
<NuxtLink
|
|
31
|
+
v-for="(item, iIndex) in section.items"
|
|
32
|
+
:key="'item-' + iIndex"
|
|
33
|
+
:to="item.to || '#'"
|
|
34
|
+
class="arg_accordion_item"
|
|
35
|
+
activeClass="is-active"
|
|
36
|
+
@click="$emit('onNavigate', item)"
|
|
37
|
+
>
|
|
38
|
+
<div class="arg_accordion_item_left">
|
|
39
|
+
<arg-icon v-if="item.icon" :name="item.icon" size="20" />
|
|
40
|
+
<span>{{ item.label }}</span>
|
|
41
|
+
</div>
|
|
42
|
+
<span
|
|
43
|
+
v-if="item.haveData !== undefined"
|
|
44
|
+
class="arg_accordion_indicator"
|
|
45
|
+
:class="item.haveData ? 'has-data' : 'no-data'"
|
|
46
|
+
/>
|
|
47
|
+
</NuxtLink>
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
<!-- Sub-sections -->
|
|
51
|
+
<template v-if="section.subSections">
|
|
52
|
+
<div
|
|
53
|
+
v-for="(sub, subIndex) in section.subSections"
|
|
54
|
+
:key="'sub-' + subIndex"
|
|
55
|
+
class="arg_accordion_sub_section"
|
|
56
|
+
>
|
|
57
|
+
<div
|
|
58
|
+
class="arg_accordion_sub_header"
|
|
59
|
+
@click="toggleSubSection(sIndex, subIndex)"
|
|
60
|
+
>
|
|
61
|
+
<span class="arg_accordion_sub_label">{{ sub.label }}</span>
|
|
62
|
+
<div
|
|
63
|
+
class="arg_accordion_sub_chevron"
|
|
64
|
+
:class="{ rotated: openSubSections[sIndex + '-' + subIndex] }"
|
|
65
|
+
>
|
|
66
|
+
<arg-icon name="CaretDown" size="12" />
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
<div
|
|
70
|
+
class="arg_accordion_sub_content"
|
|
71
|
+
:class="{ open: openSubSections[sIndex + '-' + subIndex] }"
|
|
72
|
+
>
|
|
73
|
+
<NuxtLink
|
|
74
|
+
v-for="(item, iIndex) in sub.items"
|
|
75
|
+
:key="'subitem-' + iIndex"
|
|
76
|
+
:to="item.to || '#'"
|
|
77
|
+
class="arg_accordion_item"
|
|
78
|
+
activeClass="is-active"
|
|
79
|
+
@click="$emit('onNavigate', item)"
|
|
80
|
+
>
|
|
81
|
+
<div class="arg_accordion_item_left">
|
|
82
|
+
<arg-icon v-if="item.icon" :name="item.icon" size="20" />
|
|
83
|
+
<span>{{ item.label }}</span>
|
|
84
|
+
</div>
|
|
85
|
+
<span
|
|
86
|
+
v-if="item.haveData !== undefined"
|
|
87
|
+
class="arg_accordion_indicator"
|
|
88
|
+
:class="item.haveData ? 'has-data' : 'no-data'"
|
|
89
|
+
/>
|
|
90
|
+
</NuxtLink>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</template>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</template>
|
|
98
|
+
|
|
99
|
+
<script>
|
|
100
|
+
import { defineComponent, reactive } from "vue";
|
|
101
|
+
import argIcon from "./argIcon.vue";
|
|
102
|
+
export default defineComponent({
|
|
103
|
+
name: "argAccordionMenu",
|
|
104
|
+
components: { argIcon },
|
|
105
|
+
props: {
|
|
106
|
+
menu: {
|
|
107
|
+
type: Array,
|
|
108
|
+
required: true
|
|
109
|
+
},
|
|
110
|
+
singleOpen: {
|
|
111
|
+
type: Boolean,
|
|
112
|
+
default: true
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
emits: ["onNavigate"],
|
|
116
|
+
setup(props) {
|
|
117
|
+
const openSections = reactive({});
|
|
118
|
+
const openSubSections = reactive({});
|
|
119
|
+
props.menu.forEach((section, index) => {
|
|
120
|
+
openSections[index] = section.defaultOpen ?? index === 0;
|
|
121
|
+
});
|
|
122
|
+
props.menu.forEach((section, sIndex) => {
|
|
123
|
+
section.subSections?.forEach((_sub, subIndex) => {
|
|
124
|
+
openSubSections[`${sIndex}-${subIndex}`] = true;
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
function toggleSection(index) {
|
|
128
|
+
if (props.singleOpen) {
|
|
129
|
+
const wasOpen = openSections[index];
|
|
130
|
+
Object.keys(openSections).forEach((key) => {
|
|
131
|
+
openSections[Number(key)] = false;
|
|
132
|
+
});
|
|
133
|
+
openSections[index] = !wasOpen;
|
|
134
|
+
} else {
|
|
135
|
+
openSections[index] = !openSections[index];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function toggleSubSection(sectionIndex, subIndex) {
|
|
139
|
+
const key = `${sectionIndex}-${subIndex}`;
|
|
140
|
+
openSubSections[key] = !openSubSections[key];
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
openSections,
|
|
144
|
+
openSubSections,
|
|
145
|
+
toggleSection,
|
|
146
|
+
toggleSubSection
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
</script>
|
|
151
|
+
|
|
152
|
+
<style scoped>
|
|
153
|
+
.arg_accordion_menu{display:flex;flex-direction:column;width:100%}.arg_accordion_section{border-bottom:1px solid var(--light,#ececf2);margin-bottom:4px;padding-bottom:8px}.arg_accordion_section:last-child{border-bottom:none}.arg_accordion_header{align-items:center;border-radius:8px;cursor:pointer;display:flex;justify-content:space-between;padding:8px;transition:background-color .2s ease}.arg_accordion_header:hover{background-color:var(--light,#ececf2)}.arg_accordion_title{font-size:13px;font-weight:700;line-height:normal}.arg_accordion_chevron{align-items:center;display:flex;transition:transform .2s ease}.arg_accordion_chevron.rotated{transform:rotate(180deg)}.arg_accordion_content{max-height:0;overflow:hidden;padding-left:12px;padding-right:8px;transition:max-height .3s ease}.arg_accordion_content.open{margin-top:4px;max-height:600px}.arg_accordion_item{align-items:center;align-self:stretch;border-radius:4px;color:var(--darkest,#1a1a2e);display:flex;font-size:14px;font-weight:400;gap:8px;justify-content:space-between;line-height:160%;padding:8px;text-decoration:none}.arg_accordion_item:hover:not(.is-active){background:var(--light,#ececf2)}.arg_accordion_item.is-active{background:rgba(33,118,255,.1)}.arg_accordion_item svg{color:var(--dark,#6c6c8a)!important}.arg_accordion_item.is-active svg,.arg_accordion_item:hover:not(.is-active) svg{color:var(--primary,#2176ff)!important}.arg_accordion_item_left{align-items:center;display:flex;gap:8px}.arg_accordion_indicator{border-radius:50%;flex-shrink:0;height:10px;width:10px}.arg_accordion_indicator.has-data{background-color:var(--system-success,#2ecc71)}.arg_accordion_indicator.no-data{background-color:#bdbdd2}.arg_accordion_sub_section{margin-bottom:8px}.arg_accordion_sub_header{align-items:center;border-radius:8px;cursor:pointer;display:flex;justify-content:space-between;padding:4px 8px;transition:background-color .2s ease}.arg_accordion_sub_header:hover{background-color:var(--light,#ececf2)}.arg_accordion_sub_label{color:var(--dark,#6c6c8a);font-size:12px;font-weight:700}.arg_accordion_sub_chevron{align-items:center;color:var(--medium,#9999b0);display:flex;transition:transform .2s ease}.arg_accordion_sub_chevron.rotated{transform:rotate(180deg)}.arg_accordion_sub_content{background:rgba(234,236,248,.4);border-radius:8px;margin-top:4px;max-height:0;overflow:hidden;padding:0 8px;transition:max-height .2s ease,padding .2s ease}.arg_accordion_sub_content.open{max-height:300px;padding:8px}
|
|
154
|
+
</style>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type PropType } from "vue";
|
|
2
|
+
interface AccordionMenuItem {
|
|
3
|
+
label: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
to?: string;
|
|
6
|
+
haveData?: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface AccordionSubSection {
|
|
9
|
+
label: string;
|
|
10
|
+
items: AccordionMenuItem[];
|
|
11
|
+
}
|
|
12
|
+
interface AccordionSection {
|
|
13
|
+
title: string;
|
|
14
|
+
defaultOpen?: boolean;
|
|
15
|
+
items?: AccordionMenuItem[];
|
|
16
|
+
subSections?: AccordionSubSection[];
|
|
17
|
+
}
|
|
18
|
+
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
19
|
+
menu: {
|
|
20
|
+
type: PropType<AccordionSection[]>;
|
|
21
|
+
required: true;
|
|
22
|
+
};
|
|
23
|
+
singleOpen: {
|
|
24
|
+
type: BooleanConstructor;
|
|
25
|
+
default: boolean;
|
|
26
|
+
};
|
|
27
|
+
}>, {
|
|
28
|
+
openSections: Record<number, boolean>;
|
|
29
|
+
openSubSections: Record<string, boolean>;
|
|
30
|
+
toggleSection: (index: number) => void;
|
|
31
|
+
toggleSubSection: (sectionIndex: number, subIndex: number) => void;
|
|
32
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "onNavigate"[], "onNavigate", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
33
|
+
menu: {
|
|
34
|
+
type: PropType<AccordionSection[]>;
|
|
35
|
+
required: true;
|
|
36
|
+
};
|
|
37
|
+
singleOpen: {
|
|
38
|
+
type: BooleanConstructor;
|
|
39
|
+
default: boolean;
|
|
40
|
+
};
|
|
41
|
+
}>> & Readonly<{
|
|
42
|
+
onOnNavigate?: ((...args: any[]) => any) | undefined;
|
|
43
|
+
}>, {
|
|
44
|
+
singleOpen: boolean;
|
|
45
|
+
}, {}, {
|
|
46
|
+
argIcon: any;
|
|
47
|
+
}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
48
|
+
export default _default;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="arg_dashboard_section">
|
|
3
|
+
<div class="arg_dashboard_section_header" @click="toggleCollapse">
|
|
4
|
+
<div class="arg_dashboard_drag_handle" @click.stop>
|
|
5
|
+
<arg-icon name="DotsSixVertical" size="16" color="var(--medium)" />
|
|
6
|
+
</div>
|
|
7
|
+
<div class="arg_dashboard_section_left">
|
|
8
|
+
<arg-icon :name="icon" size="20" color="var(--primary)" />
|
|
9
|
+
<span class="arg_dashboard_section_title">{{ title }}</span>
|
|
10
|
+
<span class="arg_dashboard_section_count">{{ count }}</span>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="arg_dashboard_section_right">
|
|
13
|
+
<div class="arg_dashboard_section_actions" @click.stop>
|
|
14
|
+
<slot name="headerActions" />
|
|
15
|
+
</div>
|
|
16
|
+
<div class="arg_dashboard_section_separator"></div>
|
|
17
|
+
<div class="arg_dashboard_section_caret">
|
|
18
|
+
<arg-icon
|
|
19
|
+
:name="collapsed ? 'CaretRight' : 'CaretDown'"
|
|
20
|
+
size="16"
|
|
21
|
+
color="var(--dark)"
|
|
22
|
+
/>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
<div
|
|
27
|
+
v-show="!collapsed"
|
|
28
|
+
class="arg_dashboard_section_content"
|
|
29
|
+
:style="maxHeight ? { maxHeight: maxHeight + 'px', overflowY: 'auto' } : {}"
|
|
30
|
+
>
|
|
31
|
+
<slot />
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script setup lang="ts">
|
|
37
|
+
import { ref, watch } from "vue";
|
|
38
|
+
|
|
39
|
+
const props = withDefaults(
|
|
40
|
+
defineProps<{
|
|
41
|
+
title: string;
|
|
42
|
+
icon: string;
|
|
43
|
+
count: number;
|
|
44
|
+
defaultCollapsed?: boolean;
|
|
45
|
+
maxHeight?: number;
|
|
46
|
+
}>(),
|
|
47
|
+
{
|
|
48
|
+
defaultCollapsed: false,
|
|
49
|
+
maxHeight: undefined,
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const emit = defineEmits<{
|
|
54
|
+
collapseChange: [collapsed: boolean];
|
|
55
|
+
}>();
|
|
56
|
+
|
|
57
|
+
const collapsed = ref(props.defaultCollapsed);
|
|
58
|
+
|
|
59
|
+
watch(
|
|
60
|
+
() => props.defaultCollapsed,
|
|
61
|
+
(val) => {
|
|
62
|
+
collapsed.value = val;
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
function toggleCollapse() {
|
|
67
|
+
collapsed.value = !collapsed.value;
|
|
68
|
+
emit("collapseChange", collapsed.value);
|
|
69
|
+
}
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<style scoped>
|
|
73
|
+
.arg_dashboard_section{background:var(--base-white,#fff);border:1px solid var(--light,#ececf2);border-radius:10px;overflow:hidden}.arg_dashboard_section_header{align-items:center;background:var(--lightest,#f5f5fa);border-bottom:1px solid var(--light,#ececf2);cursor:pointer;display:flex;gap:8px;padding:12px 16px;transition:background .15s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none}.arg_dashboard_section_header:hover{background:var(--light,#ececf2)}.arg_dashboard_drag_handle{align-items:center;border-radius:4px;cursor:grab;display:flex;padding:2px;transition:background .15s ease}.arg_dashboard_drag_handle:hover{background:var(--light,#ececf2)}.arg_dashboard_drag_handle:active{cursor:grabbing}.arg_dashboard_section_left{align-items:center;display:flex;flex:1;gap:8px;min-width:0}.arg_dashboard_section_title{color:var(--darkest,#1a1a2e);font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.arg_dashboard_section_count{background:rgba(33,118,255,.1);border-radius:10px;color:var(--primary,#2176ff);font-size:12px;font-weight:600;padding:2px 8px;white-space:nowrap}.arg_dashboard_section_right{align-items:center;display:flex;flex-shrink:0;gap:8px}.arg_dashboard_section_actions{align-items:center;display:flex;gap:4px}.arg_dashboard_section_separator{background:var(--light,#ececf2);height:20px;width:1px}.arg_dashboard_section_caret{align-items:center;display:flex;transition:transform .2s ease}.arg_dashboard_section_content{padding:0}
|
|
74
|
+
</style>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="[
|
|
4
|
+
'arg_drawer_container',
|
|
5
|
+
open ? 'arg_drawer_open' : '',
|
|
6
|
+
]"
|
|
7
|
+
@click.self="$emit('onClose')"
|
|
8
|
+
>
|
|
9
|
+
<div
|
|
10
|
+
class="arg_drawer_panel"
|
|
11
|
+
:class="[
|
|
12
|
+
side === 'left' ? 'arg_drawer_left' : 'arg_drawer_right',
|
|
13
|
+
open ? 'arg_drawer_visible' : '',
|
|
14
|
+
]"
|
|
15
|
+
:style="{ width: panelWidth }"
|
|
16
|
+
>
|
|
17
|
+
<slot />
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script>
|
|
23
|
+
import { defineComponent, computed } from "vue";
|
|
24
|
+
export default defineComponent({
|
|
25
|
+
name: "argDrawer",
|
|
26
|
+
props: {
|
|
27
|
+
open: {
|
|
28
|
+
type: Boolean,
|
|
29
|
+
default: false
|
|
30
|
+
},
|
|
31
|
+
side: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: "right",
|
|
34
|
+
validator: (value) => ["left", "right"].includes(value)
|
|
35
|
+
},
|
|
36
|
+
width: {
|
|
37
|
+
type: [String, Number],
|
|
38
|
+
default: 400
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
emits: ["onClose"],
|
|
42
|
+
setup(props) {
|
|
43
|
+
const panelWidth = computed(() => {
|
|
44
|
+
return typeof props.width === "number" ? `${props.width}px` : props.width;
|
|
45
|
+
});
|
|
46
|
+
return { panelWidth };
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<style scoped>
|
|
52
|
+
.arg_drawer_container{background-color:transparent;display:flex;height:100vh;left:0;opacity:0;pointer-events:none;position:fixed;top:0;transition:background-color .35s ease,opacity .35s ease;width:100%}.arg_drawer_open{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);background-color:rgba(0,0,0,.6);opacity:1;pointer-events:auto;z-index:99}.arg_drawer_panel{background:var(--base-white,#fff);height:100%;overflow-y:auto;position:absolute;top:0;transition:transform .35s ease}.arg_drawer_right{right:0;transform:translateX(100%)}.arg_drawer_left{left:0;transform:translateX(-100%)}.arg_drawer_visible{transform:translateX(0)}
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
2
|
+
open: {
|
|
3
|
+
type: BooleanConstructor;
|
|
4
|
+
default: boolean;
|
|
5
|
+
};
|
|
6
|
+
side: {
|
|
7
|
+
type: StringConstructor;
|
|
8
|
+
default: string;
|
|
9
|
+
validator: (value: string) => boolean;
|
|
10
|
+
};
|
|
11
|
+
width: {
|
|
12
|
+
type: (StringConstructor | NumberConstructor)[];
|
|
13
|
+
default: number;
|
|
14
|
+
};
|
|
15
|
+
}>, {
|
|
16
|
+
panelWidth: import("vue").ComputedRef<string>;
|
|
17
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "onClose"[], "onClose", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
18
|
+
open: {
|
|
19
|
+
type: BooleanConstructor;
|
|
20
|
+
default: boolean;
|
|
21
|
+
};
|
|
22
|
+
side: {
|
|
23
|
+
type: StringConstructor;
|
|
24
|
+
default: string;
|
|
25
|
+
validator: (value: string) => boolean;
|
|
26
|
+
};
|
|
27
|
+
width: {
|
|
28
|
+
type: (StringConstructor | NumberConstructor)[];
|
|
29
|
+
default: number;
|
|
30
|
+
};
|
|
31
|
+
}>> & Readonly<{
|
|
32
|
+
onOnClose?: ((...args: any[]) => any) | undefined;
|
|
33
|
+
}>, {
|
|
34
|
+
width: string | number;
|
|
35
|
+
open: boolean;
|
|
36
|
+
side: string;
|
|
37
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
38
|
+
export default _default;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="arg_login_landing">
|
|
3
|
+
<!-- Animated background blobs -->
|
|
4
|
+
<div class="arg_login_background">
|
|
5
|
+
<div class="arg_login_blob arg_login_blob_1"></div>
|
|
6
|
+
<div class="arg_login_blob arg_login_blob_2"></div>
|
|
7
|
+
<div class="arg_login_blob arg_login_blob_3"></div>
|
|
8
|
+
<div class="arg_login_blob arg_login_blob_4"></div>
|
|
9
|
+
<div class="arg_login_blob arg_login_blob_5"></div>
|
|
10
|
+
<div class="arg_login_blob arg_login_blob_6"></div>
|
|
11
|
+
<div class="arg_login_blob arg_login_blob_7"></div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div class="arg_login_content">
|
|
15
|
+
<div class="arg_login_card">
|
|
16
|
+
<!-- Logo -->
|
|
17
|
+
<div class="arg_login_logo">
|
|
18
|
+
<slot name="logo">
|
|
19
|
+
<span v-if="appEmoji" class="arg_login_logo_emoji">{{ appEmoji }}</span>
|
|
20
|
+
</slot>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<!-- Title -->
|
|
24
|
+
<h1 class="arg_login_title">{{ appName }}</h1>
|
|
25
|
+
<p v-if="appSubtitle" class="arg_login_subtitle">{{ appSubtitle }}</p>
|
|
26
|
+
|
|
27
|
+
<!-- Description -->
|
|
28
|
+
<p v-if="appDescription" class="arg_login_description">{{ appDescription }}</p>
|
|
29
|
+
|
|
30
|
+
<!-- Sign-in button -->
|
|
31
|
+
<button
|
|
32
|
+
class="arg_login_button"
|
|
33
|
+
:disabled="loading"
|
|
34
|
+
@click="$emit('onLogin')"
|
|
35
|
+
>
|
|
36
|
+
<svg
|
|
37
|
+
v-if="!loading"
|
|
38
|
+
class="arg_login_button_icon"
|
|
39
|
+
fill="none"
|
|
40
|
+
stroke="currentColor"
|
|
41
|
+
viewBox="0 0 24 24"
|
|
42
|
+
>
|
|
43
|
+
<path
|
|
44
|
+
stroke-linecap="round"
|
|
45
|
+
stroke-linejoin="round"
|
|
46
|
+
stroke-width="2"
|
|
47
|
+
d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1"
|
|
48
|
+
/>
|
|
49
|
+
</svg>
|
|
50
|
+
<span v-if="loading" class="arg_login_spinner"></span>
|
|
51
|
+
{{ buttonLabel }}
|
|
52
|
+
</button>
|
|
53
|
+
|
|
54
|
+
<!-- Features grid -->
|
|
55
|
+
<div v-if="features.length > 0" class="arg_login_features">
|
|
56
|
+
<div
|
|
57
|
+
v-for="(feature, index) in features"
|
|
58
|
+
:key="index"
|
|
59
|
+
class="arg_login_feature"
|
|
60
|
+
>
|
|
61
|
+
<div class="arg_login_feature_icon">{{ feature.icon }}</div>
|
|
62
|
+
<span>{{ feature.label }}</span>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<!-- Default slot for extra content below the card -->
|
|
68
|
+
<slot />
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</template>
|
|
72
|
+
|
|
73
|
+
<script setup lang="ts">
|
|
74
|
+
interface Feature {
|
|
75
|
+
icon: string;
|
|
76
|
+
label: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
withDefaults(
|
|
80
|
+
defineProps<{
|
|
81
|
+
appName?: string;
|
|
82
|
+
appSubtitle?: string;
|
|
83
|
+
appDescription?: string;
|
|
84
|
+
appEmoji?: string;
|
|
85
|
+
buttonLabel?: string;
|
|
86
|
+
loading?: boolean;
|
|
87
|
+
features?: Feature[];
|
|
88
|
+
}>(),
|
|
89
|
+
{
|
|
90
|
+
appName: "Application",
|
|
91
|
+
appSubtitle: "",
|
|
92
|
+
appDescription: "",
|
|
93
|
+
appEmoji: "",
|
|
94
|
+
buttonLabel: "Sign in to Continue",
|
|
95
|
+
loading: false,
|
|
96
|
+
features: () => [],
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
defineEmits<{
|
|
101
|
+
onLogin: [];
|
|
102
|
+
}>();
|
|
103
|
+
</script>
|
|
104
|
+
|
|
105
|
+
<style scoped>
|
|
106
|
+
.arg_login_landing{align-items:center;background:linear-gradient(135deg,#f8fafc,#e0e7ff 50%,#ddd6fe);display:flex;justify-content:center;min-height:100vh;overflow:hidden;position:relative}.arg_login_background{inset:0;overflow:hidden;position:absolute}.arg_login_blob{animation:arg_login_float 20s ease-in-out infinite;border-radius:50%;filter:blur(150px);opacity:.5;position:absolute}.arg_login_blob_1{background:linear-gradient(135deg,#1e3a8a,#3b82f6);height:900px;left:-200px;top:-300px;width:900px}.arg_login_blob_2{animation-delay:-7s;background:linear-gradient(135deg,#ec4899,#f472b6);bottom:-250px;height:800px;right:-200px;width:800px}.arg_login_blob_3{animation-delay:-14s;background:linear-gradient(135deg,#8b5cf6,#a78bfa);height:700px;left:50%;top:50%;transform:translate(-50%,-50%);width:700px}.arg_login_blob_4{animation-delay:-10s;background:linear-gradient(135deg,#06b6d4,#67e8f9);height:600px;left:5%;top:60%;width:600px}.arg_login_blob_5{animation-delay:-5s;background:linear-gradient(135deg,#3b82f6,#60a5fa);height:550px;right:10%;top:10%;width:550px}.arg_login_blob_6{animation-delay:-12s;background:linear-gradient(135deg,#a855f7,#c084fc);bottom:20%;height:500px;left:20%;width:500px}.arg_login_blob_7{animation-delay:-3s;background:linear-gradient(135deg,#ec4899,#f472b6);height:450px;left:35%;top:5%;width:450px}@keyframes arg_login_float{0%,to{transform:translate(0) scale(1)}25%{transform:translate(30px,-30px) scale(1.05)}50%{transform:translate(-20px,20px) scale(.95)}75%{transform:translate(-30px,-20px) scale(1.02)}}.arg_login_content{max-width:480px;padding:24px;position:relative;width:100%;z-index:10}.arg_login_card{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background:hsla(0,0%,100%,.95);border:1px solid hsla(0,0%,100%,.8);border-radius:24px;box-shadow:0 25px 50px -12px rgba(0,0,0,.15);padding:48px 40px;text-align:center}.arg_login_logo{align-items:center;background:linear-gradient(135deg,#6366f1,#4f46e5);border-radius:20px;box-shadow:0 10px 40px -10px rgba(99,102,241,.5);display:flex;height:80px;justify-content:center;margin:0 auto 24px;width:80px}.arg_login_logo_emoji{font-size:40px}.arg_login_title{color:#1e293b;font-size:36px;font-weight:800;letter-spacing:-.5px;margin:0 0 4px}.arg_login_subtitle{color:#6366f1;font-size:14px;font-weight:600;letter-spacing:2px;margin:0 0 24px;text-transform:uppercase}.arg_login_description{color:#64748b;font-size:16px;line-height:1.6;margin:0 0 32px}.arg_login_button{align-items:center;background:linear-gradient(135deg,#6366f1,#4f46e5);border:none;border-radius:12px;box-shadow:0 4px 15px -3px rgba(99,102,241,.4);color:#fff;cursor:pointer;display:inline-flex;font-size:16px;font-weight:600;gap:10px;justify-content:center;padding:16px 32px;transition:all .3s ease;width:100%}.arg_login_button:hover:not(:disabled){box-shadow:0 8px 25px -5px rgba(99,102,241,.5);transform:translateY(-2px)}.arg_login_button:active:not(:disabled){transform:translateY(0)}.arg_login_button:disabled{cursor:not-allowed;opacity:.7}.arg_login_button_icon,.arg_login_spinner{height:20px;width:20px}.arg_login_spinner{animation:arg_login_spin .6s linear infinite;border:2px solid hsla(0,0%,100%,.3);border-radius:50%;border-top-color:#fff}@keyframes arg_login_spin{to{transform:rotate(1turn)}}.arg_login_features{border-top:1px solid #e2e8f0;display:grid;gap:16px;grid-template-columns:repeat(2,1fr);margin-top:32px;padding-top:32px}.arg_login_feature{align-items:center;color:#475569;display:flex;font-size:14px;font-weight:500;gap:10px}.arg_login_feature_icon{align-items:center;background:linear-gradient(135deg,#ede9fe,#e0e7ff);border-radius:10px;display:flex;flex-shrink:0;font-size:18px;height:36px;justify-content:center;width:36px}@media (max-width:480px){.arg_login_card{padding:32px 24px}.arg_login_title{font-size:28px}.arg_login_features{grid-template-columns:1fr}}
|
|
107
|
+
</style>
|
|
@@ -6,16 +6,25 @@
|
|
|
6
6
|
isSource ? 'set-width' : '',
|
|
7
7
|
]"
|
|
8
8
|
>
|
|
9
|
-
<div
|
|
10
|
-
<
|
|
9
|
+
<div class="arg_modal" :class="[isSource ? 'row' : 'col', open ? 'arg_modal_visible' : '']">
|
|
10
|
+
<div v-if="$slots.header" class="arg_modal_header">
|
|
11
|
+
<slot name="header" />
|
|
12
|
+
<div class="arg_modal_close" @click="$emit('onClose')">
|
|
13
|
+
<arg-icon name="X" size="16" color="var(--dark)" />
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="arg_modal_body" :class="{ 'no-header': !$slots.header, 'no-footer': !$slots.footer }">
|
|
17
|
+
<slot />
|
|
18
|
+
</div>
|
|
19
|
+
<div v-if="$slots.footer" class="arg_modal_footer">
|
|
20
|
+
<slot name="footer" />
|
|
21
|
+
</div>
|
|
11
22
|
</div>
|
|
12
23
|
</div>
|
|
13
24
|
</template>
|
|
14
25
|
|
|
15
26
|
<script>
|
|
16
|
-
import {
|
|
17
|
-
defineComponent
|
|
18
|
-
} from "vue";
|
|
27
|
+
import { defineComponent } from "vue";
|
|
19
28
|
export default defineComponent({
|
|
20
29
|
name: "argModal",
|
|
21
30
|
props: {
|
|
@@ -27,9 +36,10 @@ export default defineComponent({
|
|
|
27
36
|
type: Boolean,
|
|
28
37
|
default: false
|
|
29
38
|
}
|
|
30
|
-
}
|
|
39
|
+
},
|
|
40
|
+
emits: ["onClose"]
|
|
31
41
|
});
|
|
32
42
|
</script>
|
|
33
43
|
<style scoped>
|
|
34
|
-
.arg_modal_container{align-items:center;background-color:transparent;
|
|
44
|
+
.arg_modal_container{align-items:center;background-color:transparent;display:flex;flex-direction:column;height:100vh;justify-content:center;left:0;opacity:0;pointer-events:none;position:fixed;top:0;transition:background-color .35s ease,opacity .35s ease;width:100%}.arg_modal_open{-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);background-color:rgba(0,0,0,.6);opacity:1;pointer-events:auto;z-index:99}.arg_modal{align-items:flex-start;background:var(--base-white,#fff);border-radius:12px;display:flex;flex-shrink:0;height:100%;opacity:0;transform:scale(.95);transition:transform .35s ease,opacity .35s ease;width:100%}.arg_modal_visible{opacity:1;transform:scale(1)}.arg_modal.row{flex-direction:row;max-height:711px;max-width:1014px}.arg_modal.col{flex-direction:column;max-height:663px;max-width:966px}.arg_modal_open.set-width{padding:0 15%;width:70%}.arg_modal_header{align-items:center;align-self:stretch;border-bottom:1px solid var(--light,#ececf2);display:flex;justify-content:space-between;padding:24px}.arg_modal_body{align-self:stretch;flex:1;overflow-y:auto;padding:24px}.arg_modal_body.no-header.no-footer{overflow-y:visible;padding:0}.arg_modal_footer{align-items:center;align-self:stretch;border-top:1px solid var(--light,#ececf2);display:flex;gap:16px;padding:24px}.arg_modal_close{align-items:center;border-radius:4px;cursor:pointer;display:flex;justify-content:center;padding:6px}.arg_modal_close:hover{background-color:var(--lightest,#f5f5fa)}
|
|
35
45
|
</style>
|
|
@@ -7,7 +7,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
7
7
|
type: BooleanConstructor;
|
|
8
8
|
default: boolean;
|
|
9
9
|
};
|
|
10
|
-
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin,
|
|
10
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "onClose"[], "onClose", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
11
11
|
open: {
|
|
12
12
|
type: BooleanConstructor;
|
|
13
13
|
default: boolean;
|
|
@@ -16,7 +16,9 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
16
16
|
type: BooleanConstructor;
|
|
17
17
|
default: boolean;
|
|
18
18
|
};
|
|
19
|
-
}>> & Readonly<{
|
|
19
|
+
}>> & Readonly<{
|
|
20
|
+
onOnClose?: ((...args: any[]) => any) | undefined;
|
|
21
|
+
}>, {
|
|
20
22
|
open: boolean;
|
|
21
23
|
isSource: boolean;
|
|
22
24
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="arg_no_license_landing">
|
|
3
|
+
<!-- Animated background blobs -->
|
|
4
|
+
<div class="arg_no_license_background">
|
|
5
|
+
<div class="arg_no_license_blob arg_no_license_blob_1"></div>
|
|
6
|
+
<div class="arg_no_license_blob arg_no_license_blob_2"></div>
|
|
7
|
+
<div class="arg_no_license_blob arg_no_license_blob_3"></div>
|
|
8
|
+
<div class="arg_no_license_blob arg_no_license_blob_4"></div>
|
|
9
|
+
<div class="arg_no_license_blob arg_no_license_blob_5"></div>
|
|
10
|
+
<div class="arg_no_license_blob arg_no_license_blob_6"></div>
|
|
11
|
+
<div class="arg_no_license_blob arg_no_license_blob_7"></div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div class="arg_no_license_content">
|
|
15
|
+
<div class="arg_no_license_card">
|
|
16
|
+
<!-- Icon -->
|
|
17
|
+
<div class="arg_no_license_icon_container">
|
|
18
|
+
<slot name="icon">
|
|
19
|
+
<svg
|
|
20
|
+
class="arg_no_license_icon"
|
|
21
|
+
fill="none"
|
|
22
|
+
stroke="currentColor"
|
|
23
|
+
viewBox="0 0 24 24"
|
|
24
|
+
>
|
|
25
|
+
<path
|
|
26
|
+
stroke-linecap="round"
|
|
27
|
+
stroke-linejoin="round"
|
|
28
|
+
stroke-width="2"
|
|
29
|
+
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
|
|
30
|
+
/>
|
|
31
|
+
</svg>
|
|
32
|
+
</slot>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<!-- Title -->
|
|
36
|
+
<h1 class="arg_no_license_title">{{ title }}</h1>
|
|
37
|
+
|
|
38
|
+
<!-- Description -->
|
|
39
|
+
<p class="arg_no_license_description">
|
|
40
|
+
<template v-if="description">{{ description }}</template>
|
|
41
|
+
<template v-else>
|
|
42
|
+
You need a <strong>{{ appName }}</strong> license to access this application.
|
|
43
|
+
</template>
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
<!-- Default slot for action content -->
|
|
47
|
+
<slot />
|
|
48
|
+
|
|
49
|
+
<!-- Footer slot -->
|
|
50
|
+
<div v-if="$slots.footer" class="arg_no_license_footer">
|
|
51
|
+
<slot name="footer" />
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<script setup lang="ts">
|
|
59
|
+
withDefaults(
|
|
60
|
+
defineProps<{
|
|
61
|
+
appName?: string;
|
|
62
|
+
title?: string;
|
|
63
|
+
description?: string;
|
|
64
|
+
}>(),
|
|
65
|
+
{
|
|
66
|
+
appName: "Application",
|
|
67
|
+
title: "License Required",
|
|
68
|
+
description: "",
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<style scoped>
|
|
74
|
+
.arg_no_license_landing{align-items:center;background:linear-gradient(135deg,#f8fafc,#e0e7ff 50%,#ddd6fe);display:flex;justify-content:center;min-height:100vh;overflow:hidden;position:relative}.arg_no_license_background{inset:0;overflow:hidden;position:absolute}.arg_no_license_blob{animation:arg_no_license_float 20s ease-in-out infinite;border-radius:50%;filter:blur(150px);opacity:.5;position:absolute}.arg_no_license_blob_1{background:linear-gradient(135deg,#1e3a8a,#3b82f6);height:900px;left:-200px;top:-300px;width:900px}.arg_no_license_blob_2{animation-delay:-7s;background:linear-gradient(135deg,#ec4899,#f472b6);bottom:-250px;height:800px;right:-200px;width:800px}.arg_no_license_blob_3{animation-delay:-14s;background:linear-gradient(135deg,#8b5cf6,#a78bfa);height:700px;left:50%;top:50%;transform:translate(-50%,-50%);width:700px}.arg_no_license_blob_4{animation-delay:-10s;background:linear-gradient(135deg,#06b6d4,#67e8f9);height:600px;left:5%;top:60%;width:600px}.arg_no_license_blob_5{animation-delay:-5s;background:linear-gradient(135deg,#3b82f6,#60a5fa);height:550px;right:10%;top:10%;width:550px}.arg_no_license_blob_6{animation-delay:-12s;background:linear-gradient(135deg,#a855f7,#c084fc);bottom:20%;height:500px;left:20%;width:500px}.arg_no_license_blob_7{animation-delay:-3s;background:linear-gradient(135deg,#ec4899,#f472b6);height:450px;left:35%;top:5%;width:450px}@keyframes arg_no_license_float{0%,to{transform:translate(0) scale(1)}25%{transform:translate(30px,-30px) scale(1.05)}50%{transform:translate(-20px,20px) scale(.95)}75%{transform:translate(-30px,-20px) scale(1.02)}}.arg_no_license_content{max-width:480px;padding:24px;position:relative;width:100%;z-index:10}.arg_no_license_card{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background:hsla(0,0%,100%,.95);border:1px solid hsla(0,0%,100%,.8);border-radius:24px;box-shadow:0 25px 50px -12px rgba(0,0,0,.15);padding:48px 40px;text-align:center}.arg_no_license_icon_container{align-items:center;background:linear-gradient(135deg,#f59e0b,#d97706);border-radius:20px;box-shadow:0 10px 40px -10px rgba(245,158,11,.5);display:flex;height:80px;justify-content:center;margin:0 auto 1.5rem;width:80px}.arg_no_license_icon{color:#fff;height:40px;width:40px}.arg_no_license_title{color:#1f2937;font-size:1.75rem;font-weight:700;margin:0 0 1rem}.arg_no_license_description{color:#6b7280;font-size:1rem;line-height:1.6;margin:0 0 1.5rem}.arg_no_license_description strong{color:#6366f1}.arg_no_license_footer{border-top:1px solid #e5e7eb;display:flex;gap:.75rem;justify-content:center;margin-top:1.5rem;padding-top:1.5rem}@media (max-width:480px){.arg_no_license_card{padding:32px 24px}.arg_no_license_title{font-size:1.5rem}}
|
|
75
|
+
</style>
|