diff options
author | Carl Schwan <carl@carlschwan.eu> | 2022-08-31 22:15:37 +0200 |
---|---|---|
committer | Carl Schwan <carl@carlschwan.eu> | 2022-08-31 22:15:37 +0200 |
commit | cecb50730271ecc5cadebab0085690b3b19725b4 (patch) | |
tree | e147a5cafafd4ca0137d92cbdfccdf3bb6550011 | |
parent | 47cc783b637de75a72a6f8b721edb3cb34934ea0 (diff) |
Fix some issues and start cleaning up stuffport-vue-main-ui
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
-rw-r--r-- | src/App.vue | 16 | ||||
-rw-r--r-- | src/api.js | 54 | ||||
-rw-r--r-- | src/components/AddFeed.vue | 188 | ||||
-rw-r--r-- | src/components/Explore.vue | 58 |
4 files changed, 206 insertions, 110 deletions
diff --git a/src/App.vue b/src/App.vue index ad80f18d5..6ff5bf5b7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,22 +1,22 @@ <template> - <Content app-name="news"> + <NcContent app-name="news"> <Sidebar /> - <AppContent> + <NcAppContent> <router-view /> - </AppContent> - </Content> + </NcAppContent> + </NcContent> </template> <script> -import Content from '@nextcloud/vue/dist/Components/Content' -import AppContent from '@nextcloud/vue/dist/Components/AppContent' +import NcContent from '@nextcloud/vue/dist/Components/NcContent.js' +import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js' import Sidebar from './components/Sidebar.vue' export default { components: { - Content, + NcContent, + NcAppContent, Sidebar, - AppContent, }, created() { this.$store.dispatch('loadFolder') diff --git a/src/api.js b/src/api.js new file mode 100644 index 000000000..b7a4e0df3 --- /dev/null +++ b/src/api.js @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu> +// SPDX-Licence-Identifier: AGPL-3.0-or-later + +import axios from '@nextcloud/axios' +import { generateUrl } from '@nextcloud/router' + +export default { + folder: { + async create(name) { + const { data } = await axios.post(generateUrl('/apps/news/api/v2/folders'), { + name, + }) + return data.folders + }, + async update(folderId, name) { + await axios.patch(generateUrl('/apps/news/api/v2/folders/{folderId}', { + folderId, + name, + })) + }, + async delete(folderId) { + await axios.post(generateUrl('/apps/news/api/v2/folders/{folderId}', { + folderId, + })) + }, + async index() { + const { data } = await axios.post(generateUrl('/apps/news/api/v1-3/folders')) + return data.folders + }, + async read(folderId, newestItemId = 0) { + const { data } = await axios.post(generateUrl('/apps/news/api/v1-3/folders/{folderId}/read', { + folderId, + }, { + newestItemId, + })) + }, + }, + feed: { + async get() { + const { data } = await axios.get(generateUrl('/apps/news/feeds')) + return data.feeds + } + async add({ feedUrl, folderId }) { + let url = feedUrl.trim() + if (!url.startsWith('http')) { + url = 'https://' + url + } + const { data } = await axios.post(generateUrl('/apps/news/feeds'), { + folderId, + url, + }) + }, + }, +} diff --git a/src/components/AddFeed.vue b/src/components/AddFeed.vue index 7ab421554..4718cb846 100644 --- a/src/components/AddFeed.vue +++ b/src/components/AddFeed.vue @@ -1,107 +1,82 @@ <template> - <NcModal @close="$emit('close')"> - <div id="new-feed" news-add-feed="Navigation.feed"> - <form ng-submit="Navigation.createFeed(Navigation.feed)" - ng-init="Navigation.feed.autoDiscover=true" - name="feedform"> - <fieldset ng-disabled="Navigation.addingFeed" style="padding: 16px"> - <input type="text" - :value="feed" - ng-model="Navigation.feed.url" - ng-class="{'ng-invalid': - !Navigation.addingFeed && - Navigation.feedUrlExists(Navigation.feed.url) - }" - :placeholder="t('news', 'Web address')" - name="address" - pattern="[^\s]+" - required - autofocus> - - <p class="error" - ng-show="!Navigation.addingFeed && - Navigation.feedUrlExists(Navigation.feed.url)"> - {{ t("news", "Feed exists already!") }} - </p> - - <!-- select a folder --> - <CheckboxRadioSwitch :checked.sync="createNewFolder" type="switch"> - {{ t("news", "New folder") }}? - </CheckboxRadioSwitch> - - <NcMultiselect v-if="!createNewFolder" - v-model="folder" + <NcModal @close="$emit('close')" :title="t('news', 'Add new feed')"> + <div class="add-feed"> + <h2>{{ t('news', 'Add new feed') }}</h2> + <form ng-submit="Navigation.createFeed(Navigation.feed)" name="feedform"> + <NcTextField type="text" + :value.sync="feedUrl" + :label="t('news', 'Web address')" + placeholder="https://..." + :labelVisible="true" + pattern="[^\s]+" + required + autofocus + :error="feedAlreadyExists" /> + + <!-- select a folder --> + <NcCheckboxRadioSwitch :checked.sync="createNewFolder" type="switch"> + {{ t("news", "New folder") }}? + </NcCheckboxRadioSwitch> + + <div v-if="!createNewFolder"> + <label for="name">{{ t('news', 'Folder name') }}</label> + <NcMultiselect v-model="folder" :options="folders" track-by="id" label="name" /> - - <!-- add a folder --> - <input v-if="createNewFolder" - type="text" - ng-model="Navigation.feed.newFolder" - ng-class="{'ng-invalid': - !Navigation.addingFeed && - !Navigation.addingFeed && - Navigation.showNewFolder && - Navigation.folderNameExists( - Navigation.feed.newFolder - ) - }" - :placeholder="t('news', 'Folder name')" - name="folderName" - style="width: 90%" - required> - - <p class="error" - ng-show="!Navigation.addingFeed && - Navigation.folderNameExists(Navigation.feed.newFolder)"> - {{ t("news", "Folder exists already!") }} + </div> + + <!-- add a folder --> + <NcTextField v-if="createNewFolder" + :label="t('news', 'Folder name')" + :labelVisible="true" + :value.sync="folderName" + required /> + + <!-- basic auth --> + <NcCheckboxRadioSwitch :checked.sync="withBasicAuth" type="switch"> + {{ t("news", "Credentials") }}? + </NcCheckboxRadioSwitch> + + <fieldset v-if="withBasicAuth" class="add-feed-basicauth"> + <p class="warning"> + {{ + t( + "news", + "HTTP Basic Auth credentials must be stored unencrypted! Everyone with access to the server or database will be able to access them!" + ) + }}> </p> - - <!-- basic auth --> - - <CheckboxRadioSwitch :checked.sync="withBasicAuth" type="switch"> - {{ t("news", "Credentials") }}? - </CheckboxRadioSwitch> - - <div v-if="withBasicAuth" class="add-feed-basicauth"> - <p class="warning"> - {{ - t( - "news", - "HTTP Basic Auth credentials must be stored unencrypted! Everyone with access to the server or database will be able to access them!" - ) - }}> - </p> - <input type="text" - ng-model="Navigation.feed.user" - :placeholder="t('news', 'Username')" - name="user" - autofocus> - - <input type="password" - ng-model="Navigation.feed.password" - :placeholder="t('news', 'Password')" - name="password" - autocomplete="new-password"> - </div> - - <NcCheckboxRadioSwitch :checked.sync="autoDiscover" type="switch"> - {{ t("news", "Auto discover Feed") }}? - </NcCheckboxRadioSwitch> - - <NcButton :wide="true" - type="primary" - ng-disabled=" - Navigation.feedUrlExists(Navigation.feed.url) || - ( - Navigation.showNewFolder && - Navigation.folderNameExists(folder.name) - )" - @click="addFeed()"> - {{ t("news", "Subscribe") }} - </NcButton> + <NcTextField type="text" + :label="t('news', 'Username')" + :labelVisible="true" + :value="username" + name="user" + autofocus /> + + <NcTextField type="password" + :label="t('news', 'Password')" + :labelVisible="true" + :value="password" + name="password" + autocomplete="new-password" /> </fieldset> + + <NcCheckboxRadioSwitch :checked.sync="autoDiscover" type="switch"> + {{ t("news", "Auto discover Feed") }}? + </NcCheckboxRadioSwitch> + + <NcButton :wide="true" + type="primary" + ng-disabled=" + Navigation.feedUrlExists(Navigation.feed.url) || + ( + Navigation.showNewFolder && + Navigation.folderNameExists(folder.name) + )" + @click="addFeed()"> + {{ t("news", "Subscribe") }} + </NcButton> </form> </div> </NcModal> @@ -114,6 +89,7 @@ import NcModal from '@nextcloud/vue/dist/Components/NcModal.js' import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' import NcMultiselect from '@nextcloud/vue/dist/Components/NcMultiselect.js' +import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js' export default { name: 'AddFeed', @@ -122,6 +98,7 @@ export default { NcCheckboxRadioSwitch, NcButton, NcMultiselect, + NcTextField, }, props: { feed: '', @@ -129,10 +106,15 @@ export default { emits: ['close'], data() { return { + feedUrl: '', + folderName: '', + password: '', + username: '', folder: {}, autoDiscover: true, createNewFolder: false, withBasicAuth: false, + feedAlreadyExists: false, } }, computed: { @@ -160,7 +142,15 @@ export default { } </script> -<style scoped> +<style scoped lang="scss"> +.add-feed { + padding: 1rem; + form { + display: flex; + flex-direction: column; + gap: 1rem; + } +} input { width: 100% } diff --git a/src/components/Explore.vue b/src/components/Explore.vue index 562d72ae8..a491ca406 100644 --- a/src/components/Explore.vue +++ b/src/components/Explore.vue @@ -22,9 +22,12 @@ <img :src="entry.image"> </div> </div> - <Button @click="subscribe(entry.feed)"> - {{ t("news", "Subscribe to") }} {{ entry.title }} - </Button> + <NcButton @click="subscribe(entry.feed)" + type="primary" + class="grid-item__button" + :wide="true"> + {{ t("news", "Subscribe to {title}", {title: entry.title}) }} + </NcButton> </div> </div> </div> @@ -76,3 +79,52 @@ export default { }, } </script> + +<style lang="scss" scoped> +.grid-container { + padding: 1rem; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + /* This is better for small screens, once min() is better supported */ + /* grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); */ + gap: 1rem; + + .grid-item { + border: 2px solid var(--color-border); + border-radius: var(--border-radius-large); + padding: 1rem; + display: flex; + flex-direction: column; + + &__button { + margin-top: auto; + } + } + .grid-item .explore-title { + background-repeat: no-repeat; + background-position: 0 center; + background-size: 24px; + padding-left: 32px; + } + .grid-item .explore-title a { + word-wrap: break-word; + } + .grid-item .explore-title a:hover, #explore .grid-item .explore-title a:focus { + text-decoration: underline; + } + .grid-item .explore-logo { + text-align: center; + margin-top: 25px; + } + .grid-item .explore-logo img { + width: 100%; + } + .grid-item .explore-subscribe { + margin-top: 16px; + max-width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} +</style> |