@@ -92,6 +97,7 @@ import Finance from 'vue-material-design-icons/Finance.vue'
import BookOpenVariantOutline from 'vue-material-design-icons/BookOpenVariantOutline.vue'
import OfficeBuildingOutline from 'vue-material-design-icons/OfficeBuildingOutline.vue'
import ShapeOutline from 'vue-material-design-icons/ShapeOutline.vue'
+import Web from 'vue-material-design-icons/Web.vue'
export default {
name: 'MainMenu',
@@ -114,6 +120,7 @@ export default {
BookOpenVariantOutline,
OfficeBuildingOutline,
ShapeOutline,
+ Web,
},
data() {
return {
diff --git a/src/sidebars/directory/DirectorySideBar.vue b/src/sidebars/directory/DirectorySideBar.vue
index 55cdb449..849c394d 100644
--- a/src/sidebars/directory/DirectorySideBar.vue
+++ b/src/sidebars/directory/DirectorySideBar.vue
@@ -46,7 +46,7 @@ import { navigationStore, directoryStore, publicationTypeStore } from '../../sto
Samenvatting:
- {{ directoryStore.listingItem?.summery }}
+ {{ directoryStore.listingItem?.summary }}
Status:
diff --git a/src/store/modules/page.spec.ts b/src/store/modules/page.spec.ts
new file mode 100644
index 00000000..be1dbb7a
--- /dev/null
+++ b/src/store/modules/page.spec.ts
@@ -0,0 +1,53 @@
+/* eslint-disable no-console */
+import { setActivePinia, createPinia } from 'pinia'
+
+import { usePageStore } from './page.js'
+import { mockPage, Page } from '../../entities/index.js'
+
+describe('Page Store', () => {
+ beforeEach(() => {
+ setActivePinia(createPinia())
+ })
+
+ it('sets page item correctly', () => {
+ const store = usePageStore()
+
+ store.setPageItem(mockPage()[0])
+
+ expect(store.pageItem).toBeInstanceOf(Page)
+ expect(store.pageItem).toEqual(mockPage()[0])
+ expect(store.pageItem.validate().success).toBe(true)
+
+ store.setPageItem(mockPage()[1])
+
+ expect(store.pageItem).toBeInstanceOf(Page)
+ expect(store.pageItem).toEqual(mockPage()[1])
+ expect(store.pageItem.validate().success).toBe(true)
+
+ store.setPageItem(mockPage()[2])
+
+ expect(store.pageItem).toBeInstanceOf(Page)
+ expect(store.pageItem).toEqual(mockPage()[2])
+ expect(store.pageItem.validate().success).toBe(false)
+ })
+
+ it('sets page list correctly', () => {
+ const store = usePageStore()
+
+ store.setPageList(mockPage())
+
+ expect(store.pageList).toHaveLength(mockPage().length)
+
+ expect(store.pageList[0]).toBeInstanceOf(Page)
+ expect(store.pageList[0]).toEqual(mockPage()[0])
+ expect(store.pageList[0].validate().success).toBe(true)
+
+ expect(store.pageList[1]).toBeInstanceOf(Page)
+ expect(store.pageList[1]).toEqual(mockPage()[1])
+ expect(store.pageList[1].validate().success).toBe(true)
+
+ expect(store.pageList[2]).toBeInstanceOf(Page)
+ expect(store.pageList[2]).toEqual(mockPage()[2])
+ expect(store.pageList[2].validate().success).toBe(false)
+ })
+})
diff --git a/src/store/modules/page.ts b/src/store/modules/page.ts
new file mode 100644
index 00000000..0d132a7c
--- /dev/null
+++ b/src/store/modules/page.ts
@@ -0,0 +1,160 @@
+/* eslint-disable no-console */
+import { Page, TPage } from '../../entities/index.js'
+import { defineStore } from 'pinia'
+
+const apiEndpoint = '/index.php/apps/opencatalogi/api/pages'
+
+interface Options {
+ /**
+ * Do not save the received item to the store, this can be enabled if API calls get run in a loop
+ */
+ doNotSetStore?: boolean
+}
+
+interface PageStoreState {
+ pageItem: Page;
+ pageList: Page[];
+}
+
+export const usePageStore = defineStore('page', {
+ state: () => ({
+ pageItem: null,
+ pageList: [],
+ } as PageStoreState),
+ actions: {
+ setPageItem(pageItem: Page | TPage) {
+ this.pageItem = pageItem && new Page(pageItem as TPage)
+ console.log('Active page item set to ' + pageItem && pageItem?.id)
+ },
+ setPageList(pageList: Page[] | TPage[]) {
+ this.pageList = pageList.map(
+ (pageItem) => new Page(pageItem as TPage),
+ )
+ console.log('Page list set to ' + pageList.length + ' items')
+ },
+ /* istanbul ignore next */ // ignore this for Jest until moved into a service
+ async refreshPageList(search: string = null) {
+ // @todo this might belong in a service?
+ let endpoint = apiEndpoint
+ if (search !== null && search !== '') {
+ endpoint = endpoint + '?_search=' + search
+ }
+ const response = await fetch(
+ endpoint, {
+ method: 'GET',
+ },
+ )
+ const rawData = (await response.json()).results
+ const data = rawData.map((pageItem: TPage) => new Page(pageItem))
+
+ this.setPageList(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async getAllPages(options: Options = {}) {
+ const response = await fetch(
+ `${apiEndpoint}`,
+ { method: 'get' },
+ )
+
+ const rawData = await response.json()
+
+ const data = rawData.results.map((pageItem: TPage) => new Page(pageItem))
+
+ options.doNotSetStore !== true && this.setPageList(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async getOnePage(id: number, options: Options = {}) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'get' },
+ )
+
+ const data = new Page(await response.json())
+
+ options.doNotSetStore !== true && this.setPageItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async addPage(item: Page) {
+ if (!(item instanceof Page)) {
+ throw Error('Please pass a Page item from the Page class')
+ }
+
+ const validateResult = item.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(apiEndpoint,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Page(await response.json())
+
+ this.refreshPageList()
+ this.setPageItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async editPage(pageItem: Page) {
+ if (!(pageItem instanceof Page)) {
+ throw Error('Please pass a Page item from the Page class')
+ }
+
+ const validateResult = pageItem.validate()
+ if (!validateResult.success) {
+ throw Error(validateResult.error.issues[0].message)
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${pageItem.id}`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(validateResult.data),
+ },
+ )
+
+ const data = new Page(await response.json())
+
+ this.refreshPageList()
+ this.setPageItem(data)
+
+ return { response, data }
+ },
+ /* istanbul ignore next */
+ async deletePage(id: number) {
+ if (!id) {
+ throw Error('Passed id is falsy')
+ }
+
+ const response = await fetch(
+ `${apiEndpoint}/${id}`,
+ { method: 'DELETE' },
+ )
+
+ this.refreshPageList()
+ this.setPageItem(null)
+
+ return { response }
+ },
+ },
+})
diff --git a/src/store/store.js b/src/store/store.js
index 1eddc424..0f1b9e7d 100644
--- a/src/store/store.js
+++ b/src/store/store.js
@@ -14,6 +14,7 @@ import { useOrganizationStore } from './modules/organization'
import { usePublicationStore } from './modules/publication'
import { useSearchStore } from './modules/search'
import { useThemeStore } from './modules/theme'
+import { usePageStore } from './modules/page'
const navigationStore = useNavigationStore(pinia)
const searchStore = useSearchStore(pinia)
@@ -24,6 +25,7 @@ const publicationStore = usePublicationStore(pinia)
const organizationStore = useOrganizationStore(pinia)
const themeStore = useThemeStore(pinia)
const configurationStore = useConfigurationStore(pinia)
+const pageStore = usePageStore(pinia)
export {
// generic
@@ -37,4 +39,5 @@ export {
organizationStore,
themeStore,
configurationStore,
+ pageStore,
}
diff --git a/src/views/AdminSettings.vue b/src/views/AdminSettings.vue
index 9e739032..fd731879 100644
--- a/src/views/AdminSettings.vue
+++ b/src/views/AdminSettings.vue
@@ -13,7 +13,7 @@
@click="openLink('/index.php/settings/apps/organization/openregister', '_blank')">
-
+
Installeer Open Registers
@@ -244,6 +244,41 @@
+ Pagina
+
+
+
+
+
+
+
+
+
+
+
+
+ Opslaan
+
+
+
Publicatie Type
+
@@ -23,6 +24,7 @@ import { NcAppContent } from '@nextcloud/vue'
import Catalogi from './catalogi/CatalogiIndex.vue'
import Organizations from './organizations/OrganizationIndex.vue'
import Themes from './themes/ThemeIndex.vue'
+import Pages from './pages/PageIndex.vue'
import Dashboard from './dashboard/DashboardIndex.vue'
import Directory from './directory/DirectoryIndex.vue'
import PublicationType from './publicationType/PublicationTypeIndex.vue'
@@ -35,6 +37,7 @@ export default {
Catalogi,
Organizations,
Themes,
+ Pages,
Dashboard,
Directory,
PublicationType,
diff --git a/src/views/pages/PageDetail.vue b/src/views/pages/PageDetail.vue
new file mode 100644
index 00000000..a6d07cab
--- /dev/null
+++ b/src/views/pages/PageDetail.vue
@@ -0,0 +1,217 @@
+
+
+
+
+
+
+ {{ page.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Help
+
+
+
+
+
+ Bewerken
+
+
+
+
+
+ Kopiƫren
+
+
+
+
+
+ Verwijderen
+
+
+
+
+
+
+ Name:
+ {{ page.name }}
+
+
+ Slug:
+ {{ page.slug }}
+
+
+ Laatst bijgewerkt:
+ {{ page.updatedAt }}
+
+
+
+
+
+
+ {{ JSON.stringify(page.contents, null, 2) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/pages/PageIndex.vue b/src/views/pages/PageIndex.vue
new file mode 100644
index 00000000..5e4cbbb3
--- /dev/null
+++ b/src/views/pages/PageIndex.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pagina toevoegen
+
+
+
+
+
+
+
+
+
diff --git a/src/views/pages/PageList.vue b/src/views/pages/PageList.vue
new file mode 100644
index 00000000..e253895c
--- /dev/null
+++ b/src/views/pages/PageList.vue
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ page?.slug }}
+
+
+
+
+
+
+ Bewerken
+
+
+
+
+
+ Kopiƫren
+
+
+
+
+
+ Verwijderen
+
+
+
+
+
+
+
+
+
+
+
+
+