From 57236d814d0b2cda0c0416c6479c538823817e6c Mon Sep 17 00:00:00 2001 From: James Collins Date: Sat, 11 Feb 2023 13:39:19 +1000 Subject: [PATCH 001/155] ignore dccache --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ba18049..5bdecb9 100644 --- a/.gitignore +++ b/.gitignore @@ -237,4 +237,7 @@ dist/ ### This Project ### /public/uploads /public/build -*.key \ No newline at end of file +*.key + +### Synk ### +.dccache \ No newline at end of file -- 2.49.1 From 2b939f417cf0d2fc68ecb0b5b9f65515276b622d Mon Sep 17 00:00:00 2001 From: James Collins Date: Sat, 11 Feb 2023 17:45:28 +1000 Subject: [PATCH 002/155] top margin now handled by SMPage --- resources/js/components/SMFooter.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/js/components/SMFooter.vue b/resources/js/components/SMFooter.vue index 1111c2e..b03c366 100644 --- a/resources/js/components/SMFooter.vue +++ b/resources/js/components/SMFooter.vue @@ -88,7 +88,6 @@ .footer { flex: 0; align-items: center; - margin-top: calc(map-get($spacer, 5) * 2); font-size: 80%; background-color: #f8f8f8; padding: 0 0 map-get($spacer, 5) 0; -- 2.49.1 From ac4d3d8ad04719a9b396a5a96cae3120e0d6b6e9 Mon Sep 17 00:00:00 2001 From: James Collins Date: Sat, 11 Feb 2023 17:50:36 +1000 Subject: [PATCH 003/155] added sm prefix to classes and recaptcha ack --- resources/js/components/SMFooter.vue | 47 ++++++++++++++++++---------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/resources/js/components/SMFooter.vue b/resources/js/components/SMFooter.vue index b03c366..9df349c 100644 --- a/resources/js/components/SMFooter.vue +++ b/resources/js/components/SMFooter.vue @@ -1,6 +1,6 @@ @@ -184,12 +182,20 @@ const disconnectMutationObserver = () => { opacity: 0.75; transition: opacity 0.2s ease-in-out; - svg { + .carousel-slide-indicator-item { + height: map-get($spacer, 1); + width: map-get($spacer, 1); + border: 1px solid white; + border-radius: 50%; cursor: pointer; font-size: 80%; - padding: 0 0.25rem; + margin: 0 calc(#{map-get($spacer, 1)} / 3); color: #fff; filter: drop-shadow(0px 0px 2px rgba(0, 0, 0, 1)); + + &.highlighted { + background-color: white; + } } } } diff --git a/resources/js/components/SMCarouselSlide.vue b/resources/js/components/SMCarouselSlide.vue index 95521d6..6433c64 100644 --- a/resources/js/components/SMCarouselSlide.vue +++ b/resources/js/components/SMCarouselSlide.vue @@ -3,7 +3,7 @@ class="carousel-slide" :style="{ backgroundImage: `url('${imageUrl}')` }"> + @@ -30,6 +31,7 @@ import { SMDate } from "../helpers/datetime"; import { useApplicationStore } from "../store/ApplicationStore"; import { api } from "../helpers/api"; import SMPage from "../components/SMPage.vue"; +import SMAttachments from "../components/SMAttachments.vue"; const applicationStore = useApplicationStore(); const route = useRoute(); -- 2.49.1 From 37e59bb8a52ab693548642701c5a84f8938448c7 Mon Sep 17 00:00:00 2001 From: James Collins Date: Fri, 24 Feb 2023 14:23:18 +1000 Subject: [PATCH 112/155] updated types --- resources/js/helpers/api.types.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/resources/js/helpers/api.types.ts b/resources/js/helpers/api.types.ts index a72d3e8..12c74c4 100644 --- a/resources/js/helpers/api.types.ts +++ b/resources/js/helpers/api.types.ts @@ -12,7 +12,16 @@ export interface EventCollection { } export interface Media { + id: string; + user_id: string; + title: string; + name: string; + mime: string; + permission: Array; + size: number; url: string; + created_at: string; + updated_at: string; } export interface MediaResponse { @@ -32,6 +41,7 @@ export interface Post { content: string; publish_at: string; hero: string; + attachments: Array; } export interface PostResponse { -- 2.49.1 From 40dce90aa0ad28b309daef56ebbb89c85ce31e27 Mon Sep 17 00:00:00 2001 From: James Collins Date: Fri, 24 Feb 2023 14:41:25 +1000 Subject: [PATCH 113/155] allow download of any files in uploads or img dirs --- public/.htaccess | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/.htaccess b/public/.htaccess index 71ed5e2..083e7d0 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -4,7 +4,7 @@ - + Header set Content-Disposition "attachment" -- 2.49.1 From a82e8df06d72497355e08faaa197b70c5895ba68 Mon Sep 17 00:00:00 2001 From: James Collins Date: Fri, 24 Feb 2023 14:41:41 +1000 Subject: [PATCH 114/155] package updates --- package-lock.json | 122 +++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/package-lock.json b/package-lock.json index b6a4e5a..56813ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,9 +42,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", - "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", + "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -646,9 +646,9 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" }, "node_modules/@types/node": { - "version": "18.14.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.0.tgz", - "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==" + "version": "18.14.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.1.tgz", + "integrity": "sha512-QH+37Qds3E0eDlReeboBxfHbX9omAcBCXEzswCu6jySP642jiM3cYSIkU/REqwhCUqXdonHFuBfJDiAJxMNhaQ==" }, "node_modules/@types/semver": { "version": "7.3.13", @@ -657,14 +657,14 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz", - "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.53.0.tgz", + "integrity": "sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/type-utils": "5.52.0", - "@typescript-eslint/utils": "5.52.0", + "@typescript-eslint/scope-manager": "5.53.0", + "@typescript-eslint/type-utils": "5.53.0", + "@typescript-eslint/utils": "5.53.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -691,14 +691,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz", - "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.53.0.tgz", + "integrity": "sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.53.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/typescript-estree": "5.53.0", "debug": "^4.3.4" }, "engines": { @@ -718,13 +718,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", - "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz", + "integrity": "sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0" + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -735,13 +735,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz", - "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.53.0.tgz", + "integrity": "sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.52.0", - "@typescript-eslint/utils": "5.52.0", + "@typescript-eslint/typescript-estree": "5.53.0", + "@typescript-eslint/utils": "5.53.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -762,9 +762,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", - "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.53.0.tgz", + "integrity": "sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -775,13 +775,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", - "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz", + "integrity": "sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/visitor-keys": "5.53.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -802,16 +802,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", - "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.53.0.tgz", + "integrity": "sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.53.0", + "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/typescript-estree": "5.53.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -828,12 +828,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", - "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz", + "integrity": "sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/types": "5.53.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1745,9 +1745,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.302", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.302.tgz", - "integrity": "sha512-Uk7C+7aPBryUR1Fwvk9VmipBcN9fVsqBO57jV2ZjTm+IZ6BMNqu7EDVEg2HxCNufk6QcWlFsBkhQyQroB2VWKw==", + "version": "1.4.310", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.310.tgz", + "integrity": "sha512-/xlATgfwkm5uDDwLw5nt/MNEf7c1oazLURMZLy39vOioGYyYzLWIDT8fZMJak6qTiAJ7udFTy7JG7ziyjNutiA==", "peer": true }, "node_modules/emoji-regex": { @@ -2991,9 +2991,9 @@ } }, "node_modules/pinia": { - "version": "2.0.31", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.31.tgz", - "integrity": "sha512-6OOKZGX79jm3q0xAu+X/PaRjfyOcFnPXcHFAA8HHa+wbJeSi5xc/nYqO8Ff7XLvwV8mKGYXcUfZUHbqUmw6P0w==", + "version": "2.0.32", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.32.tgz", + "integrity": "sha512-8Tw4OrpCSJ028UUyp0gYPP/wyjigLoEceuO/x1G+FlHVf73337e5vLm4uDmrRIoBG1hvaed/eSHnrCFjOc4nkA==", "dependencies": { "@vue/devtools-api": "^6.5.0", "vue-demi": "*" @@ -3598,9 +3598,9 @@ } }, "node_modules/terser": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.4.tgz", - "integrity": "sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug==", + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.5.tgz", + "integrity": "sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==", "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.2", @@ -3672,9 +3672,9 @@ "dev": true }, "node_modules/tinymce": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.3.1.tgz", - "integrity": "sha512-+oCwXuTxAdJXVJ0130OxQz0JDNsqg3deuzgeUo8X5Vb27EzCJgXwO5eWvCxvkxpQo4oiHMVlM4tUIpTUHufHGQ==" + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.3.2.tgz", + "integrity": "sha512-nOVHk4FhHKQj48hi7fEptS1Se6CNzPtfIcDzTO70KoTcSiQIFzhhZjS5bPotSzFnQ4dIQJ4QPOd7sqNs6fXUrA==" }, "node_modules/tinypool": { "version": "0.3.1", @@ -3868,9 +3868,9 @@ "dev": true }, "node_modules/vite": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.3.tgz", - "integrity": "sha512-0Zqo4/Fr/swSOBmbl+HAAhOjrqNwju+yTtoe4hQX9UsARdcuc9njyOdr6xU0DDnV7YP0RT6mgTTOiRtZgxfCxA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.4.tgz", + "integrity": "sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==", "dependencies": { "esbuild": "^0.16.14", "postcss": "^8.4.21", -- 2.49.1 From c3bb2179b1ec1f8c0f080bc7a19835a2471644c9 Mon Sep 17 00:00:00 2001 From: James Collins Date: Fri, 24 Feb 2023 15:05:57 +1000 Subject: [PATCH 115/155] remove unused label --- resources/js/components/SMEditor.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/js/components/SMEditor.vue b/resources/js/components/SMEditor.vue index 138d0bc..eab61c2 100644 --- a/resources/js/components/SMEditor.vue +++ b/resources/js/components/SMEditor.vue @@ -1,6 +1,5 @@ @@ -97,7 +110,9 @@ import SMMessage from "../SMMessage.vue"; import SMModal from "../SMModal.vue"; import { api } from "../../helpers/api"; import { bytesReadable } from "../../helpers/types"; -import { Media } from "../../helpers/api.types"; +import { getFilePreview } from "../../helpers/utils"; +import { Media, MediaCollection, MediaResponse } from "../../helpers/api.types"; +import SMLoadingIcon from "../SMLoadingIcon.vue"; const props = defineProps({ mime: { @@ -105,141 +120,337 @@ const props = defineProps({ default: "image/", required: false, }, + accepts: { + type: String, + default: "image/*", + required: false, + }, + allowUpload: { + type: Boolean, + default: true, + required: false, + }, }); -const uploader = ref(null); -const formLoading = ref(false); -const formLoadingMessage = ref(""); +/** + * Reference to the File Upload Input element. + */ +const refUploadInput = ref(null); + +/** + * Is the dialog loading/busy + */ +const dialogLoading = ref(false); + +/** + * The dialog loading message to display + */ +const dialogLoadingMessage = ref(""); + +/** + * The form user message to display + */ const formMessage = ref(""); +/** + * Is the media loading/busy + */ +const mediaLoading = ref(true); + +/** + * Classes to apply to the media browser + */ +const mediaBrowserClasses = ref(["media-browser-grid"]); + +/** + * Current page. + */ const page = ref(1); + +/** + * Total media items expressed by API. + */ const totalItems = ref(0); + +/** + * List of current media items. + */ const mediaItems: Ref = ref([]); + +/** + * Selected media item id. + */ const selected = ref(""); + +/** + * How many media items are we showing per page. + */ const perPage = ref(12); -const handleCancel = () => { +/** + * Returns the pagination info + */ +const computedPaginationInfo = computed(() => { + if (totalItems.value == 0) { + return "0 - 0 of 0"; + } + + const start = (page.value - 1) * perPage.value + 1; + const end = start + perPage.value - 1; + + return `${start} - ${end} of ${totalItems.value}`; +}); + +/** + * Returns the file types accepted. + */ +const computedAccepts = computed(() => { + if (props.accepts.length > 0) { + return props.accepts; + } + + if (props.mime.endsWith("/")) { + return `${props.mime}*`; + } + + return props.mime; +}); + +/** + * Return the total number of pages. + */ +const computedTotalPages = computed(() => { + return Math.ceil(totalItems.value / perPage.value); +}); + +/** + * Return if the previous button should be disabled. + */ +const computedDisablePrevButton = computed(() => { + return page.value <= 1; +}); + +/** + * Return if the next button should be disabled. + */ +const computedDisableNextButton = computed(() => { + return page.value >= computedTotalPages.value; +}); + +/** + * Get the media item by id. + * + * @param {string} item_id The media item id. + * @returns {Media | null} The media object or null. + */ +const getMediaItem = (item_id: string): Media | null => { + let found: Media | null = null; + + mediaItems.value.every((item) => { + console.log(item.id, item_id); + if (item.id == item_id) { + found = item; + return false; + } + + return true; + }); + + return found; +}; + +/** + * Handle user clicking the cancel/close button. + */ +const handleClickCancel = () => { closeDialog(false); }; -const handleConfirm = () => { +/** + * Handle user clicking the insert button. + */ +const handleClickInsert = () => { if (selected.value !== "") { - closeDialog(selected.value); - } else { - closeDialog(false); + const mediaItem = getMediaItem(selected.value); + console.log(mediaItem, selected.value); + if (mediaItem != null) { + closeDialog(mediaItem); + return; + } } + + closeDialog(false); }; -const handleSelection = (item_id: string): void => { +/** + * Handle user clicking a media item (selecting). + * + * @param {string} item_id The media id. + */ +const handleClickItem = (item_id: string): void => { selected.value = item_id; }; -const handlePickSelection = (item_id: string): void => { - closeDialog(item_id); -}; - -const handleLoad = async () => { - formMessage.value = ""; - selected.value = ""; - - try { - let params = { - page: 0, - limit: 0, - // fields: "", - }; - params.page = page.value; - params.limit = perPage.value; - // params.fields = "url"; - - let res = await api.get({ - url: "/media", - params: params, - }); - - totalItems.value = res.data.total; - mediaItems.value = res.data.media; - } catch (error) { - if (error.status == 404) { - // formMessage.type = "primary"; - // formMessage.icon = "folder-open-outline"; - // formMessage.message = "No media items found"; - } else { - formMessage.value = - error?.data?.message || "An unexpected error occurred"; - } - } -}; - -const handleAskUpload = () => { - uploader.value.click(); -}; - -const handleUpload = async () => { - formLoading.value = true; - formMessage.value = ""; - - try { - let submitFormData = new FormData(); - if (uploader.value.files[0] instanceof File) { - submitFormData.append("file", uploader.value.files[0]); - - let res = await api.post({ - url: "/media", - params: { - mime: props.mime, - }, - body: submitFormData, - headers: { - "Content-Type": "multipart/form-data", - }, - // onUploadProgress: (progressEvent) => - // (formLoadingMessage.value = `Uploading Files ${Math.floor( - // (progressEvent.loaded / progressEvent.total) * 100 - // )}%`), - }); - - if (res.data.medium) { - closeDialog(res.data.medium); - } else { - formMessage.value = - "An unexpected response was received from the server"; - } - } else { - formMessage.value = "No file was selected to upload"; - } - } catch (err) { - console.log(err); - formMessage.value = - err.response?.data?.message || "An unexpected error occurred"; +/** + * Handle user double clicking a media item. + * + * @param item_id The media id. + */ +const handleDblClickItem = (item_id: string): void => { + const mediaItem = getMediaItem(item_id); + if (mediaItem != null) { + closeDialog(mediaItem); + return; } - formLoading.value = false; + closeDialog(false); }; -const handlePrev = ($event) => { +/** + * Handle Grid layout request click + */ +const handleClickGridLayout = () => { + mediaBrowserClasses.value = ["media-browser-grid"]; +}; + +/** + * Handle List layout request click + */ +const handleClickListLayout = () => { + mediaBrowserClasses.value = ["media-browser-list"]; +}; + +/** + * Handle click on previous button + * + * @param {MouseEvent} $event The mouse event. + */ +const handleClickPrev = ($event: MouseEvent): void => { if ( - $event.target.classList.contains("disabled") == false && + $event.target && + ($event.target as HTMLElement).classList.contains("disabled") == + false && page.value > 1 ) { page.value--; } }; -const handleNext = ($event) => { +/** + * Handle click on next button + * + * @param {MouseEvent} $event The mouse event. + */ +const handleClickNext = ($event: MouseEvent): void => { if ( - $event.target.classList.contains("disabled") == false && - page.value < totalPages.value + $event.target && + ($event.target as HTMLElement).classList.contains("disabled") == + false && + page.value < computedTotalPages.value ) { page.value++; } }; +/** + * When the user clicks the upload button + */ +const handleClickUpload = () => { + if (refUploadInput.value != null) { + refUploadInput.value.click(); + } +}; + +/** + * Upload the file to the server. + */ +const handleChangeUpload = async () => { + dialogLoading.value = true; + formMessage.value = ""; + + if (refUploadInput.value != null && refUploadInput.value.files != null) { + const firstFile: File | undefined = refUploadInput.value.files[0]; + if (firstFile != null) { + let submitFormData = new FormData(); + submitFormData.append("file", firstFile); + + api.post({ + url: "/media", + body: submitFormData, + headers: { + "Content-Type": "multipart/form-data", + }, + // progress: (progressData) => + // (dialogLoadingMessage.value = `Uploading Files ${Math.floor( + // (progressData.loaded / progressData.total) * 100 + // )}%`), + }) + .then((result) => { + if (result.data) { + const data = result.data as MediaResponse; + closeDialog(data.medium); + } else { + formMessage.value = + "An unexpected response was received from the server"; + } + }) + .catch((error) => { + formMessage.value = + error.response?.data?.message || + "An unexpected error occurred"; + }); + } else { + formMessage.value = "No file was selected to upload"; + } + } else { + formMessage.value = "No file was selected to upload"; + } + + dialogLoading.value = false; +}; + +/** + * Load the data of the dialog + */ +const handleLoad = async () => { + mediaLoading.value = true; + + api.get({ + url: "/media", + params: { + page: page.value, + limit: perPage.value, + }, + }) + .then((result) => { + if (result.data) { + const data = result.data as MediaCollection; + + totalItems.value = data.total; + mediaItems.value = data.media; + } + }) + .catch((error) => { + formMessage.value = + error?.data?.message || "An unexpected error occurred"; + }) + .finally(() => { + mediaLoading.value = false; + }); +}; + +/** + * Handle the user pressing keyboard keys. + * + * @param {KeyboardEvent} event The keyboard event. + */ const eventKeyUp = (event: KeyboardEvent) => { if (event.key === "Escape") { - handleCancel(); + handleClickCancel(); } else if (event.key === "Enter") { - handleConfirm(); + if (selected.value.length > 0) { + handleClickInsert(); + } } }; @@ -251,19 +462,7 @@ onUnmounted(() => { document.removeEventListener("keyup", eventKeyUp); }); -const totalPages = computed(() => { - return Math.ceil(totalItems.value / perPage.value); -}); - -const prevDisabled = computed(() => { - return page.value <= 1; -}); - -const nextDisabled = computed(() => { - return page.value >= totalPages.value; -}); - -watch(page, (value) => { +watch(page, () => { handleLoad(); }); @@ -273,27 +472,114 @@ handleLoad(); -- 2.49.1 From bb0be1dadf7369ba6444ebf4826c443eb496d376 Mon Sep 17 00:00:00 2001 From: James Collins Date: Fri, 24 Feb 2023 22:04:57 +1000 Subject: [PATCH 123/155] fix z-index so loading cover covers all --- resources/js/components/SMDialog.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/js/components/SMDialog.vue b/resources/js/components/SMDialog.vue index 12a71d5..6a865ad 100644 --- a/resources/js/components/SMDialog.vue +++ b/resources/js/components/SMDialog.vue @@ -87,6 +87,7 @@ defineProps({ backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(4px); background-color: rgba(255, 255, 255, 0.5); + z-index: 19000; .dialog-loading { display: flex; -- 2.49.1 From 158da60922f09327f65d6e3018234c021ef29588 Mon Sep 17 00:00:00 2001 From: James Collins Date: Fri, 24 Feb 2023 22:05:05 +1000 Subject: [PATCH 124/155] cleanup --- resources/js/components/SMInput.vue | 78 +++++++++++++---------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/resources/js/components/SMInput.vue b/resources/js/components/SMInput.vue index c753588..bd4b99f 100644 --- a/resources/js/components/SMInput.vue +++ b/resources/js/components/SMInput.vue @@ -6,6 +6,7 @@ 'sm-input-active': inputActive, 'sm-feedback-invalid': feedbackInvalid, }, + computedClassType, ]"> - {{ - props.modelValue - }} - {{ props.modelValue }} -
-
+
+
@@ -82,10 +78,6 @@
-
- - {{ help }} -
@@ -107,15 +99,6 @@ const props = defineProps({ default: "", required: false, }, - placeholder: { - type: String, - default: "", - required: false, - }, - required: { - type: Boolean, - default: false, - }, type: { type: String, default: "text", @@ -124,14 +107,6 @@ const props = defineProps({ type: String, default: "", }, - help: { - type: String, - default: "", - }, - helpIcon: { - type: String, - default: "", - }, accept: { type: String, default: "", @@ -168,6 +143,13 @@ const feedbackInvalid = ref(props.feedbackInvalid); const value = ref(props.modelValue); const inputActive = ref(value.value.length > 0 || props.type == "select"); +/** + * Return the classname based on type + */ +const computedClassType = computed(() => { + return `sm-input-${props.type}`; +}); + watch( () => props.label, (newValue) => { @@ -276,10 +258,6 @@ const handleKeydown = (event: Event) => { emits("keydown", event); }; -const inline = computed(() => { - return ["static", "link"].includes(props.type); -}); - const handleMediaSelect = async (event) => { let result = await openDialog(SMDialogMedia); if (result) { @@ -378,19 +356,35 @@ const handleMediaSelect = async (event) => { resize: none; } - .sm-input-media-display { - display: flex; - margin-bottom: 1rem; - border: 1px solid $border-color; - background-color: #fff; + &.sm-input-media { + label { + position: relative; + transform: none; + } + } - img { - max-width: 100%; - max-height: 100%; + .sm-input-media { + text-align: center; + + .sm-input-media-item { + display: block; + margin-bottom: 0.5rem; + + img { + max-width: 100%; + max-height: 100%; + } + + ion-icon { + padding: 4rem; + font-size: 3rem; + border: 1px solid $border-color; + background-color: #fff; + } } - ion-icon { - padding: 4rem; + .button { + display: inline-block; } } -- 2.49.1 From f9939134384267fba39e600f14ee47dad45cb61d Mon Sep 17 00:00:00 2001 From: James Collins Date: Fri, 24 Feb 2023 22:05:11 +1000 Subject: [PATCH 125/155] added --- .../js/components/SMInputAttachments.vue | 202 ++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 resources/js/components/SMInputAttachments.vue diff --git a/resources/js/components/SMInputAttachments.vue b/resources/js/components/SMInputAttachments.vue new file mode 100644 index 0000000..4038c92 --- /dev/null +++ b/resources/js/components/SMInputAttachments.vue @@ -0,0 +1,202 @@ + + + + + -- 2.49.1 From cc89d4569052d3d683613502bb36144a332d32b4 Mon Sep 17 00:00:00 2001 From: James Collins Date: Fri, 24 Feb 2023 22:05:21 +1000 Subject: [PATCH 126/155] begun adding attachment support --- resources/js/views/dashboard/PostEdit.vue | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/resources/js/views/dashboard/PostEdit.vue b/resources/js/views/dashboard/PostEdit.vue index 9aa9513..e20b3c5 100644 --- a/resources/js/views/dashboard/PostEdit.vue +++ b/resources/js/views/dashboard/PostEdit.vue @@ -43,6 +43,11 @@ + + + + + -- 2.49.1 From 55ec88e11fdab68d77ec289e04eb9e25ed2f066b Mon Sep 17 00:00:00 2001 From: James Collins Date: Sun, 26 Feb 2023 13:53:46 +1000 Subject: [PATCH 136/155] improved progress bar design --- resources/css/app.scss | 1 - resources/css/progressbar.scss | 28 --------------------- resources/js/components/SMProgress.vue | 12 +++++---- resources/js/main.js | 2 -- resources/js/router/index.js | 3 --- resources/js/store/ProgressStore.ts | 35 ++++++++++++++++---------- 6 files changed, 29 insertions(+), 52 deletions(-) delete mode 100644 resources/css/progressbar.scss diff --git a/resources/css/app.scss b/resources/css/app.scss index 0236d1a..bd4c172 100644 --- a/resources/css/app.scss +++ b/resources/css/app.scss @@ -3,7 +3,6 @@ @import "data-table.scss"; @import "tinymce.scss"; @import "prism.css"; -@import "progressbar.scss"; * { box-sizing: border-box; diff --git a/resources/css/progressbar.scss b/resources/css/progressbar.scss deleted file mode 100644 index b8c2bed..0000000 --- a/resources/css/progressbar.scss +++ /dev/null @@ -1,28 +0,0 @@ -$vue3-progress-bar-container-z-index: 999999 !default; -$vue3-progress-bar-container-transition: all 500ms ease !default; - -$vue3-progress-bar-color: $primary-color-dark !default; -$vue3-progress-bar-height: 4px !default; -$vue3-progress-bar-transition: all 200ms ease !default; - -.vue3-progress-bar-container { - position: fixed; - z-index: $vue3-progress-bar-container-z-index; - top: 0; - left: 0; - width: 100%; - opacity: 0; - background-color: #eee; - transition: $vue3-progress-bar-container-transition; - &[active="true"] { - opacity: 1; - transition: none; - } - .vue3-progress-bar { - width: 100%; - height: $vue3-progress-bar-height; - transform: translate3d(-100%, 0, 0); - background-color: $vue3-progress-bar-color; - transition: $vue3-progress-bar-transition; - } -} diff --git a/resources/js/components/SMProgress.vue b/resources/js/components/SMProgress.vue index 25e61c6..19a9115 100644 --- a/resources/js/components/SMProgress.vue +++ b/resources/js/components/SMProgress.vue @@ -9,10 +9,10 @@ width: `${(progressStore.status || 0) * 100}%`, }">
-
-
+
+
@@ -48,7 +48,7 @@ const progressStore = useProgressStore(); position: fixed; top: 10px; right: 10px; - transition: opacity 0.2s ease-in-out; + opacity: 0.5; .sm-spinner-icon { width: 18px; @@ -60,6 +60,8 @@ const progressStore = useProgressStore(); border-left-color: #29d; border-radius: 50%; + transition: opacity 0.2s ease-in-out; + -webkit-animation: sm-progress-spinner 500ms linear infinite; animation: sm-progress-spinner 500ms linear infinite; } diff --git a/resources/js/main.js b/resources/js/main.js index f9afcff..c283797 100644 --- a/resources/js/main.js +++ b/resources/js/main.js @@ -12,7 +12,6 @@ import SMColumn from "./components/SMColumn.vue"; import { PromiseDialog } from "vue3-promise-dialog"; import { VueReCaptcha } from "vue-recaptcha-v3"; import "./lib/prism"; -import { Vue3ProgressPlugin } from "@marcoschulte/vue3-progress"; const pinia = createPinia(); pinia.use(piniaPluginPersistedstate); @@ -27,7 +26,6 @@ createApp(App) autoHideBadge: true, }, }) - .use(Vue3ProgressPlugin) .component("SMContainer", SMContainer) .component("SMRow", SMRow) .component("SMColumn", SMColumn) diff --git a/resources/js/router/index.js b/resources/js/router/index.js index 56bd202..fe26375 100644 --- a/resources/js/router/index.js +++ b/resources/js/router/index.js @@ -4,8 +4,6 @@ import { useApplicationStore } from "../store/ApplicationStore"; import { useProgressStore } from "../store/ProgressStore"; import { api } from "../helpers/api"; -const progresses = []; - export const routes = [ { path: "/", @@ -379,7 +377,6 @@ router.beforeEach(async (to, from, next) => { const applicationStore = useApplicationStore(); const progressStore = useProgressStore(); - // progressStore.reset(); progressStore.start(); applicationStore.clearDynamicTitle(); diff --git a/resources/js/store/ProgressStore.ts b/resources/js/store/ProgressStore.ts index ec3bbf3..d03cb97 100644 --- a/resources/js/store/ProgressStore.ts +++ b/resources/js/store/ProgressStore.ts @@ -21,12 +21,12 @@ export const useProgressStore = defineStore({ actions: { start() { - if (this.queue == 0) { + if (this.queue == 0 && this.opacity == 0) { this.set(0); const work = () => { window.setTimeout(() => { - if (this.status != null) { + if (this.status < 1) { this._trickle(); work(); } @@ -43,7 +43,7 @@ export const useProgressStore = defineStore({ this.timeoutID = window.setTimeout(() => { this._show(); this.timeoutID = null; - }, 200); + }, 2000); } if (this.spinner == 0) { @@ -55,7 +55,8 @@ export const useProgressStore = defineStore({ }, set(number: number) { - this.status = clamp(number, 0.08, 1); + const n = clamp(number, 0.08, 1); + this.status = n; }, finish() { @@ -67,21 +68,29 @@ export const useProgressStore = defineStore({ _trickle() { const n = this.status; - if (this.queue == 0 && this.timeoutID == null) { - this.timeoutID = window.setTimeout(() => { - this.set(1); + if (this.queue == 0) { + if (this.opacity == 0 && this.timeoutID != null) { + this._hide(); + window.clearTimeout(this.timeoutID); this.timeoutID = null; - + } else if (this.timeoutID == null) { this.timeoutID = window.setTimeout(() => { - this._hide(); + this.set(1); this.timeoutID = null; + + this.timeoutID = window.setTimeout(() => { + this._hide(); + this.timeoutID = null; + + window.setTimeout(() => { + this.status = 0; + }, 150); + }, 500); }, 500); - }, 200); + } } - if (n == 0) { - this.start(); - } else if (n < 1) { + if (n > 0 && n < 1) { let amount = 0; if (n >= 0 && n < 0.2) { -- 2.49.1 From cff787f541f018267601e80f5cd7eab23e4710e7 Mon Sep 17 00:00:00 2001 From: James Collins Date: Sun, 26 Feb 2023 17:48:43 +1000 Subject: [PATCH 137/155] added toasts --- resources/js/components/SMToast.vue | 135 ++++++++++++++++++++++++ resources/js/components/SMToastList.vue | 30 ++++++ resources/js/store/ToastStore.ts | 54 ++++++++++ resources/js/views/App.vue | 2 + 4 files changed, 221 insertions(+) create mode 100644 resources/js/components/SMToast.vue create mode 100644 resources/js/components/SMToastList.vue create mode 100644 resources/js/store/ToastStore.ts diff --git a/resources/js/components/SMToast.vue b/resources/js/components/SMToast.vue new file mode 100644 index 0000000..f452011 --- /dev/null +++ b/resources/js/components/SMToast.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/resources/js/components/SMToastList.vue b/resources/js/components/SMToastList.vue new file mode 100644 index 0000000..c807e84 --- /dev/null +++ b/resources/js/components/SMToastList.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/resources/js/store/ToastStore.ts b/resources/js/store/ToastStore.ts new file mode 100644 index 0000000..fe247b7 --- /dev/null +++ b/resources/js/store/ToastStore.ts @@ -0,0 +1,54 @@ +import { defineStore } from "pinia"; + +export interface ToastOptions { + id?: number; + title?: string; + content: string; + type?: string; +} + +export interface ToastItem { + id: number; + title: string; + content: string; + type: string; +} + +export interface ToastStore { + toasts: ToastItem[]; +} + +export const defaultToastItem: ToastItem = { + id: 0, + title: "", + content: "", + type: "primary", +}; + +export const useToastStore = defineStore({ + id: "toasts", + state: (): ToastStore => ({ + toasts: [], + }), + + actions: { + addToast(toast: ToastOptions) { + if (!toast.id || toast.id == 0) { + toast.id = + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) + 1; + } + + toast.title = toast.title || defaultToastItem.title; + toast.type = toast.type || defaultToastItem.type; + + this.toasts.push(toast); + console.log(this.toasts[0].title); + }, + + clearToast(id: number) { + this.toasts = this.toasts.filter( + (item: ToastItem) => item.id !== id + ); + }, + }, +}); diff --git a/resources/js/views/App.vue b/resources/js/views/App.vue index d3d6e25..417c116 100644 --- a/resources/js/views/App.vue +++ b/resources/js/views/App.vue @@ -9,6 +9,7 @@ + @@ -16,6 +17,7 @@ import SMNavbar from "../components/SMNavbar.vue"; import SMFooter from "../components/SMFooter.vue"; import SMProgress from "../components/SMProgress.vue"; +import SMToastList from "../components/SMToastList.vue"; import { DialogWrapper } from "vue3-promise-dialog"; -- 2.49.1 From 56f786cd2b93e31e8910d707d54748c84e952423 Mon Sep 17 00:00:00 2001 From: James Collins Date: Sun, 26 Feb 2023 19:13:37 +1000 Subject: [PATCH 138/155] cleanup types and added isValid function to controls --- resources/js/helpers/form.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/resources/js/helpers/form.ts b/resources/js/helpers/form.ts index a88d846..beb3366 100644 --- a/resources/js/helpers/form.ts +++ b/resources/js/helpers/form.ts @@ -101,18 +101,20 @@ const defaultFormControlValidation: FormControlValidation = { result: defaultValidationResult, }; -type FormClearValidations = () => void; -type FormSetValidation = ( +type FormControlClearValidations = () => void; +type FormControlSetValidation = ( valid: boolean, message?: string | Array ) => ValidationResult; +type FormControlIsValid = () => boolean; -interface FormControlObject { +export interface FormControlObject { value: string; validate: () => ValidationResult; validation: FormControlValidation; - clearValidations: FormClearValidations; - setValidationResult: FormSetValidation; + clearValidations: FormControlClearValidations; + setValidationResult: FormControlSetValidation; + isValid: FormControlIsValid; } /* eslint-disable indent */ @@ -135,11 +137,17 @@ export const FormControl = ( setValidationResult: createValidationResult, validate: function () { if (this.validation.validator) { - return this.validation.validator(this.value); + this.validation.result = this.validation.validator.validate( + this.value + ); + return this.validation.result; } return defaultValidationResult; }, + isValid: function () { + return this.validation.result.valid; + }, }; }; /* eslint-enable indent */ -- 2.49.1 From 34a90bf218938ff543928d99c80f65092545701c Mon Sep 17 00:00:00 2001 From: James Collins Date: Sun, 26 Feb 2023 19:14:03 +1000 Subject: [PATCH 139/155] removed .prevent from button --- resources/js/views/dashboard/UserEdit.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/js/views/dashboard/UserEdit.vue b/resources/js/views/dashboard/UserEdit.vue index a648cd1..9acbb99 100644 --- a/resources/js/views/dashboard/UserEdit.vue +++ b/resources/js/views/dashboard/UserEdit.vue @@ -18,7 +18,7 @@ + @click="handleChangePassword" /> -- 2.49.1 From 212c5410e15c778745da7d25d092cedc95d73cf3 Mon Sep 17 00:00:00 2001 From: James Collins Date: Sun, 26 Feb 2023 19:14:12 +1000 Subject: [PATCH 140/155] support control object --- resources/js/components/SMInput.vue | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/resources/js/components/SMInput.vue b/resources/js/components/SMInput.vue index bd4b99f..f210653 100644 --- a/resources/js/components/SMInput.vue +++ b/resources/js/components/SMInput.vue @@ -118,7 +118,7 @@ const props = defineProps({ }, }, control: { - type: String, + type: [String, Object], default: "", }, form: { @@ -136,7 +136,13 @@ const mediaUrl = ref(""); const objForm = inject("form", props.form); const objControl = - !isEmpty(objForm) && props.control != "" ? objForm[props.control] : null; + typeof props.control == "object" + ? props.control + : !isEmpty(objForm) && + typeof props.control == "string" && + props.control != "" + ? objForm[props.control] + : null; const label = ref(props.label); const feedbackInvalid = ref(props.feedbackInvalid); @@ -237,12 +243,10 @@ const handleFocus = (event: Event) => { emits("focus", event); }; -const handleBlur = (event: Event) => { +const handleBlur = async (event: Event) => { if (objControl) { - objForm.validate(props.control); - feedbackInvalid.value = objForm[props.control].validation.result.valid - ? "" - : objForm[props.control].validation.result.invalidMessages[0]; + objControl.validate(); + objControl.isValid(); } const target = event.target as HTMLInputElement; -- 2.49.1 From 3231063bc2b33a4abcd363eaa68451c0f144bee5 Mon Sep 17 00:00:00 2001 From: James Collins Date: Sun, 26 Feb 2023 19:25:10 +1000 Subject: [PATCH 141/155] default attachments to empty array --- resources/js/views/NewsView.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/js/views/NewsView.vue b/resources/js/views/NewsView.vue index 70a6223..fc25a49 100644 --- a/resources/js/views/NewsView.vue +++ b/resources/js/views/NewsView.vue @@ -19,7 +19,7 @@ - + -- 2.49.1 From 2b298b7c7634eff4781ef74a0dec2c6222e5b414 Mon Sep 17 00:00:00 2001 From: James Collins Date: Sun, 26 Feb 2023 20:01:52 +1000 Subject: [PATCH 142/155] fix box shadow clipping --- resources/js/components/SMToast.vue | 3 +-- resources/js/components/SMToastList.vue | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/js/components/SMToast.vue b/resources/js/components/SMToast.vue index f452011..4d49ddb 100644 --- a/resources/js/components/SMToast.vue +++ b/resources/js/components/SMToast.vue @@ -87,11 +87,10 @@ onMounted(() => { background-color: #fff; padding: map-get($spacer, 2) map-get($spacer, 2) map-get($spacer, 2) map-get($spacer, 2); - border: 1px solid #fff; border-radius: 12px; + border: 1px solid $border-color; box-shadow: 0 0 10px rgba(0, 0, 0, 0.25); margin-bottom: 1rem; - border: 1px solid $border-color; transition: opacity 0.2s ease-in, margin 0.2s ease-in; .sm-toast-inner { diff --git a/resources/js/components/SMToastList.vue b/resources/js/components/SMToastList.vue index c807e84..4d85b80 100644 --- a/resources/js/components/SMToastList.vue +++ b/resources/js/components/SMToastList.vue @@ -21,10 +21,11 @@ const toastStore = useToastStore(); .sm-toast-container { position: fixed; height: 2px; - top: 4rem; - right: 1rem; + top: 3.5rem; + right: 0.75rem; height: 100%; z-index: 3000; + padding: 10px; overflow: hidden; } -- 2.49.1 From 808304303a0ed06931a77a5ab43ce2ebfe3d636f Mon Sep 17 00:00:00 2001 From: James Collins Date: Sun, 26 Feb 2023 20:02:01 +1000 Subject: [PATCH 143/155] cleanup --- .../dialogs/SMDialogChangePassword.vue | 90 +++++++++---------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/resources/js/components/dialogs/SMDialogChangePassword.vue b/resources/js/components/dialogs/SMDialogChangePassword.vue index c49427e..5d99c80 100644 --- a/resources/js/components/dialogs/SMDialogChangePassword.vue +++ b/resources/js/components/dialogs/SMDialogChangePassword.vue @@ -1,29 +1,22 @@