build: switch from yarn to npm to manage js dependencies and move js contents to root

yarn v1 is being deprecated and starts to have some issues

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2023-11-14 17:24:42 +01:00
parent 32055122c3
commit 2e72f6faf4
595 changed files with 12078 additions and 7843 deletions

View File

@@ -0,0 +1,157 @@
<template>
<div class="">
<header class="" v-if="title">
<h2 class="">{{ title }}</h2>
</header>
<section :class="{ 'flex gap-1': hasIcon }">
<div class="" v-if="hasIcon && (icon || iconByType)">
<o-icon
:icon="icon ? icon : iconByType"
:variant="variant"
:both="!icon"
custom-size="48"
/>
</div>
<div class="">
<p>
<template v-if="$slots.default">
<slot />
</template>
<template v-else>
<div v-html="message" />
</template>
</p>
<o-field v-if="hasInput">
<o-input
v-model="prompt"
expanded
class="input"
ref="input"
v-bind="inputAttrs"
@keydown.enter="confirm"
autofocus
/>
</o-field>
</div>
</section>
<footer v-if="canCancel" class="flex gap-2 my-2">
<o-button ref="cancelButton" outlined @click="cancel('button')">{{
cancelText ?? t("Cancel")
}}</o-button>
<o-button :variant="variant" ref="confirmButton" @click="confirm">{{
confirmText ?? t("Confirm")
}}</o-button>
</footer>
</div>
</template>
<script lang="ts" setup>
import { useFocus } from "@vueuse/core";
import { computed, nextTick, ref } from "vue";
import { useI18n } from "vue-i18n";
const props = withDefaults(
defineProps<{
title: string;
message: string | string[];
icon?: string;
hasIcon?: boolean;
variant?: string;
size?: string;
canCancel?: boolean;
confirmText?: string;
cancelText?: string;
onConfirm: (prompt?: string) => any;
onCancel?: (source: string) => any;
ariaLabel?: string;
ariaModal?: boolean;
ariaRole?: string;
hasInput?: boolean;
inputAttrs?: Record<string, any>;
}>(),
{
variant: "primary",
canCancel: true,
hasInput: false,
inputAttrs: () => ({}),
}
);
const emit = defineEmits(["confirm", "cancel", "close"]);
const { t } = useI18n({ useScope: "global" });
const hasInput = computed(() => props.hasInput);
const onConfirm = computed(() => props.onConfirm);
const onCancel = computed(() => props.onCancel);
const inputAttrs = computed(() => props.inputAttrs);
// const modalOpened = ref(false);
const prompt = ref<string>(hasInput.value ? inputAttrs.value.value ?? "" : "");
const input = ref();
// https://github.com/oruga-ui/oruga/issues/339
const promptInputComp = computed(() => input.value?.$refs.input);
if (hasInput.value) {
useFocus(promptInputComp, { initialValue: true });
}
// const dialogClass = computed(() => {
// return [props.size];
// });
/**
* Icon name (MDI) based on the type.
*/
const iconByType = computed(() => {
switch (props.variant) {
case "info":
return "information";
case "success":
return "check-circle";
case "warning":
return "alert";
case "danger":
return "alert-circle";
default:
return null;
}
});
/**
* If it's a prompt Dialog, validate the input.
* Call the onConfirm prop (function) and close the Dialog.
*/
const confirm = () => {
console.debug("dialog confirmed", input.value?.$el);
if (input.value !== undefined) {
const inputElement = input.value.$el.querySelector("input");
if (!inputElement.checkValidity()) {
nextTick(() => inputElement.select());
return;
}
}
onConfirm.value(prompt.value);
close();
};
/**
* Close the Dialog.
*/
const close = () => {
emit("close");
};
/**
* Close the Modal if canCancel and call the onCancel prop (function).
*/
const cancel = (source: string) => {
emit("cancel", source);
if (onCancel.value) {
onCancel.value(source);
}
close();
};
</script>

View File

