Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions docs/endpoint-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,43 @@ Name | Type | Description
`object_type` | string (Optional) | Allows to filter the activities to a given object. May only appear together with `object_id` and the `filter` type filter
`object_id` | string (Optional) | Allows to filter the activities to a given object. May only appear together with `object_type` and the `filter` type filter
`sort` | string - `asc` or `desc` | Should activities be given ascending or descending (from the `since`) (Default: `desc`)
`search` | string (Optional) | Only return activities whose file path contains this substring, matched case insensitively. Must be between 2 and 255 characters
`from` | int (Optional) | Only return activities with a timestamp at or after this Unix timestamp
`to` | int (Optional) | Only return activities with a timestamp at or before this Unix timestamp
`actor` | string (Optional) | Only return activities authored by this account. At most 64 characters

### Searching and filtering by date

`search` matches against the activity's file path, so it finds activities by file
or folder name. It does not match the rendered subject, because subjects are
stored as untranslated template keys with their data held separately.

`from` and `to` are inclusive and independent: either may be given on its own for
an open ended range. Both are Unix timestamps in seconds, so the client decides
which timezone a calendar day maps onto. Values above `2147483647` are clamped to
that maximum, which is the largest value the `timestamp` column can hold.

### Filtering by account

`actor` restricts the stream to activities authored by one account, given as its
account name (user id), not its display name.

It composes with the type filter rather than replacing it: `by` combined with an
`actor` yields everyone else's activity narrowed to that one account, and `self`
combined with a different account yields nothing, since the two restrict the same
column.

### Cost

A date range is served by the `activity_user_time` index and an `actor` by
`activity_filter_by`, so both stay index-ordered and get cheaper the narrower
they are. A `search` is a substring match that no index can serve; it stays
bounded because every query is already restricted to a single user, and
combining it with a date range or an actor narrows the scan further. Terms
shorter than 2 characters are rejected rather than run, since they would scan
the user's whole stream to return a useless result.

All four parameters are carried over into the `Link` header for the next page.

## HTTP Status

Expand All @@ -58,6 +94,7 @@ Status Code | Description
`200 OK` | Activities
`204 No Content` | The user has selected no activities to be listed in the stream
`304 Not Modified` | ETag/If-None-Match are the same or the end of the activity list was reached
`400 Bad Request` | The search term is too short or too long, or `from` is after `to`
`403 Forbidden` | The offset activity belongs to a different user
`403 Forbidden` | The user is not logged in
`404 Not Found` | The filter is unknown
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,18 @@ SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
SPDX-FileCopyrightText: Sindre Sorhus
SPDX-FileCopyrightText: Stefan Thomas <justmoon@members.fsf.org> (http://www.justmoon.net)
SPDX-FileCopyrightText: Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)
SPDX-FileCopyrightText: atomiks
SPDX-FileCopyrightText: inline-style-parser developers
SPDX-FileCopyrightText: rhysd <lin90162@yahoo.co.jp>
SPDX-FileCopyrightText: ts-md5 developers

This file is generated from multiple sources. Included packages:
- @floating-ui/dom
- version: 1.7.6
- license: MIT
- @floating-ui/utils
- version: 0.2.11
- license: MIT
- @nextcloud/capabilities
- version: 1.2.1
- license: GPL-3.0-or-later
Expand Down

Large diffs are not rendered by default.

This file was deleted.

This file was deleted.

