@conduction/nextcloud-vue 2.120.0 → 2.122.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +53 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +546 -523
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useNamedSource.js +9 -0
- package/dist/esm/components/CnIndexPage/useNamedSource.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js +1 -0
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue.js +9 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue.js.map +1 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue2.js +214 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue2.js.map +1 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue3.js +125 -0
- package/dist/esm/components/CnReadinessChecklist/CnReadinessChecklist.vue3.js.map +1 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue.js +9 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue2.js +163 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue3.js +131 -0
- package/dist/esm/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSchemaRulesWidget/schemaRules.js +127 -0
- package/dist/esm/components/CnSchemaRulesWidget/schemaRules.js.map +1 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue.js +9 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue.js.map +1 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue2.js +82 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue2.js.map +1 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue3.js +61 -0
- package/dist/esm/components/CnSearchIndexStatus/CnSearchIndexStatus.vue3.js.map +1 -0
- package/dist/esm/components/CnSearchIndexStatus/searchIndexStatus.js +60 -0
- package/dist/esm/components/CnSearchIndexStatus/searchIndexStatus.js.map +1 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue.js +10 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue.js.map +1 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue2.js +226 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue2.js.map +1 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue3.js +126 -0
- package/dist/esm/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue3.js.map +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +42 -32
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/composables/indexSources.js +116 -16
- package/dist/esm/composables/indexSources.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +42 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +42 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +309 -13
- package/dist/esm/utils/libraryWidgetKeys.js +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +14136 -12578
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +309 -13
- package/l10n/en.json +42 -1
- package/l10n/nl.json +42 -1
- package/package.json +1 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +74 -3
- package/src/components/CnIndexPage/useNamedSource.js +9 -0
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +1 -0
- package/src/components/CnReadinessChecklist/CnReadinessChecklist.vue +335 -0
- package/src/components/CnReadinessChecklist/index.js +9 -0
- package/src/components/CnSchemaRulesWidget/CnSchemaRulesWidget.vue +300 -0
- package/src/components/CnSchemaRulesWidget/index.js +10 -0
- package/src/components/CnSchemaRulesWidget/schemaRules.js +123 -0
- package/src/components/CnSearchIndexStatus/CnSearchIndexStatus.vue +160 -0
- package/src/components/CnSearchIndexStatus/index.js +10 -0
- package/src/components/CnSearchIndexStatus/searchIndexStatus.js +56 -0
- package/src/components/CnShippedConfigurationSection/CnShippedConfigurationSection.vue +328 -0
- package/src/components/CnShippedConfigurationSection/index.js +9 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +10 -0
- package/src/components/index.js +4 -0
- package/src/composables/indexSources.js +116 -16
- package/src/css/index-page.css +7 -0
- package/src/css/look-board-detail.css +27 -0
- package/src/css/look-board-index.css +108 -12
- package/src/css/look-board.css +27 -1
- package/src/index.js +4 -0
- package/src/utils/libraryWidgetKeys.js +1 -0
|
@@ -738,6 +738,14 @@ function readRowsPath(body, path) {
|
|
|
738
738
|
return String(path).split('.').reduce((value, key) => (value && typeof value === 'object' ? value[key] : undefined), body)
|
|
739
739
|
}
|
|
740
740
|
|
|
741
|
+
/**
|
|
742
|
+
* The `sourceConfig` keys the endpoint source reads itself; every other key
|
|
743
|
+
* goes along as a query parameter.
|
|
744
|
+
*
|
|
745
|
+
* @type {Array<string>}
|
|
746
|
+
*/
|
|
747
|
+
const ENDPOINT_SOURCE_KEYS = ['url', 'rowsPath', 'totalPath', 'searchParam', 'searchFields', 'notePath', 'noteText', 'refusedText'];
|
|
748
|
+
|
|
741
749
|
/**
|
|
742
750
|
* The endpoint source: rows from an app's own endpoint
|
|
743
751
|
* (`entitySource: "endpoint"`), for a list that is not OpenRegister objects,
|
|
@@ -760,25 +768,46 @@ function readRowsPath(body, path) {
|
|
|
760
768
|
* request with that tab's filter, its total read at `sourceConfig.totalPath`
|
|
761
769
|
* (`total` by default), else the number of rows the answer holds.
|
|
762
770
|
*
|
|
771
|
+
* Three more keys shape what the page says around the rows:
|
|
772
|
+
* - `searchParam`: the page's search box sends its term as this parameter
|
|
773
|
+
* (`sender`), so the endpoint does the searching.
|
|
774
|
+
* - `notePath` and `noteText`: a value read off the answer (`filterOrder`) and
|
|
775
|
+
* the sentence it is said in ("Filters run in this order: {order}", its one
|
|
776
|
+
* placeholder taking the value); a list
|
|
777
|
+
* is joined with commas. Shown above the rows.
|
|
778
|
+
* - `refusedText`: what a refused load (403) says when the endpoint gave no
|
|
779
|
+
* `message` of its own. A refusal is not an empty list, so the page shows it
|
|
780
|
+
* instead of the rows, and a failed load is not one either.
|
|
781
|
+
* - `searchFields`: the filters the endpoint takes, in the same shape a
|
|
782
|
+
* registered source declares them (`{ status: { param: 'status', single:
|
|
783
|
+
* true } }`), so a filter strip or sidebar on the page narrows the
|
|
784
|
+
* endpoint's query.
|
|
785
|
+
*
|
|
786
|
+
* @param {object} [declared] The page's `sourceConfig`, for `searchParam` and `searchFields`.
|
|
787
|
+
* @param {object} [context] The page's helpers; `translate` is the app's catalogue.
|
|
763
788
|
* @return {object} The source adapter.
|
|
764
789
|
* @spec openspec/changes/index-endpoint-source/specs/index-page/spec.md#requirement-an-index-page-can-list-rows-from-an-app-endpoint
|
|
765
790
|
*/
|
|
766
|
-
function endpointSource() {
|
|
767
|
-
const state = reactive({ rows: [], loading: false });
|
|
791
|
+
function endpointSource(declared = {}, context = {}) {
|
|
792
|
+
const state = reactive({ rows: [], loading: false, refusal: '', failed: false, note: '' });
|
|
793
|
+
const translate$1 = typeof context.translate === 'function' ? context.translate : (text) => text;
|
|
794
|
+
const searchParam = typeof declared.searchParam === 'string' && declared.searchParam !== '' ? declared.searchParam : null;
|
|
795
|
+
const searchFields = declared.searchFields && typeof declared.searchFields === 'object' && !Array.isArray(declared.searchFields) ? declared.searchFields : null;
|
|
768
796
|
let seq = 0;
|
|
769
797
|
let warned = false;
|
|
770
798
|
|
|
771
799
|
/**
|
|
772
|
-
* The query parameters for a config: every key but the
|
|
773
|
-
* empty values left out, a list joined by
|
|
800
|
+
* The query parameters for a config: every key but the source's own
|
|
801
|
+
* (`url`, the paths, the texts), empty values left out, a list joined by
|
|
802
|
+
* commas.
|
|
774
803
|
*
|
|
775
|
-
* @param {object}
|
|
804
|
+
* @param {object} config The config.
|
|
776
805
|
* @return {object} The parameters.
|
|
777
806
|
*/
|
|
778
|
-
const paramsOf = (
|
|
807
|
+
const paramsOf = (config) => {
|
|
779
808
|
const params = {};
|
|
780
|
-
for (const [key, value] of Object.entries(
|
|
781
|
-
if (value === undefined || value === null || value === '') {
|
|
809
|
+
for (const [key, value] of Object.entries(config)) {
|
|
810
|
+
if (ENDPOINT_SOURCE_KEYS.includes(key) || value === undefined || value === null || value === '') {
|
|
782
811
|
continue
|
|
783
812
|
}
|
|
784
813
|
params[key] = Array.isArray(value) ? value.join(',') : (typeof value === 'object' ? JSON.stringify(value) : value);
|
|
@@ -798,15 +827,61 @@ function endpointSource() {
|
|
|
798
827
|
return typeof url === 'string' && url !== '' && !Object.hasOwn(config, 'entitySource')
|
|
799
828
|
};
|
|
800
829
|
|
|
830
|
+
/**
|
|
831
|
+
* The note read off an answer, in the page's sentence.
|
|
832
|
+
*
|
|
833
|
+
* @param {object} body The response body.
|
|
834
|
+
* @param {string} [path] Where the value sits.
|
|
835
|
+
* @param {string} [text] The sentence, with one `{placeholder}` where the value goes.
|
|
836
|
+
* @return {string} The note, or '' when there is nothing to say.
|
|
837
|
+
*/
|
|
838
|
+
const noteOf = (body, path, text) => {
|
|
839
|
+
if (!path || !body || typeof body !== 'object' || Array.isArray(body)) {
|
|
840
|
+
return ''
|
|
841
|
+
}
|
|
842
|
+
const raw = readRowsPath(body, path);
|
|
843
|
+
const value = Array.isArray(raw) ? raw.filter((v) => v !== null && v !== undefined && v !== '').join(', ') : (raw === null || raw === undefined ? '' : String(raw));
|
|
844
|
+
if (value === '') {
|
|
845
|
+
return ''
|
|
846
|
+
}
|
|
847
|
+
return text ? translate$1(text).replace(/\{\w+\}/, value) : value
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* The sentence a refused load is said in: the endpoint's own, else the
|
|
852
|
+
* page's, else the library's.
|
|
853
|
+
*
|
|
854
|
+
* @param {object} body The refusal's body.
|
|
855
|
+
* @param {string} [text] The page's `refusedText`.
|
|
856
|
+
* @return {string} The sentence.
|
|
857
|
+
*/
|
|
858
|
+
const refusalOf = (body, text) => {
|
|
859
|
+
if (body && typeof body.message === 'string' && body.message.trim() !== '') {
|
|
860
|
+
return body.message
|
|
861
|
+
}
|
|
862
|
+
return text ? translate$1(text) : translate('nextcloud-vue', 'You may not read this list.')
|
|
863
|
+
};
|
|
864
|
+
|
|
801
865
|
return {
|
|
866
|
+
/**
|
|
867
|
+
* The parameter the page's search term is sent as, or null when this
|
|
868
|
+
* endpoint takes no search.
|
|
869
|
+
*/
|
|
870
|
+
searchParam,
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* The page filters this endpoint takes, and the parameter each becomes.
|
|
874
|
+
*/
|
|
875
|
+
searchFields,
|
|
876
|
+
|
|
802
877
|
/**
|
|
803
878
|
* Fetch the rows.
|
|
804
879
|
*
|
|
805
880
|
* @param {object} config The page's source config with the tab filter merged in.
|
|
806
|
-
* @return {Promise<void>} Resolves when loaded; a failed request leaves no rows and rethrows.
|
|
881
|
+
* @return {Promise<void>} Resolves when loaded or refused; a failed request leaves no rows and rethrows.
|
|
807
882
|
*/
|
|
808
883
|
load: async (config) => {
|
|
809
|
-
const { url, rowsPath,
|
|
884
|
+
const { url, rowsPath, notePath, noteText, refusedText } = config || {};
|
|
810
885
|
const mine = ++seq;
|
|
811
886
|
if (!requestable(config)) {
|
|
812
887
|
state.rows = [];
|
|
@@ -818,7 +893,7 @@ function endpointSource() {
|
|
|
818
893
|
}
|
|
819
894
|
return
|
|
820
895
|
}
|
|
821
|
-
const params = paramsOf(
|
|
896
|
+
const params = paramsOf(config);
|
|
822
897
|
state.loading = true;
|
|
823
898
|
try {
|
|
824
899
|
const { default: axios } = await import('@nextcloud/axios');
|
|
@@ -827,12 +902,22 @@ function endpointSource() {
|
|
|
827
902
|
const rows = Array.isArray(body) ? body : readRowsPath(body, rowsPath || 'results');
|
|
828
903
|
if (mine === seq) {
|
|
829
904
|
state.rows = Array.isArray(rows) ? rows : [];
|
|
905
|
+
state.refusal = '';
|
|
906
|
+
state.failed = false;
|
|
907
|
+
state.note = noteOf(body, notePath, noteText);
|
|
830
908
|
}
|
|
831
909
|
} catch (error) {
|
|
832
|
-
if (mine
|
|
833
|
-
|
|
910
|
+
if (mine !== seq) {
|
|
911
|
+
return
|
|
912
|
+
}
|
|
913
|
+
state.rows = [];
|
|
914
|
+
state.note = '';
|
|
915
|
+
const refused = error && error.response && error.response.status === 403;
|
|
916
|
+
state.refusal = refused ? refusalOf(error.response.data, refusedText) : '';
|
|
917
|
+
state.failed = !refused;
|
|
918
|
+
if (!refused) {
|
|
919
|
+
throw error
|
|
834
920
|
}
|
|
835
|
-
throw error
|
|
836
921
|
} finally {
|
|
837
922
|
if (mine === seq) {
|
|
838
923
|
state.loading = false;
|
|
@@ -851,9 +936,9 @@ function endpointSource() {
|
|
|
851
936
|
if (!requestable(config)) {
|
|
852
937
|
return Number.NaN
|
|
853
938
|
}
|
|
854
|
-
const { url, rowsPath, totalPath
|
|
939
|
+
const { url, rowsPath, totalPath } = config;
|
|
855
940
|
const { default: axios } = await import('@nextcloud/axios');
|
|
856
|
-
const res = await axios.get(generateUrl(url), { params: paramsOf(
|
|
941
|
+
const res = await axios.get(generateUrl(url), { params: paramsOf(config) });
|
|
857
942
|
const body = res ? res.data : null;
|
|
858
943
|
const total = body && typeof body === 'object' && !Array.isArray(body) ? readRowsPath(body, totalPath || 'total') : undefined;
|
|
859
944
|
if (typeof total === 'number' && Number.isFinite(total)) {
|
|
@@ -872,6 +957,21 @@ function endpointSource() {
|
|
|
872
957
|
* @return {boolean} Whether a load is in flight.
|
|
873
958
|
*/
|
|
874
959
|
loading: () => state.loading,
|
|
960
|
+
|
|
961
|
+
/**
|
|
962
|
+
* @return {string} The sentence the last load was refused with, or ''.
|
|
963
|
+
*/
|
|
964
|
+
refusal: () => state.refusal,
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* @return {boolean} Whether the last load failed for another reason than a refusal.
|
|
968
|
+
*/
|
|
969
|
+
failed: () => state.failed,
|
|
970
|
+
|
|
971
|
+
/**
|
|
972
|
+
* @return {string} The note read off the last answer, or ''.
|
|
973
|
+
*/
|
|
974
|
+
note: () => state.note,
|
|
875
975
|
}
|
|
876
976
|
}
|
|
877
977
|
|