Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
614aa09
wip
NeoIsRecursive Aug 25, 2025
12705b7
wip
NeoIsRecursive Aug 25, 2025
e9c5168
fix formatting
NeoIsRecursive Aug 25, 2025
ba899d5
wip
NeoIsRecursive Aug 25, 2025
800fa7c
wip
NeoIsRecursive Aug 25, 2025
fbb1c90
wip
NeoIsRecursive Aug 25, 2025
c7ee4d7
wip
NeoIsRecursive Aug 26, 2025
e582aac
wip
NeoIsRecursive Aug 27, 2025
6f5eeb5
Merge remote-tracking branch 'origin/main' into statamic-6
NeoIsRecursive Aug 27, 2025
97570bf
Update mago to beta.2
NeoIsRecursive Aug 29, 2025
afb6398
chore: use queueable trait instead of splitup
NeoIsRecursive Sep 1, 2025
d8ca40a
wip bump alpha
NeoIsRecursive Sep 1, 2025
78a4c73
chore: update mago
NeoIsRecursive Sep 1, 2025
0d8fe7e
fix: php actor issues
NeoIsRecursive Sep 1, 2025
d77e8c6
wip
NeoIsRecursive Oct 31, 2025
bbe233b
Fix test issues
NeoIsRecursive Oct 31, 2025
ff81a66
Make mago happy
NeoIsRecursive Oct 31, 2025
a3a0d3f
bump min php version to 8.3
NeoIsRecursive Oct 31, 2025
db2d554
wip
NeoIsRecursive Oct 31, 2025
a032436
update mago and migrate to yaml file and apply fixes
NeoIsRecursive Nov 19, 2025
3b34e50
wip
NeoIsRecursive Nov 19, 2025
c3d2ff4
wip update mago and pest
NeoIsRecursive Jan 13, 2026
0dcfdab
wip
NeoIsRecursive Jan 19, 2026
098e6c3
wip beta support
NeoIsRecursive Jan 20, 2026
6b9f16d
Update to statamic 6
NeoIsRecursive Feb 10, 2026
1d5ccc2
Update php version to 8.5
NeoIsRecursive Feb 10, 2026
c62aa3f
chore: update deps and improve static analysis a bit
NeoIsRecursive Apr 17, 2026
8862cc2
fix
NeoIsRecursive Apr 17, 2026
de2a32d
fix: icon
NeoIsRecursive Apr 17, 2026
b09d1a9
fix: stop polling
NeoIsRecursive Apr 17, 2026
f87ef2e
fix: handle chunk assembling better
NeoIsRecursive Apr 17, 2026
6ea8289
fix: typings
NeoIsRecursive Apr 17, 2026
cdd5806
fix: build error
NeoIsRecursive Apr 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
php-version: 8.5
tools: composer:v2

- name: Install composer dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
- name: "installing PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "8.3"
php-version: "8.5"

- name: "installing dependencies"
run: composer install --no-interaction --prefer-dist --optimize-autoloader
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php: [8.2, 8.3, 8.4]
php: [8.3, 8.4, 8.5]
dependency-version: [prefer-lowest, prefer-stable]