3 changes: 3 additions & 0 deletions js/ActivityTab-Cxq6JF8r.chunk.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");t.appendChild(document.createTextNode(".download-summary[data-v-81e4514f]{display:flex;align-items:flex-start;padding:8px 0;margin-bottom:calc(var(--default-grid-baseline) * 2);color:var(--color-text-maxcontrast)}.download-summary__icon[data-v-81e4514f]{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:20px;height:20px;margin-top:2px;opacity:.5}.download-summary__text[data-v-81e4514f]{padding:0 5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.activity[data-v-50818749]{display:flex;flex-direction:column;overflow:hidden;height:100%}.activity__actions[data-v-50818749]{display:flex;flex-direction:column;width:100%}.activity__list[data-v-50818749]{flex-grow:1;overflow:scroll}.activity__empty-content[data-v-50818749]{height:100%}[data-v-50818749] .empty-content__icon span{background-size:64px;width:64px;height:64px}")),document.head.appendChild(t)}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
import{l as R}from"./activity-sidebar.mjs";import{b as A,m as I,h as G,o as D}from"./NcCheckboxRadioSwitch-BVTMQSAg-DheoiI42.chunk.mjs";import{d as b,x as V,B as E,y as T,a as i,c as o,j as B,a1 as p,J as h,m as n,e as S,f as u,t as H,E as g,l as M,b as r,g as y,F as v,K as k,n as q}from"./translation-DoG5ZELJ-C5SW80h5.chunk.mjs";import{a as j}from"./index-BrNGPgve.chunk.mjs";import{j as F,f as O,A as W}from"./ActivityComponent.vue_vue_type_script_setup_true_lang-BKMWNZYb.chunk.mjs";import{l as f}from"./logger-CXg3FpL2.chunk.mjs";import{g as U,a as z,b as J}from"./api-fwrRGLr6.chunk.mjs";import"./preload-helper-DxYC2qmj.chunk.mjs";var w;(function(t){t[t.User=0]="User",t[t.Group=1]="Group",t[t.Link=3]="Link",t[t.Email=4]="Email",t[t.Remote=6]="Remote",t[t.Team=7]="Team",t[t.Guest=8]="Guest",t[t.RemoteGroup=9]="RemoteGroup",t[t.Room=10]="Room",t[t.Deck=12]="Deck",t[t.FederatedGroup=14]="FederatedGroup",t[t.ScienceMesh=15]="ScienceMesh"})(w||(w={}));const K=b({__name:"ActivitySidebarPlugin",props:{plugin:{},node:{}},emits:["reloadActivities"],setup(t,{emit:e}){const a=t,s=e,d=B();return V(()=>a.plugin.mount(d.value,{node:a.node,context:E()?.proxy??void 0,reload:()=>s("reloadActivities")})),T(()=>a.plugin.unmount()),(_,c)=>(i(),o("div",{ref_key:"attachTarget",ref:d},null,512))}}),Z='<svg xmlns="http://www.w3.org/2000/svg" id="mdi-download-circle" viewBox="0 0 24 24"><path d="M12 2C17.5 2 22 6.5 22 12C22 17.5 17.5 22 12 22C6.5 22 2 17.5 2 12C2 6.5 6.5 2 12 2M8 17H16V15H8V17M16 10H13.5V6H10.5V10H8L12 14L16 10Z" /></svg>',$=b({name:"DownloadSummary",components:{NcIconSvgWrapper:A},props:{fileId:{type:Number,required:!0}},data(){return{totalCount:0,monthlyCount:0,downloadSVG:Z}},computed:{summaryText(){return this.monthlyCount>0&&this.monthlyCount<this.totalCount?p("activity","Downloaded %n time (%s in the last 30 days)","Downloaded %n times (%s in the last 30 days)",this.totalCount,[String(this.monthlyCount)]):p("activity","Downloaded %n time","Downloaded %n times",this.totalCount)}},watch:{fileId:{immediate:!0,handler(){this.fetchCounts()}}},methods:{async fetchCounts(){if(this.fileId){this.totalCount=0,this.monthlyCount=0;try{const t=await I.get(j("apps/activity/api/v2/activity/downloads/count"),{params:{format:"json",object_type:"files",object_id:this.fileId}});this.totalCount=t.data.ocs.data.total,this.monthlyCount=t.data.ocs.data.last30d}catch(t){f.error("Failed to fetch download counts",{error:t})}}},t:h,n:p}}),Q={key:0,class:"download-summary"},X={class:"download-summary__icon"},Y={class:"download-summary__text"};function tt(t,e,a,s,d,_){const c=n("NcIconSvgWrapper");return t.totalCount>0?(i(),o("div",Q,[S("span",X,[u(c,{svg:t.downloadSVG,size:20},null,8,["svg"])]),S("span",Y,H(t.summaryText),1)])):g("",!0)}const it=G($,[["render",tt],["__scopeId","data-v-81e4514f"]]),et=b({name:"ActivityTab",components:{ActivityComponent:O,DownloadSummary:it,NcEmptyContent:F,NcIconSvgWrapper:A,NcLoadingIcon:D,ActivitySidebarPlugin:K},props:{node:{type:Object,required:!0},folder:{type:Object,required:!1,default:void 0},view:{type:Object,required:!1,default:void 0}},expose:["update"],data(){return{error:"",loading:!0,activities:[],lightningBoltSVG:R,sidebarPlugins:[]}},computed:{hasPublicLink(){return Object.values(this.node?.attributes?.["share-types"]??{}).flat().includes(w.Link)}},watch:{node:{immediate:!0,async handler(){await this.update()}}},async mounted(){this.node&&await this.update()},methods:{async update(){this.sidebarPlugins=[];const t=J();t.length>0&&M(()=>{this.sidebarPlugins=t}),this.resetState(),await this.getActivities()},async getActivities(){try{this.loading=!0;const t=await this.processActivities(await this.loadRealActivities()),e=await z({node:this.node});this.activities=[...t,...e].sort((a,s)=>s.timestamp-a.timestamp)}catch(t){this.error=h("activity","Unable to load the activity list"),f.error("Error loading the activity list",{error:t})}finally{this.loading=!1}},resetState(){this.loading=!0,this.error="",this.activities=[]},async loadRealActivities(){try{const{data:t}=await I.get(j("apps/activity/api/v2/activity/filter"),{params:{format:"json",object_type:"files",object_id:this.node.fileid}});return t.ocs.data}catch(t){if(t.response!==void 0&&t.response.status===304)return[];throw t}},processActivities(t){t=t.map(a=>new W(a)),f.debug(`Processed ${t.length} activity(ies)`,{activities:t,node:this.node});const e=U();return t.filter(a=>!e||e.every(s=>s(a)))},t:h}}),at={key:0,class:"activity__actions"},ot={key:4,class:"activity__list"};function st(t,e,a,s,d,_){const c=n("NcIconSvgWrapper"),m=n("NcEmptyContent"),P=n("ActivitySidebarPlugin"),x=n("DownloadSummary"),L=n("NcLoadingIcon"),N=n("ActivityComponent");return i(),o("div",{class:q([{"icon-loading":t.loading},"activity"])},[t.error||!t.node?(i(),r(m,{key:0,name:t.error},{icon:y(()=>[u(c,{svg:t.lightningBoltSVG},null,8,["svg"])]),_:1},8,["name"])):(i(),o(v,{key:1},[t.sidebarPlugins.length>0?(i(),o("div",at,[(i(!0),o(v,null,k(t.sidebarPlugins,(l,C)=>(i(),r(P,{key:C,plugin:l,node:t.node,onReloadActivities:e[0]||(e[0]=nt=>t.getActivities())},null,8,["plugin","node"]))),128))])):g("",!0),t.hasPublicLink&&t.node.fileid?(i(),r(x,{key:1,fileId:t.node.fileid},null,8,["fileId"])):g("",!0),t.loading?(i(),r(m,{key:2,class:"activity__empty-content",name:t.t("activity","Loading activities")},{icon:y(()=>[u(L)]),_:1},8,["name"])):t.activities.length===0?(i(),r(m,{key:3,class:"activity__empty-content",name:t.t("activity","No activity yet")},{icon:y(()=>[u(c,{svg:t.lightningBoltSVG},null,8,["svg"])]),_:1},8,["name"])):(i(),o("ul",ot,[(i(!0),o(v,null,k(t.activities,l=>(i(),r(N,{key:l.id,activity:l,showPreviews:!1,onReload:e[1]||(e[1]=C=>t.getActivities())},null,8,["activity"]))),128))]))],64))],2)}const vt=G(et,[["render",st],["__scopeId","data-v-50818749"]]);export{vt as default};
//# sourceMappingURL=ActivityTab-Cxq6JF8r.chunk.mjs.map

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions js/ActivityTab-EzBumh36.chunk.mjs

This file was deleted.

21 changes: 21 additions & 0 deletions js/NcCheckboxRadioSwitch-BVTMQSAg-DheoiI42.chunk.mjs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions js/NcCheckboxRadioSwitch-BVTMQSAg-DheoiI42.chunk.mjs.map

Large diffs are not rendered by default.

21 changes: 0 additions & 21 deletions js/_plugin-vue_export-helper-YgYGpvaA.chunk.mjs

This file was deleted.

1 change: 0 additions & 1 deletion js/_plugin-vue_export-helper-YgYGpvaA.chunk.mjs.map

This file was deleted.

Loading
Loading