@@ -0,0 +1,104 @@
<template>
<transition enter-active-class="fadeInUp" leave-active-class="fadeOut">
<div
v-show="isActive"
class="snackbar"
:class="[variant, position]"
@mouseenter="pause"
@mouseleave="removePause"
:role="actionTextWithDefault ? 'alertdialog' : 'alert'"
>
<template v-if="$slots.default">
<slot />
</template>
<template v-else>
<div class="text" v-html="message" />
</template>
<div class="flex gap-2">
<div v-if="cancelText" class="action light cancel" @click="close">
<o-button>{{ cancelText }}</o-button>
</div>
<div
v-if="actionTextWithDefault"
class="action"
@click="action"
:class="variant"
>
<o-button>{{ actionTextWithDefault }}</o-button>
</div>
</div>
</div>
</transition>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref } from "vue";
import { useI18n } from "vue-i18n";
type positionValues =
| "top-right"
| "top"
| "top-left"
| "bottom-right"
| "bottom"
| "bottom-left";
const props = withDefaults(
defineProps<{
message: string;
actionText?: string;
onAction?: () => any;
cancelText?: string | null;
variant?: string;
position?: positionValues;
pauseOnHover?: boolean;
indefinite?: boolean;
}>(),
{
onAction: () => {
// do nothing
},
cancelText: null,
variant: "dark",
position: "bottom-right",
pauseOnHover: false,
indefinite: false,
}
);
const emit = defineEmits(["close"]);
const { t } = useI18n({ useScope: "global" });
const actionTextWithDefault = computed(() => props.actionText ?? t("OK"));
const isActive = ref(false);
const isPaused = ref(false);
const timer = ref(0);
onMounted(() => {
isActive.value = true;
});
const pause = () => {
isPaused.value = true;
};
const removePause = () => {
if (props.pauseOnHover && !props.indefinite) {
isPaused.value = false;
close();
}
};
const action = () => {
props.onAction();
};
const close = () => {
if (!isPaused.value) {
clearTimeout(timer.value);
isActive.value = false;
emit("close");
}
};
</script>

View File

@@ -0,0 +1,39 @@
<template>
<a
v-if="isInternal"
:target="newTab ? '_blank' : undefined"
:href="href"
rel="noopener noreferrer"
v-bind="$attrs"
>
<slot />
</a>
<router-link :to="to" v-bind="$attrs" v-else>
<slot />
</router-link>
</template>
<script lang="ts">
// use normal <script> to declare options
export default {
inheritAttrs: false,
};
</script>
<script lang="ts" setup>
import { computed } from "vue";
const props = withDefaults(
defineProps<{
to: { name: string; params?: any; query?: any } | string;
isInternal?: boolean;
newTab?: boolean;
}>(),
{ isInternal: true, newTab: true }
);
const href = computed(() => {
if (typeof props.to === "string" || props.to instanceof String) {
return props.to as string;
}
return undefined;
});
</script>

View File

@@ -0,0 +1,16 @@
<template>
<Story :layout="{ type: 'grid', width: 60 }">
<Variant title="Google">
<MaterialIcon :icon="['', 'google']" />
</Variant>
<Variant title="Calendar">
<MaterialIcon :icon="['', 'calendar']" />
</Variant>
<Variant title="Account Multiple Plus">
<MaterialIcon :icon="['', 'account-multiple-plus']" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import MaterialIcon from "./MaterialIcon.vue";
</script>

View File

