-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
dd63f1e
commit 3d2e7d5
Showing
11 changed files
with
455 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[main] | ||
host = https://www.transifex.com | ||
|
||
[o:owncloud-org:p:owncloud-web:r:app-activities] | ||
file_filter = locale/<lang>/app.po | ||
minimum_perc = 0 | ||
source_file = template.pot | ||
source_lang = en | ||
type = PO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"name": "web-app-activities", | ||
"version": "0.0.0", | ||
"private": true, | ||
"description": "ownCloud activities app", | ||
"license": "AGPL-3.0", | ||
"devDependencies": { | ||
"web-test-helpers": "workspace:*" | ||
}, | ||
"peerDependencies": { | ||
"@ownclouders/web-client": "workspace:*", | ||
"@ownclouders/web-pkg": "workspace:*", | ||
"design-system": "workspace:@ownclouders/design-system@*", | ||
"fuse.js": "7.0.0", | ||
"lodash-es": "4.17.21", | ||
"mark.js": "^8.11.1", | ||
"pinia": "2.2.2", | ||
"vue-concurrency": "5.0.1", | ||
"vue-router": "4.2.5", | ||
"zod": "3.23.8" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<template> | ||
<main id="activities"> | ||
<router-view /> | ||
</main> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { defineComponent } from 'vue' | ||
export default defineComponent({ | ||
name: 'LayoutContainer' | ||
}) | ||
</script> | ||
|
||
<style lang="scss"> | ||
#activities { | ||
overflow: auto; | ||
padding: var(--oc-space-medium) !important; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const APPID = 'activities' |
85 changes: 85 additions & 0 deletions
85
packages/web-app-activities/src/components/ActivityItem.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<template> | ||
<div class="oc-flex oc-flex-middle activity-item"> | ||
<div class="oc-flex oc-flex-middle"> | ||
<oc-avatar :width="36" :user-name="activity.template.variables.user.displayName" /> | ||
<span class="oc-ml-s" v-text="activity.template.variables.user.displayName" /> | ||
</div> | ||
<div>activity unknown</div> | ||
<div class="oc-text-truncate"> | ||
<resource-list-item v-if="resource" :resource="resource" :is-resource-clickable="false" /> | ||
<div v-if="resourceDeleted" class="oc-text-muted oc-flex oc-flex-middle oc-p-xs"> | ||
<oc-icon name="delete-bin" /> | ||
<span class="oc-ml-s" v-text="activity.template.variables.resource.name" /> | ||
</div> | ||
</div> | ||
<div><span v-text="modifiedDateTime"></span></div> | ||
</div> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { computed, defineComponent, onMounted, PropType, ref, unref } from 'vue' | ||
import { Activity } from '@ownclouders/web-client/src/graph/generated' | ||
import { DateTime } from 'luxon' | ||
import { formatDateFromDateTime, ResourceListItem, useClientService } from '@ownclouders/web-pkg' | ||
import { useGettext } from 'vue3-gettext' | ||
import { Resource } from '@ownclouders/web-client' | ||
export default defineComponent({ | ||
name: 'ActivityList', | ||
components: { ResourceListItem }, | ||
props: { | ||
activity: { | ||
type: Object as PropType<Activity>, | ||
required: true | ||
} | ||
}, | ||
setup(props) { | ||
const clientService = useClientService() | ||
const { current: currentLanguage } = useGettext() | ||
const resource = ref<Resource>() | ||
const resourceDeleted = ref(false) | ||
const modifiedDateTime = computed(() => { | ||
const dateTime = DateTime.fromISO(props.activity.times.recordedTime) | ||
return formatDateFromDateTime(dateTime, currentLanguage) | ||
}) | ||
onMounted(async () => { | ||
try { | ||
resource.value = await clientService.webdav.getFileInfo( | ||
unref(props.activity.template.variables.space.id), | ||
{ fileId: props.activity.template.variables.resource.id } | ||
) | ||
} catch (e) { | ||
resourceDeleted.value = true | ||
} | ||
}) | ||
return { | ||
modifiedDateTime, | ||
resource, | ||
resourceDeleted | ||
} | ||
} | ||
}) | ||
</script> | ||
|
||
<style lang="scss"> | ||
.activity-item { | ||
.oc-resource-name { | ||
text-overflow: ellipsis; | ||
white-space: nowrap; | ||
max-width: 100%; | ||
overflow: hidden; | ||
} | ||
} | ||
.activity-item > * { | ||
flex: 1; | ||
text-align: left; | ||
} | ||
.activity-item > *:last-child { | ||
text-align: right !important; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import translations from '../l10n/translations.json' | ||
import { useGettext } from 'vue3-gettext' | ||
import { computed } from 'vue' | ||
import { AppMenuItemExtension, defineWebApplication, Extension } from '@ownclouders/web-pkg' | ||
import { urlJoin } from '@ownclouders/web-client' | ||
import { RouteRecordRaw } from 'vue-router' | ||
import { APPID } from './appid' | ||
|
||
export default defineWebApplication({ | ||
setup() { | ||
const { $gettext } = useGettext() | ||
|
||
const appInfo = { | ||
name: $gettext('Activities'), | ||
id: APPID, | ||
icon: 'pulse', | ||
color: '#ff6961' | ||
} | ||
|
||
const routes: RouteRecordRaw[] = [ | ||
{ | ||
path: '/', | ||
name: 'root', | ||
component: () => import('./LayoutContainer.vue'), | ||
redirect: urlJoin(appInfo.id, 'list'), | ||
meta: { | ||
authContext: 'user' | ||
}, | ||
children: [ | ||
{ | ||
path: 'list', | ||
name: 'list', | ||
component: () => import('./views/App.vue'), | ||
meta: { | ||
authContext: 'user', | ||
title: $gettext('Activities') | ||
} | ||
} | ||
] | ||
} | ||
] | ||
|
||
const menuItemExtension: AppMenuItemExtension = { | ||
id: `app.${appInfo.id}.menuItem`, | ||
type: 'appMenuItem', | ||
label: () => appInfo.name, | ||
color: appInfo.color, | ||
icon: appInfo.icon, | ||
priority: 30, | ||
path: urlJoin(appInfo.id) | ||
} | ||
const extensions = computed(() => { | ||
const result: Extension[] = [] | ||
|
||
result.push(menuItemExtension) | ||
|
||
return result | ||
}) | ||
|
||
return { | ||
appInfo, | ||
routes, | ||
translations, | ||
extensions | ||
} | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<template> | ||
<ul class="oc-list activity-list"> | ||
<li v-for="(activities, date) in activitiesDateCategorized" :key="date" class="oc-mb-l"> | ||
<span class="oc-text-bold oc-text-muted activity-list-date" v-text="getListDate(date)" /> | ||
<ul class="oc-ml-s oc-mt-s timeline"> | ||
<li v-for="activityItem in activities" :key="activityItem"> | ||
<ActivityItem :activity="activityItem" /> | ||
</li> | ||
</ul> | ||
</li> | ||
</ul> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { computed, defineComponent, PropType } from 'vue' | ||
import { Activity } from '@ownclouders/web-client/graph/generated' | ||
import { DateTime } from 'luxon' | ||
import ActivityItem from '../components/ActivityItem.vue' | ||
import { formatDateFromDateTime } from '@ownclouders/web-pkg' | ||
import { useGettext } from 'vue3-gettext' | ||
export default defineComponent({ | ||
name: 'ActivityList', | ||
components: { ActivityItem }, | ||
props: { | ||
activities: { | ||
type: Array as PropType<Activity[]>, | ||
required: true | ||
} | ||
}, | ||
setup(props) { | ||
const { current: currentLanguage } = useGettext() | ||
const activitiesDateCategorized = computed(() => { | ||
return props.activities.reduce((acc, activity) => { | ||
const date = DateTime.fromISO(activity.times.recordedTime).toISODate() | ||
if (!acc[date]) { | ||
acc[date] = [] | ||
} | ||
acc[date].push(activity) | ||
// TODO: Remove mock data | ||
const date2 = DateTime.fromISO(activity.times.recordedTime).minus({ day: 1 }).toISODate() | ||
if (!acc[date2]) { | ||
acc[date2] = [] | ||
} | ||
acc[date2].push(activity) | ||
const date3 = DateTime.fromISO(activity.times.recordedTime).minus({ day: 2 }).toISODate() | ||
if (!acc[date3]) { | ||
acc[date3] = [] | ||
} | ||
acc[date3].push(activity) | ||
return acc | ||
}, {}) | ||
}) | ||
const getListDate = (dateISO: string) => { | ||
const dateTime = DateTime.fromISO(dateISO) | ||
if ( | ||
dateTime.hasSame(DateTime.now(), 'day') || | ||
dateTime.hasSame(DateTime.now().minus({ day: 1 }), 'day') | ||
) { | ||
return dateTime.toRelativeCalendar({ locale: currentLanguage }) | ||
} | ||
return formatDateFromDateTime(dateTime, currentLanguage, DateTime.DATE_MED_WITH_WEEKDAY) | ||
} | ||
return { activitiesDateCategorized, getListDate } | ||
} | ||
}) | ||
</script> | ||
|
||
<style lang="scss"> | ||
.activity-list { | ||
max-width: 1000px; | ||
&-date { | ||
text-transform: capitalize; | ||
} | ||
} | ||
</style> |
Oops, something went wrong.