steps:
Expand Down
6 changes: 3 additions & 3 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
"build": "vite build"
},
"devDependencies": {
"@vitejs/plugin-vue2": "^2.3.1",
"laravel-vite-plugin": "^1.0.2",
"vite": "^6.3.5"
"@statamic/cms": "file:./../vendor/statamic/cms/resources/dist-package",
"laravel-vite-plugin": "^2.0.0",
"vite": "^7.1.12"
},
"dependencies": {
"resumablejs": "^1.1.0"
Expand Down
88 changes: 0 additions & 88 deletions client/src/components/Actions.vue

This file was deleted.

201 changes: 154 additions & 47 deletions client/src/components/Backup.vue
Original file line number Diff line number Diff line change
@@ -1,55 +1,162 @@
<template>
<div>
<div class="flex">
<div class="flex flex-col mb-4">
<h1>{{ __("statamic-backup::backup.title") }}</h1>
<p v-if="status !== 'idle'" class="text-sm text-gray-700 whitespace-nowrap">
{{ __(`statamic-backup::backup.state.${status}`) }}
</p>
</div>
<backup-actions @openBrowser="openBrowser" />
</div>

<backup-listing />
</div>
</template>
<script setup>
import { Listing, DropdownItem, Header, Button } from "@statamic/cms/ui";
import { Head } from "@statamic/cms/inertia";
import { requireElevatedSession } from "@statamic/cms";
import { useBackupStore } from "../store";
import { onUnmounted, ref, watch } from "vue";
import { useResumable } from "../resumable";

<script>
import Listing from "./Listing.vue";
import Actions from "./Actions.vue";
import { store } from "../store";
const backupStore = useBackupStore();

export default {
components: {
"backup-listing": Listing,
"backup-actions": Actions,
},
props: {
chunkSize: {
type: Number,
default: 2 * 1024 * 1024, // 2MB
},
const listing = ref(null);

const dropZone = ref(null);
const browseTarget = ref(null);

const { files } = useResumable({
chunkSize: Statamic.$config.get('statamic_backup.chunk_size', 2 * 1024 * 1024),
dropZone,
browseTarget,
onFileUploaded: (file) => {
listing.value.refresh();
},
created() {
// console.log(this.chunkSize)
});

backupStore.startPolling();
Comment thread
NeoIsRecursive marked this conversation as resolved.

window.backup = {
chunkSize: this.chunkSize
};
onUnmounted(() => {
backupStore.stopPolling();
})

if (!this.$store.hasModule('backup-provider')) {
this.$store.registerModule('backup-provider', store);
this.$store.dispatch('backup-provider/pollEndpoint');
watch(
() => backupStore.status,
(newStatus, oldStatus) => {
if (oldStatus === "initializing") return;
if (newStatus !== oldStatus) {
listing.value.refresh();
}
},
computed: {
status() {
return this.$store.state['backup-provider'].status;
},
},
destroy() {
this.$store.dispatch('backup-provider/stopPolling');
this.$store.unregisterModule('backup-provider');
},
}
);

const withErrHandling = (fn) => async (params) => {
return fn(params).catch((err) => {
console.error(err);

if (err.response) {
Statamic.$toast.error(err.response.data.message);
} else {
Statamic.$toast.error(err.message);
}
});
};

const queueRestore = withErrHandling(async (id) => {
await requireElevatedSession();

const { data } =
await window.Statamic.$app.config.globalProperties.$axios.post(
cp_url(`api/backups/restore/${id}`)
);

Statamic.$toast.info(__(data.message));
});

const queueBackup = withErrHandling(async () => {
backupStore.setStatus("backup_in_progress");

const { data } =
await window.Statamic.$app.config.globalProperties.$axios.post(
cp_url("api/backups")
);

Statamic.$toast.info(__(data.message));
listing.value.refresh();
});

const deleteBackup = withErrHandling(async (id) => {
await requireElevatedSession();

const { data } =
await window.Statamic.$app.config.globalProperties.$axios.delete(
cp_url(`api/backups/${id}`)
);

Statamic.$toast.info(__(data.message));
listing.value.refresh();
});
</script>

<template>
<Head title="Backups" />
<Header icon="database" :title="__('statamic-backup::backup.title')">
<Button variant="subtle" ref="browseTarget">{{
__("statamic-backup::backup.upload.label")
}}</Button>
<Button
variant="primary"
v-on:click="queueBackup"
:disabled="!backupStore.abilities.backup.isPossible"
:loading="backupStore.status === 'backup_in_progress'"
>
{{ __("statamic-backup::backup.create") }}
</Button>
</Header>

<p v-for="file in files" :key="file.file.uniqueIdentifier" class="mb-2">
<span>{{ file.file.fileName }}</span>
<span v-if="file.status === 'uploading'">
- {{ Math.round(file.progress * 100) }}%</span
>
<span v-if="file.status === 'retrying'">
- {{ __("statamic-backup::backup.upload.retrying") }}</span
>
<span v-if="file.status === 'error'" class="text-red-600">
- {{ __("statamic-backup::backup.upload.error") }}</span
>
</p>

<Listing
ref="listing"
:allowSearch="false"
:allowCustomizingColumns="false"
:url="cp_url('api/backups')"
:columns="[
{
field: 'name',
label: __('statamic-backup::backup.name'),
visible: true,
},
{
field: 'created_at',
label: __('statamic-backup::backup.created_at'),
visible: true,
},
{
field: 'size',
label: __('statamic-backup::backup.size'),
visible: true,
},
]"
>
<template #prepended-row-actions="{ row }">
<DropdownItem
v-if="backupStore.abilities.download.isPermitted"
:text="__('statamic-backup::backup.download.label')"
target="_blank"
:href="`${cp_url('api/backups/download')}/${row.id}`"
/>
<DropdownItem
v-if="backupStore.abilities.restore.isPermitted"
:disabled="!backupStore.abilities.restore.isPossible"
v-on:click="queueRestore(row.id)"
:text="__('statamic-backup::backup.restore.label')"
/>
<DropdownItem
v-if="backupStore.abilities.destroy.isPermitted"
variant="destructive"
v-on:click="deleteBackup(row.id)"
:text="__('statamic-backup::backup.destroy.label')"
/>
</template>
</Listing>
</template>
Loading
Loading