feature complete create view

This commit is contained in:
MarcZierle 2022-01-17 22:38:06 +01:00
parent e750480fd0
commit 840e82a1af
3 changed files with 423 additions and 24 deletions

226
package-lock.json generated
View File

@ -1,11 +1,11 @@
{ {
"name": "frontend", "name": "zierle-training-online-tools",
"version": "0.1.0", "version": "0.1.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "frontend", "name": "zierle-training-online-tools",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"axios": "^0.24.0", "axios": "^0.24.0",
@ -13,9 +13,19 @@
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-meta": "^3.0.0-alpha.8", "vue-meta": "^3.0.0-alpha.8",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",
"vuedraggable": "^4.1.0",
"vuex": "^4.0.0-0" "vuex": "^4.0.0-0"
}, },
"devDependencies": { "devDependencies": {
"@vicons/antd": "^0.11.0",
"@vicons/carbon": "^0.11.0",
"@vicons/fa": "^0.11.0",
"@vicons/fluent": "^0.11.0",
"@vicons/ionicons4": "^0.11.0",
"@vicons/ionicons5": "^0.11.0",
"@vicons/material": "^0.11.0",
"@vicons/tabler": "^0.11.0",
"@vicons/utils": "^0.1.4",
"@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0", "@vue/cli-plugin-router": "~4.5.0",
@ -2097,6 +2107,66 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/@vicons/antd": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/antd/-/antd-0.11.0.tgz",
"integrity": "sha512-XRkUMJzfjr3Q5S6xbAg4ALI90DIGNhZdbVW6SejFi6EgxB5bts3YMMcM4HbF77vdQX5bhxgju3Hd3uP97OgvAQ==",
"dev": true
},
"node_modules/@vicons/carbon": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/carbon/-/carbon-0.11.0.tgz",
"integrity": "sha512-+Wkl8wOP1GR7jS+OKcsJ58NnZr4i+BZhbpLRtgpZQui1zFpYjoWinwvYKLjGKJ/oiR10Q237cBDjGwmMSzXqTg==",
"dev": true
},
"node_modules/@vicons/fa": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/fa/-/fa-0.11.0.tgz",
"integrity": "sha512-Mlv4sxlghqAPu+RM+6w0/GIcsQFK/fx1syw1HkABS6MJRLwHOqbmImCYZQam7OMAYhZBs82YpY5cp2NFSgwkOA==",
"dev": true
},
"node_modules/@vicons/fluent": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/fluent/-/fluent-0.11.0.tgz",
"integrity": "sha512-5sbdKLijk5/PBtsapDjBodskSCrfOsqOlpCbXQ33pZmY0VZ62N46Yq6SFJXHyUgFhjvReRrFe4wCGVAktchHFg==",
"dev": true
},
"node_modules/@vicons/ionicons4": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/ionicons4/-/ionicons4-0.11.0.tgz",
"integrity": "sha512-2wgc2WZiQhR5AwNfiJcjxjNb910QBqeEYFXnZ0IJtfSgSUPH7lX6HEXegly3zqvLA0dmdUvyo2kI9lF/2PSbnQ==",
"dev": true
},
"node_modules/@vicons/ionicons5": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/ionicons5/-/ionicons5-0.11.0.tgz",
"integrity": "sha512-4IWamqtXUsuCdlW6NQc2xyoJ+PUXGMwzSrppQbdVCYg0pjYld89jOfLOIkuTWq8o2XUa+Q1/78jzWBtXMTojNg==",
"dev": true
},
"node_modules/@vicons/material": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/material/-/material-0.11.0.tgz",
"integrity": "sha512-ZQVs6Z5AjSSKqeN4GrG+5fRbi4rbvLwio06Nsjs5NGDuHCB57QHN2rwkooxeoRUbiFT4GCCKatsoWbjqE6BSZg==",
"dev": true
},
"node_modules/@vicons/tabler": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/tabler/-/tabler-0.11.0.tgz",
"integrity": "sha512-ijVUphdgqTde22/4+hlZ9j2AQutpxd3piOW4cWovcnS/ELlMc/4di2/0SDxsJ6282VdZoE9Xv0dI1iSr0XKPEg==",
"dev": true
},
"node_modules/@vicons/utils": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@vicons/utils/-/utils-0.1.4.tgz",
"integrity": "sha512-OHI19qVNN6i+uPQ+Y3f2s0dUxwsYnOCcKBW7XOU4yXXO1aU3ZoKpblCc3+4N0qmgoJs5rWKRAaMisipqEXJwAg==",
"dev": true,
"dependencies": {
"@xicons/utils": "^0.1.4"
},
"peerDependencies": {
"vue": "^3.0.6"
}
},
"node_modules/@vue/babel-helper-vue-jsx-merge-props": { "node_modules/@vue/babel-helper-vue-jsx-merge-props": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz",
@ -2918,6 +2988,38 @@
"@xtuc/long": "4.2.2" "@xtuc/long": "4.2.2"
} }
}, },
"node_modules/@xicons/utils": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@xicons/utils/-/utils-0.1.4.tgz",
"integrity": "sha512-uXxKDLz9abr80yJC05XSTq6wlyFcdW+N/1IYJkeHjzzXVc4VQ0sEYMoMMTjAH7HQBOyOkzOB4pf5NGF72lwa8Q==",
"dev": true,
"dependencies": {
"css-render": "^0.13.2"
}
},
"node_modules/@xicons/utils/node_modules/@types/node": {
"version": "14.14.45",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.45.tgz",
"integrity": "sha512-DssMqTV9UnnoxDWu959sDLZzfvqCF0qDNRjaWeYSui9xkFe61kKo4l1TWNTQONpuXEm+gLMRvdlzvNHBamzmEw==",
"dev": true
},
"node_modules/@xicons/utils/node_modules/css-render": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/css-render/-/css-render-0.13.9.tgz",
"integrity": "sha512-n3C4ZH59rveBrUlAD7n0Ze9/gUMKa4dlH1C9CWKpGcIHR/xRcIVXzBGy1iw8WWq2ySmn2/ZqOpySQNAK5Pb6sw==",
"dev": true,
"dependencies": {
"@emotion/hash": "~0.8.0",
"@types/node": "~14.14.31",
"csstype": "~3.0.5"
}
},
"node_modules/@xicons/utils/node_modules/csstype": {
"version": "3.0.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==",
"dev": true
},
"node_modules/@xtuc/ieee754": { "node_modules/@xtuc/ieee754": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@ -13170,6 +13272,11 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/sortablejs": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
"integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="
},
"node_modules/source-list-map": { "node_modules/source-list-map": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@ -14918,6 +15025,17 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true "dev": true
}, },
"node_modules/vuedraggable": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
"integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==",
"dependencies": {
"sortablejs": "1.14.0"
},
"peerDependencies": {
"vue": "^3.0.1"
}
},
"node_modules/vueuc": { "node_modules/vueuc": {
"version": "0.4.19", "version": "0.4.19",
"resolved": "https://registry.npmjs.org/vueuc/-/vueuc-0.4.19.tgz", "resolved": "https://registry.npmjs.org/vueuc/-/vueuc-0.4.19.tgz",
@ -17562,6 +17680,63 @@
} }
} }
}, },
"@vicons/antd": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/antd/-/antd-0.11.0.tgz",
"integrity": "sha512-XRkUMJzfjr3Q5S6xbAg4ALI90DIGNhZdbVW6SejFi6EgxB5bts3YMMcM4HbF77vdQX5bhxgju3Hd3uP97OgvAQ==",
"dev": true
},
"@vicons/carbon": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/carbon/-/carbon-0.11.0.tgz",
"integrity": "sha512-+Wkl8wOP1GR7jS+OKcsJ58NnZr4i+BZhbpLRtgpZQui1zFpYjoWinwvYKLjGKJ/oiR10Q237cBDjGwmMSzXqTg==",
"dev": true
},
"@vicons/fa": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/fa/-/fa-0.11.0.tgz",
"integrity": "sha512-Mlv4sxlghqAPu+RM+6w0/GIcsQFK/fx1syw1HkABS6MJRLwHOqbmImCYZQam7OMAYhZBs82YpY5cp2NFSgwkOA==",
"dev": true
},
"@vicons/fluent": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/fluent/-/fluent-0.11.0.tgz",
"integrity": "sha512-5sbdKLijk5/PBtsapDjBodskSCrfOsqOlpCbXQ33pZmY0VZ62N46Yq6SFJXHyUgFhjvReRrFe4wCGVAktchHFg==",
"dev": true
},
"@vicons/ionicons4": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/ionicons4/-/ionicons4-0.11.0.tgz",
"integrity": "sha512-2wgc2WZiQhR5AwNfiJcjxjNb910QBqeEYFXnZ0IJtfSgSUPH7lX6HEXegly3zqvLA0dmdUvyo2kI9lF/2PSbnQ==",
"dev": true
},
"@vicons/ionicons5": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/ionicons5/-/ionicons5-0.11.0.tgz",
"integrity": "sha512-4IWamqtXUsuCdlW6NQc2xyoJ+PUXGMwzSrppQbdVCYg0pjYld89jOfLOIkuTWq8o2XUa+Q1/78jzWBtXMTojNg==",
"dev": true
},
"@vicons/material": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/material/-/material-0.11.0.tgz",
"integrity": "sha512-ZQVs6Z5AjSSKqeN4GrG+5fRbi4rbvLwio06Nsjs5NGDuHCB57QHN2rwkooxeoRUbiFT4GCCKatsoWbjqE6BSZg==",
"dev": true
},
"@vicons/tabler": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@vicons/tabler/-/tabler-0.11.0.tgz",
"integrity": "sha512-ijVUphdgqTde22/4+hlZ9j2AQutpxd3piOW4cWovcnS/ELlMc/4di2/0SDxsJ6282VdZoE9Xv0dI1iSr0XKPEg==",
"dev": true
},
"@vicons/utils": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@vicons/utils/-/utils-0.1.4.tgz",
"integrity": "sha512-OHI19qVNN6i+uPQ+Y3f2s0dUxwsYnOCcKBW7XOU4yXXO1aU3ZoKpblCc3+4N0qmgoJs5rWKRAaMisipqEXJwAg==",
"dev": true,
"requires": {
"@xicons/utils": "^0.1.4"
}
},
"@vue/babel-helper-vue-jsx-merge-props": { "@vue/babel-helper-vue-jsx-merge-props": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz",
@ -18260,6 +18435,40 @@
"@xtuc/long": "4.2.2" "@xtuc/long": "4.2.2"
} }
}, },
"@xicons/utils": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@xicons/utils/-/utils-0.1.4.tgz",
"integrity": "sha512-uXxKDLz9abr80yJC05XSTq6wlyFcdW+N/1IYJkeHjzzXVc4VQ0sEYMoMMTjAH7HQBOyOkzOB4pf5NGF72lwa8Q==",
"dev": true,
"requires": {
"css-render": "^0.13.2"
},
"dependencies": {
"@types/node": {
"version": "14.14.45",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.45.tgz",
"integrity": "sha512-DssMqTV9UnnoxDWu959sDLZzfvqCF0qDNRjaWeYSui9xkFe61kKo4l1TWNTQONpuXEm+gLMRvdlzvNHBamzmEw==",
"dev": true
},
"css-render": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/css-render/-/css-render-0.13.9.tgz",
"integrity": "sha512-n3C4ZH59rveBrUlAD7n0Ze9/gUMKa4dlH1C9CWKpGcIHR/xRcIVXzBGy1iw8WWq2ySmn2/ZqOpySQNAK5Pb6sw==",
"dev": true,
"requires": {
"@emotion/hash": "~0.8.0",
"@types/node": "~14.14.31",
"csstype": "~3.0.5"
}
},
"csstype": {
"version": "3.0.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==",
"dev": true
}
}
},
"@xtuc/ieee754": { "@xtuc/ieee754": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@ -26477,6 +26686,11 @@
} }
} }
}, },
"sortablejs": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
"integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="
},
"source-list-map": { "source-list-map": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@ -27886,6 +28100,14 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true "dev": true
}, },
"vuedraggable": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
"integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==",
"requires": {
"sortablejs": "1.14.0"
}
},
"vueuc": { "vueuc": {
"version": "0.4.19", "version": "0.4.19",
"resolved": "https://registry.npmjs.org/vueuc/-/vueuc-0.4.19.tgz", "resolved": "https://registry.npmjs.org/vueuc/-/vueuc-0.4.19.tgz",

View File

@ -13,9 +13,19 @@
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-meta": "^3.0.0-alpha.8", "vue-meta": "^3.0.0-alpha.8",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",
"vuedraggable": "^4.1.0",
"vuex": "^4.0.0-0" "vuex": "^4.0.0-0"
}, },
"devDependencies": { "devDependencies": {
"@vicons/antd": "^0.11.0",
"@vicons/carbon": "^0.11.0",
"@vicons/fa": "^0.11.0",
"@vicons/fluent": "^0.11.0",
"@vicons/ionicons4": "^0.11.0",
"@vicons/ionicons5": "^0.11.0",
"@vicons/material": "^0.11.0",
"@vicons/tabler": "^0.11.0",
"@vicons/utils": "^0.1.4",
"@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0", "@vue/cli-plugin-router": "~4.5.0",

View File

@ -5,35 +5,111 @@
<n-button type="primary">Generate</n-button> <n-button type="primary">Generate</n-button>
</n-space> </n-space>
{{start_slide_image}} {{start_slide_image}}
{{slides}}
<n-space justify="space-around"> <n-space justify="space-around">
<n-input size="large" round placeholder="Photo Log title" v-model:value="title" @change="updateServerData" /> <n-input size="large" round placeholder="Photo Log title" v-model:value="title" @change="updateServerData" />
<n-date-picker v-model:value="date" type="date" @update:value="updateServerData" /> <n-date-picker v-model:value="date" type="date" @update:value="updateServerData" />
<n-button type="primary"
:disabled="!unsaved_changes"
:loading="currently_saving"
@click="saveChanges"
>
<template #icon>
<n-icon><SaveFilled /></n-icon>
</template>
{{saving_info}}
</n-button>
</n-space> </n-space>
<n-divider title-placement="center">Slides</n-divider> <n-divider title-placement="center">Slides</n-divider>
<n-space vertical> <n-space justify="center" style="min-width: 100vw;">
<n-space vertical style="max-width: 80vw; width: 600px;">
<n-card <n-card
style="width: 80%;" class="add-slide-between-button:hover"
v-for="(slide, index) in editSlides" :key="index" @click="addSlideAfter(-1)">
:title="'#'+(index+1)" > <n-space justify="center">
<n-button circle secondary type="info">
<n-icon><LibraryAddRound /></n-icon>
</n-button>
</n-space>
</n-card>
<n-image-group> <transition-group name="slide-cards">
<n-space> <draggable
<n-image :list="slides"
v-for="(photo_id, photoIndex) in slide" :key="photoIndex" item-key="id"
width="100" style="width: 100%;"
:src="getPhotoSrcById(photo_id)" >
/> <template #item="{ element: slide, index }">
<n-button round dashed type="info" @click="selectPhotosForSlide(index)"> Edit </n-button>
</n-space>
</n-image-group>
</n-card> <div>
<n-card
:title="'#'+(index+1)" class=".move-slide-handle">
<template #header-extra>
<n-space>
<n-button round secondary type="success" @click="selectPhotosForSlide(index)">
<template #icon>
<n-icon><AddPhotoAlternateOutlined /></n-icon>
</template>
Select Photos
</n-button>
<n-popconfirm
type="error"
>
<template #trigger>
<n-button
circle secondary
type="error"
>
<n-icon><TrashBinSharp /></n-icon>
</n-button>
</template>
Delete slide?
<template #action>
<n-button size="small" type="error" @click="removeSlide(index)"> Delete </n-button>
</template>
</n-popconfirm>
</n-space>
</template>
<n-image-group>
<n-space>
<draggable
:list="slide"
item-key="id"
@start="drag = true"
@end="drag = false"
>
<template #item="{element: photoid}">
<n-image
width="100"
:src="getPhotoSrcById(photoid)"
/>
</template>
</draggable>
</n-space>
</n-image-group>
</n-card>
<n-card
class="add-slide-between-button"
@click="addSlideAfter(index)">
<n-space justify="center">
<n-button circle secondary type="info">
<n-icon><LibraryAddRound /></n-icon>
</n-button>
</n-space>
</n-card>
</div>
</template>
</draggable>
</transition-group>
</n-space>
</n-space> </n-space>
<PhotoSelectModal <PhotoSelectModal
@ -41,7 +117,7 @@
@closed="selectPhotosModal=false" @closed="selectPhotosModal=false"
@selected="addPhotosToSlide" @selected="addPhotosToSlide"
:max_select=max_photos_per_slide :or_less=true :max_select=max_photos_per_slide :or_less=true
:already-selected=editSlides[selectedSlide] /> :already-selected=slides[selectedSlide] />
<n-modal v-model:show="showCreateModal" :mask-closable=false> <n-modal v-model:show="showCreateModal" :mask-closable=false>
<n-spin :show="isCreateLoading"> <n-spin :show="isCreateLoading">
@ -78,12 +154,24 @@
import { useMeta } from 'vue-meta' import { useMeta } from 'vue-meta'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import draggable from 'vuedraggable'
import TrashBinSharp from '@vicons/ionicons5/TrashBinSharp'
import LibraryAddRound from '@vicons/material/LibraryAddRound'
import AddPhotoAlternateOutlined from '@vicons/material/AddPhotoAlternateOutlined'
import SaveFilled from '@vicons/material/SaveFilled'
import PhotoSelectModal from '@/components/PhotoSelectModal' import PhotoSelectModal from '@/components/PhotoSelectModal'
export default { export default {
name: 'CreateLog', name: 'CreateLog',
components: { components: {
draggable,
PhotoSelectModal, PhotoSelectModal,
TrashBinSharp,
LibraryAddRound,
AddPhotoAlternateOutlined,
SaveFilled,
}, },
props: { props: {
e: { e: {
@ -104,10 +192,15 @@ export default {
selectPhotosModal: false, selectPhotosModal: false,
selectedSlide: null, selectedSlide: null,
max_photos_per_slide: 3, max_photos_per_slide: 3,
unsaved_changes: false,
currently_saving: false,
isLoadingData: false, isLoadingData: false,
isCreateLoading: false, isCreateLoading: false,
isSavingServer: false, isSavingServer: false,
drag: false,
} }
}, },
setup() { setup() {
@ -129,9 +222,18 @@ export default {
}) })
} }
}, },
watch: {
title: function () { this.unsaved_changes = true },
date: function () { this.unsaved_changes = true},
slides: {handler() { this.unsaved_changes = true}, deep: true},
},
computed: { computed: {
editSlides() { saving_info() {
return [...this.slides, []] if (!this.unsaved_changes)
return 'No changes made'
if (this.currently_saving)
return 'Saving...'
return 'Save Changes'
}, },
photos() { photos() {
return this.$store.getters.photos return this.$store.getters.photos
@ -153,6 +255,12 @@ export default {
} }
}, },
methods: { methods: {
saveChanges() {
this.currently_saving = true
this.updateServerData()
this.currently_saving = false
this.unsaved_changes = false
},
selectPhotosForSlide(slide_index) { selectPhotosForSlide(slide_index) {
this.selectedSlide = slide_index this.selectedSlide = slide_index
this.selectPhotosModal = true this.selectPhotosModal = true
@ -170,7 +278,12 @@ export default {
}, },
addPhotosToSlide(selected_photos) { addPhotosToSlide(selected_photos) {
this.slides[this.selectedSlide] = selected_photos this.slides[this.selectedSlide] = selected_photos
this.updateServerData() },
addSlideAfter(index) {
this.slides.splice(index+1, 0, [])
},
removeSlide(index) {
this.slides.splice(index, 1)
}, },
navigateBack() { navigateBack() {
this.$router.go(-1) this.$router.go(-1)
@ -233,7 +346,13 @@ export default {
this.render_date = found_log.render_date this.render_date = found_log.render_date
this.start_slide_image = found_log.start_slide_image this.start_slide_image = found_log.start_slide_image
this.slides = found_log.slides this.slides = found_log.slides
for(const idx in this.slides) {
this.slides[idx] = this.slides[idx].filter((s)=>s!==null)
}
this.isLoadingData = false this.isLoadingData = false
this.unsaved_changes = false
} else { } else {
this.message.error('Photo Log could not be found') this.message.error('Photo Log could not be found')
} }
@ -241,15 +360,27 @@ export default {
}, },
updateServerData() { updateServerData() {
this.isSavingServer = true this.isSavingServer = true
let server_slides = [...this.slides]
for (const idx in server_slides) {
server_slides[idx] = [
...server_slides[idx],
...new Array(
this.max_photos_per_slide-server_slides[idx].length)
.map(()=>null)]
}
this.$store.dispatch('updatePhotoLogDetails', { this.$store.dispatch('updatePhotoLogDetails', {
id: this.id, id: this.id,
title: this.title, title: this.title,
date: this.dateStr, date: this.dateStr,
render_date: this.render_date, render_date: this.render_date,
start_slide_image: this.start_slide_image, start_slide_image: this.start_slide_image,
slides: this.slides slides: server_slides
}).then(() => { }).then(() => {
this.message.success('Changes saved') this.message.success('Changes saved')
}).catch((error) => {
this.message.error('There was a problem saving the changes: '+error.message)
}).finally(() => { }).finally(() => {
this.isSavingServer = false this.isSavingServer = false
}) })
@ -275,4 +406,40 @@ export default {
.n-input { .n-input {
min-width: 30em; min-width: 30em;
} }
.add-slide-between-button, .add-slide-between-button * {
margin: 0;
padding: 0;
}
.add-slide-between-button {
cursor: pointer;
height: 1.5em;
background-color: #addeff;
overflow: hidden;
opacity: 30%;
transition: all 0.25s;
}
.add-slide-between-button:hover {
height: 5em;
opacity: 90%;
cursor: pointer;
background-color: #addeff;
}
.slide-cards-enter-active,
.slide-cards-leave-active {
transition: all 0.25s ease;
}
.slide-cards-enter-from,
.slide-cards-leave-to {
opacity: 0;
transform: translateY(30px);
}
.slide-cards-move {
transition: transform 0.25s ease;
}
</style> </style>