Skip to content

Commit c470291

Browse files
committed
Add main page sortable
1 parent 2a0455d commit c470291

File tree

3 files changed

+120
-30
lines changed

3 files changed

+120
-30
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<script lang="ts">
2+
import Sortable, { type Options } from 'sortablejs';
3+
import SortableList from '../input/SortableList.svelte';
4+
import { isEqual } from 'lodash-es';
5+
import getArrayDifference from '$lib/utilities/arrayOrder';
6+
import graphql from '$lib/utilities/api';
7+
import { success } from '$lib/utilities/toasts';
8+
9+
interface Props {
10+
images: any[];
11+
}
12+
13+
const { images }: Props = $props();
14+
15+
let originalOrder = $state(images.map((x: any) => `${x.mainImageConfig.id}`));
16+
// svelte-ignore state_referenced_locally
17+
let updatedElements = $state($state.snapshot(originalOrder));
18+
19+
let sortable: Sortable | undefined = $state();
20+
const sortableOptions: Options = {
21+
draggable: '.image-item',
22+
chosenClass: 'item-chosen',
23+
ghostClass: 'item-ghost',
24+
animation: 150,
25+
dataIdAttr: 'data-imageId',
26+
onEnd: () => (updatedElements = sortable!.toArray())
27+
};
28+
29+
let saveEnabled: boolean = $derived(!isEqual(originalOrder, updatedElements));
30+
31+
async function updateImagesOrder() {
32+
const query = `
33+
mutation updateMainPageConfig($id: Int!, $index: Int!) {
34+
updateMainPageConfig(id: $id, index: $index) {
35+
id
36+
}
37+
}
38+
`;
39+
40+
const updates = getArrayDifference(originalOrder, updatedElements);
41+
42+
updates.forEach(async ({ id, newPos }) => {
43+
await graphql(query, { id: parseInt(id), index: newPos });
44+
});
45+
46+
originalOrder = updatedElements;
47+
48+
success('Orden actualizado con éxito.');
49+
}
50+
</script>
51+
52+
<SortableList bind:sortable sortableId="sortable-main-page" {sortableOptions}>
53+
<div
54+
id="sortable-main-page"
55+
class="grid grid-cols-3 lg:grid-cols-5 gap-5 items-center w-full overflow-y-scroll overflow-x-hidden images-container"
56+
>
57+
{#each images as image (image.filename)}
58+
<a
59+
href={`/proyectos/${image.space.project.id}/ambientes/${image.space.id}/imagenes/${image.filename}`}
60+
class="image-item transition-all border-vector-orange hover:border-4 relative"
61+
data-imageId={image.mainImageConfig.id}
62+
>
63+
<img src={image.imageUrl} alt={image.altTextEs} />
64+
<div
65+
class="absolute top-0 left-0 text-yellow-500 bg-vector-black/70 text-2xl px-1 pb-0.5 flex gap-x-2 items-start"
66+
>
67+
{#if image.space.project.thumbnail?.filename === image.filename}
68+
<div title="Imagen principal">⭐</div>
69+
{/if}
70+
{#if image.mainPage}
71+
<div title="Imagen en página principal">🏠</div>
72+
{/if}
73+
{#if image.sculpture}
74+
<div title="Imagen es una escultura">🖼️</div>
75+
{/if}
76+
</div>
77+
</a>
78+
{/each}
79+
<div
80+
id="cancel-images-main-page"
81+
class={`${saveEnabled ? 'opacity-100' : 'opacity-0'} transition-all flex flex-col items-center gap-1`}
82+
>
83+
<button
84+
class="w-fit text-xl p-1 rounded-md text-green-500 hover:bg-green-500 hover:text-black"
85+
onclick={updateImagesOrder}
86+
>
87+
88+
</button>
89+
<button
90+
type="button"
91+
onclick={() => {
92+
sortable?.sort(originalOrder!);
93+
updatedElements = originalOrder;
94+
95+
let buttons = document.getElementById('cancel-images-main-page')!;
96+
97+
sortable?.el.appendChild(buttons);
98+
}}
99+
class="w-fit text-xl text-red-500 p-1 rounded-md hover:text-black hover:bg-red-500 transition-colors cursor-pointer"
100+
>
101+
X
102+
</button>
103+
</div>
104+
</div>
105+
</SortableList>
Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
<script lang="ts">
22
import EditorLinks from '$lib/components/layout/editorLinks.svelte';
3+
import ImageGridMainPage from '$lib/components/layout/imageGridMainPage.svelte';
4+
import type { PageData } from './$types';
5+
6+
let { data }: { data: PageData } = $props();
37
</script>
48

5-
<div
6-
class="size-full bg-black text-white h-[calc(100svh-5rem)] p-20 flex items-center flex-col gap-10"
7-
>
8-
<h1 class="text-2xl text-center">Editor de Página Principal</h1>
9-
<EditorLinks
10-
mobileUrl="/proyectos/paginaPrincipal/movil"
11-
desktopUrl="/proyectos/paginaPrincipal/escritorio"
12-
/>
9+
<div class="size-full bg-black text-white p-20 flex items-center flex-col gap-10">
10+
<ImageGridMainPage images={data.mainPageData} />
11+
<div>
12+
<h1 class="text-2xl text-center">Editor de Página Principal</h1>
13+
<EditorLinks
14+
mobileUrl="/proyectos/paginaPrincipal/movil"
15+
desktopUrl="/proyectos/paginaPrincipal/escritorio"
16+
/>
17+
</div>
1318
</div>

frontend/admin/src/routes/proyectos/paginaPrincipal/+page.ts

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,11 @@ export const load = async ({ fetch }) => {
66
mainPageImages {
77
id
88
filename
9+
imageUrl
910
mainPage
1011
mainImageConfig {
1112
id
12-
descriptionEs
13-
descriptionEn
14-
descriptionAlignment
15-
descriptionFont
16-
descriptionFontSize
17-
phoneConfig {
18-
descriptionPosition
19-
logoPosition
20-
overflow
21-
imageBorders {
22-
n
23-
s
24-
e
25-
w
26-
}
27-
logoBorders {
28-
n
29-
s
30-
e
31-
w
32-
}
33-
}
13+
index
3414
}
3515
space {
3616
id

0 commit comments

Comments
 (0)