@@ -0,0 +1,296 @@
<template>
<component
:is="componentInstance"
v-if="componentInstance"
:size="realSize"
/>
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent } from "vue";
const icons: Record<string, () => Promise<any>> = {
FormatBold: () =>
import(`../../../node_modules/vue-material-design-icons/FormatBold.vue`),
FormatItalic: () =>
import(`../../../node_modules/vue-material-design-icons/FormatItalic.vue`),
FormatUnderline: () =>
import(
`../../../node_modules/vue-material-design-icons/FormatUnderline.vue`
),
FormatHeader1: () =>
import(`../../../node_modules/vue-material-design-icons/FormatHeader1.vue`),
FormatHeader2: () =>
import(`../../../node_modules/vue-material-design-icons/FormatHeader2.vue`),
FormatHeader3: () =>
import(`../../../node_modules/vue-material-design-icons/FormatHeader3.vue`),
Link: () =>
import(`../../../node_modules/vue-material-design-icons/Link.vue`),
LinkOff: () =>
import(`../../../node_modules/vue-material-design-icons/LinkOff.vue`),
Image: () =>
import(`../../../node_modules/vue-material-design-icons/Image.vue`),
FormatListBulleted: () =>
import(
`../../../node_modules/vue-material-design-icons/FormatListBulleted.vue`
),
FormatListNumbered: () =>
import(
`../../../node_modules/vue-material-design-icons/FormatListNumbered.vue`
),
FormatQuoteClose: () =>
import(
`../../../node_modules/vue-material-design-icons/FormatQuoteClose.vue`
),
Undo: () =>
import(`../../../node_modules/vue-material-design-icons/Undo.vue`),
Redo: () =>
import(`../../../node_modules/vue-material-design-icons/Redo.vue`),
AccountCircle: () =>
import(`../../../node_modules/vue-material-design-icons/AccountCircle.vue`),
Upload: () =>
import(`../../../node_modules/vue-material-design-icons/Upload.vue`),
Chat: () =>
import(`../../../node_modules/vue-material-design-icons/Chat.vue`),
Calendar: () =>
import(`../../../node_modules/vue-material-design-icons/Calendar.vue`),
Cog: () => import(`../../../node_modules/vue-material-design-icons/Cog.vue`),
AccountMultiplePlus: () =>
import(
`../../../node_modules/vue-material-design-icons/AccountMultiplePlus.vue`
),
AccountMultipleMinus: () =>
import(
`../../../node_modules/vue-material-design-icons/AccountMultipleMinus.vue`
),
AccountMultiple: () =>
import(
`../../../node_modules/vue-material-design-icons/AccountMultiple.vue`
),
Bullhorn: () =>
import(`../../../node_modules/vue-material-design-icons/Bullhorn.vue`),
Delete: () =>
import(`../../../node_modules/vue-material-design-icons/Delete.vue`),
Alert: () =>
import(`../../../node_modules/vue-material-design-icons/Alert.vue`),
ChevronDown: () =>
import(`../../../node_modules/vue-material-design-icons/ChevronDown.vue`),
ChevronUp: () =>
import(`../../../node_modules/vue-material-design-icons/ChevronUp.vue`),
ChevronLeft: () =>
import(`../../../node_modules/vue-material-design-icons/ChevronLeft.vue`),
ChevronRight: () =>
import(`../../../node_modules/vue-material-design-icons/ChevronRight.vue`),
Reply: () =>
import(`../../../node_modules/vue-material-design-icons/Reply.vue`),
DotsHorizontal: () =>
import(
`../../../node_modules/vue-material-design-icons/DotsHorizontal.vue`
),
Pencil: () =>
import(`../../../node_modules/vue-material-design-icons/Pencil.vue`),
Flag: () =>
import(`../../../node_modules/vue-material-design-icons/Flag.vue`),
ContentPaste: () =>
import(`../../../node_modules/vue-material-design-icons/ContentPaste.vue`),
Lock: () =>
import(`../../../node_modules/vue-material-design-icons/Lock.vue`),
Google: () =>
import(`../../../node_modules/vue-material-design-icons/Google.vue`),
MenuDown: () =>
import(`../../../node_modules/vue-material-design-icons/MenuDown.vue`),
MenuUp: () =>
import(`../../../node_modules/vue-material-design-icons/MenuUp.vue`),
Check: () =>
import(`../../../node_modules/vue-material-design-icons/Check.vue`),
TimerSandEmpty: () =>
import(
`../../../node_modules/vue-material-design-icons/TimerSandEmpty.vue`
),
Earth: () =>
import(`../../../node_modules/vue-material-design-icons/Earth.vue`),
Map: () => import(`../../../node_modules/vue-material-design-icons/Map.vue`),
MapMarker: () =>
import(`../../../node_modules/vue-material-design-icons/MapMarker.vue`),
Close: () =>
import(`../../../node_modules/vue-material-design-icons/Close.vue`),
Magnify: () =>
import(`../../../node_modules/vue-material-design-icons/Magnify.vue`),
Loading: () =>
import(`../../../node_modules/vue-material-design-icons/Loading.vue`),
Eye: () => import(`../../../node_modules/vue-material-design-icons/Eye.vue`),
EyeOff: () =>
import(`../../../node_modules/vue-material-design-icons/EyeOff.vue`),
AlertCircle: () =>
import(`../../../node_modules/vue-material-design-icons/AlertCircle.vue`),
Rss: () => import(`../../../node_modules/vue-material-design-icons/Rss.vue`),
CalendarSync: () =>
import(`../../../node_modules/vue-material-design-icons/CalendarSync.vue`),
OpenInNew: () =>
import(`../../../node_modules/vue-material-design-icons/OpenInNew.vue`),
Home: () =>
import(`../../../node_modules/vue-material-design-icons/Home.vue`),
Send: () =>
import(`../../../node_modules/vue-material-design-icons/Send.vue`),
Comment: () =>
import(`../../../node_modules/vue-material-design-icons/Comment.vue`),
Label: () =>
import(`../../../node_modules/vue-material-design-icons/Label.vue`),
CalendarToday: () =>
import(`../../../node_modules/vue-material-design-icons/CalendarToday.vue`),
WheelchairAccessibility: () =>
import(
`../../../node_modules/vue-material-design-icons/WheelchairAccessibility.vue`
),
Youtube: () =>
import(`../../../node_modules/vue-material-design-icons/Youtube.vue`),
Twitch: () =>
import(`../../../node_modules/vue-material-design-icons/Twitch.vue`),
Twitter: () =>
import(`../../../node_modules/vue-material-design-icons/Twitter.vue`),
MicrosoftTeams: () =>
import(
`../../../node_modules/vue-material-design-icons/MicrosoftTeams.vue`
),
GoogleHangouts: () =>
import(
`../../../node_modules/vue-material-design-icons/GoogleHangouts.vue`
),
Webcam: () =>
import(`../../../node_modules/vue-material-design-icons/Webcam.vue`),
TicketConfirmation: () =>
import(
`../../../node_modules/vue-material-design-icons/TicketConfirmation.vue`
),
CalendarCheck: () =>
import(`../../../node_modules/vue-material-design-icons/CalendarCheck.vue`),
CalendarText: () =>
import(`../../../node_modules/vue-material-design-icons/CalendarText.vue`),
CalendarQuestion: () =>
import(
`../../../node_modules/vue-material-design-icons/CalendarQuestion.vue`
),
CalendarRemove: () =>
import(
`../../../node_modules/vue-material-design-icons/CalendarRemove.vue`
),
FileDocumentEdit: () =>
import(
`../../../node_modules/vue-material-design-icons/FileDocumentEdit.vue`
),
Subtitles: () =>
import(`../../../node_modules/vue-material-design-icons/Subtitles.vue`),
HelpCircleOutline: () =>
import(
`../../../node_modules/vue-material-design-icons/HelpCircleOutline.vue`
),
Cash: () =>
import(`../../../node_modules/vue-material-design-icons/Cash.vue`),
ArrowUp: () =>
import(`../../../node_modules/vue-material-design-icons/ArrowUp.vue`),
Share: () =>
import(`../../../node_modules/vue-material-design-icons/Share.vue`),
TimelineText: () =>
import(`../../../node_modules/vue-material-design-icons/TimelineText.vue`),
Account: () =>
import(`../../../node_modules/vue-material-design-icons/Account.vue`),
City: () =>
import(`../../../node_modules/vue-material-design-icons/City.vue`),
ChevronDoubleUp: () =>
import(
`../../../node_modules/vue-material-design-icons/ChevronDoubleUp.vue`
),
ChevronDoubleDown: () =>
import(
`../../../node_modules/vue-material-design-icons/ChevronDoubleDown.vue`
),
GoogleSpreadsheet: () =>
import(
`../../../node_modules/vue-material-design-icons/GoogleSpreadsheet.vue`
),
FilePdfBox: () =>
import(`../../../node_modules/vue-material-design-icons/FilePdfBox.vue`),
FileDelimited: () =>
import(`../../../node_modules/vue-material-design-icons/FileDelimited.vue`),
FileDocumentOutline: () =>
import(
`../../../node_modules/vue-material-design-icons/FileDocumentOutline.vue`
),
Refresh: () =>
import(`../../../node_modules/vue-material-design-icons/Refresh.vue`),
RoadVariant: () =>
import(`../../../node_modules/vue-material-design-icons/RoadVariant.vue`),
AccountGroup: () =>
import(`../../../node_modules/vue-material-design-icons/AccountGroup.vue`),
Web: () => import(`../../../node_modules/vue-material-design-icons/Web.vue`),
Email: () =>
import(`../../../node_modules/vue-material-design-icons/Email.vue`),
ChatAlert: () =>
import(`../../../node_modules/vue-material-design-icons/ChatAlert.vue`),
InboxArrowDown: () =>
import(
`../../../node_modules/vue-material-design-icons/InboxArrowDown.vue`
),
InboxArrowUp: () =>
import(`../../../node_modules/vue-material-design-icons/InboxArrowUp.vue`),
LanDisconnect: () =>
import(`../../../node_modules/vue-material-design-icons/LanDisconnect.vue`),
CloudQuestion: () =>
import(`../../../node_modules/vue-material-design-icons/CloudQuestion.vue`),
Filter: () =>
import(`../../../node_modules/vue-material-design-icons/Filter.vue`),
CheckCircle: () =>
import(`../../../node_modules/vue-material-design-icons/CheckCircle.vue`),
ViewList: () =>
import(`../../../node_modules/vue-material-design-icons/ViewList.vue`),
SmokingOff: () =>
import(`../../../node_modules/vue-material-design-icons/SmokingOff.vue`),
BellOutline: () =>
import(`../../../node_modules/vue-material-design-icons/BellOutline.vue`),
BellOffOutline: () =>
import(
`../../../node_modules/vue-material-design-icons/BellOffOutline.vue`
),
ExitToApp: () =>
import(`../../../node_modules/vue-material-design-icons/ExitToApp.vue`),
CheckboxMarked: () =>
import(
`../../../node_modules/vue-material-design-icons/CheckboxMarked.vue`
),
EyeOutline: () =>
import(`../../../node_modules/vue-material-design-icons/EyeOutline.vue`),
PencilOutline: () =>
import(`../../../node_modules/vue-material-design-icons/PencilOutline.vue`),
Apps: () =>
import(`../../../node_modules/vue-material-design-icons/Apps.vue`),
};
const props = withDefaults(
defineProps<{
icon: string[] | string;
size?: string;
type?: string;
}>(),
{ size: "18" }
);
const name = computed(() => toPascalCase(props.icon[1]));
const componentInstance = computed(() => {
if (Object.prototype.hasOwnProperty.call(icons, name.value)) {
return defineAsyncComponent(icons[name.value]);
} else {
console.error("Icon is undefined", name.value);
return undefined;
}
});
const realSize = computed(() => Number.parseInt(props.size ?? "18"));
function toPascalCase(text: string) {
return text.replace(/(^\w|-\w)/g, clearAndUpper);
}
function clearAndUpper(text: string) {
return text.replace(/-/, "").toUpperCase();
}
</script>