@camstack/addon-waste-collections 0.1.2 → 0.1.3
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/waste-collections.addon.js +167 -83
- package/dist/waste-collections.addon.mjs +167 -83
- package/package.json +1 -1
|
@@ -52760,18 +52760,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
|
52760
52760
|
var MB = 1024 * 1024;
|
|
52761
52761
|
1024 * MB, 3072 * MB;
|
|
52762
52762
|
//#endregion
|
|
52763
|
-
//#region src/custom-actions.ts
|
|
52764
|
-
var wasteCollectionsActions = defineCustomActions({ fetchNow: customAction(object({
|
|
52765
|
-
/** When set, refresh only this configured source id; otherwise all enabled. */
|
|
52766
|
-
sourceId: string().min(1).optional() }).optional(), object({
|
|
52767
|
-
ok: literal(true),
|
|
52768
|
-
refreshed: array(object({
|
|
52769
|
-
sourceId: string(),
|
|
52770
|
-
entryCount: number().int(),
|
|
52771
|
-
error: string().optional()
|
|
52772
|
-
}))
|
|
52773
|
-
}), { kind: "mutation" }) });
|
|
52774
|
-
//#endregion
|
|
52775
52763
|
//#region src/waste-types.ts
|
|
52776
52764
|
var WasteSourceConfigSchema = object({
|
|
52777
52765
|
id: string().min(1),
|
|
@@ -52812,6 +52800,54 @@ var WasteFetchResultSchema = discriminatedUnion("ok", [object({
|
|
|
52812
52800
|
error: string()
|
|
52813
52801
|
})]);
|
|
52814
52802
|
//#endregion
|
|
52803
|
+
//#region src/custom-actions.ts
|
|
52804
|
+
var SourceIdSchema = string().min(1).regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "id must be a lowercase slug");
|
|
52805
|
+
var WasteSourceRowSchema = WasteSourceConfigSchema.extend({ formValues: record(string(), unknown()).optional() });
|
|
52806
|
+
var wasteCollectionsActions = defineCustomActions({
|
|
52807
|
+
fetchNow: customAction(object({
|
|
52808
|
+
/** When set, refresh only this configured source id; otherwise all enabled. */
|
|
52809
|
+
sourceId: string().min(1).optional() }).optional(), object({
|
|
52810
|
+
ok: literal(true),
|
|
52811
|
+
refreshed: array(object({
|
|
52812
|
+
sourceId: string(),
|
|
52813
|
+
entryCount: number().int(),
|
|
52814
|
+
error: string().optional()
|
|
52815
|
+
}))
|
|
52816
|
+
}), {
|
|
52817
|
+
kind: "mutation",
|
|
52818
|
+
auth: "admin"
|
|
52819
|
+
}),
|
|
52820
|
+
listSources: customAction(object({}), array(WasteSourceRowSchema).readonly(), {
|
|
52821
|
+
kind: "mutation",
|
|
52822
|
+
auth: "admin"
|
|
52823
|
+
}),
|
|
52824
|
+
sourceFormSchema: customAction(object({}), unknown(), {
|
|
52825
|
+
kind: "mutation",
|
|
52826
|
+
auth: "admin"
|
|
52827
|
+
}),
|
|
52828
|
+
createSource: customAction(object({
|
|
52829
|
+
id: SourceIdSchema,
|
|
52830
|
+
label: string().min(1)
|
|
52831
|
+
}), object({ id: string() }), {
|
|
52832
|
+
kind: "mutation",
|
|
52833
|
+
auth: "admin"
|
|
52834
|
+
}),
|
|
52835
|
+
updateSource: customAction(object({
|
|
52836
|
+
id: string().min(1),
|
|
52837
|
+
label: string().min(1),
|
|
52838
|
+
module: string().min(1).optional(),
|
|
52839
|
+
argsJson: string().optional(),
|
|
52840
|
+
enabled: boolean().optional()
|
|
52841
|
+
}), object({ ok: literal(true) }), {
|
|
52842
|
+
kind: "mutation",
|
|
52843
|
+
auth: "admin"
|
|
52844
|
+
}),
|
|
52845
|
+
deleteSource: customAction(object({ id: string().min(1) }), object({ ok: literal(true) }), {
|
|
52846
|
+
kind: "mutation",
|
|
52847
|
+
auth: "admin"
|
|
52848
|
+
})
|
|
52849
|
+
});
|
|
52850
|
+
//#endregion
|
|
52815
52851
|
//#region src/fetch-source.ts
|
|
52816
52852
|
/**
|
|
52817
52853
|
* Spawn the embedded Python bridge once per source fetch.
|
|
@@ -52956,11 +52992,56 @@ function createWasteCalendarSource(deps) {
|
|
|
52956
52992
|
};
|
|
52957
52993
|
}
|
|
52958
52994
|
//#endregion
|
|
52995
|
+
//#region src/waste-source-schema.ts
|
|
52996
|
+
var WASTE_SOURCE_FORM_SCHEMA = { sections: [{
|
|
52997
|
+
id: "source",
|
|
52998
|
+
title: "Source",
|
|
52999
|
+
columns: 2,
|
|
53000
|
+
fields: [
|
|
53001
|
+
{
|
|
53002
|
+
type: "text",
|
|
53003
|
+
key: "label",
|
|
53004
|
+
label: "Label",
|
|
53005
|
+
description: "Shown under System → Calendars.",
|
|
53006
|
+
default: "New source"
|
|
53007
|
+
},
|
|
53008
|
+
{
|
|
53009
|
+
type: "text",
|
|
53010
|
+
key: "module",
|
|
53011
|
+
label: "Source module",
|
|
53012
|
+
description: "HACS provider name, e.g. `ics`, `junker_app`, `abfallnavi_de`.",
|
|
53013
|
+
default: "ics"
|
|
53014
|
+
},
|
|
53015
|
+
{
|
|
53016
|
+
type: "textarea",
|
|
53017
|
+
key: "argsJson",
|
|
53018
|
+
label: "Args (JSON object)",
|
|
53019
|
+
description: "Constructor kwargs for the HACS source, e.g. `{\"url\":\"https://…/calendar.ics\"}`.",
|
|
53020
|
+
rows: 4,
|
|
53021
|
+
default: "{}",
|
|
53022
|
+
span: 2
|
|
53023
|
+
},
|
|
53024
|
+
{
|
|
53025
|
+
type: "boolean",
|
|
53026
|
+
key: "enabled",
|
|
53027
|
+
label: "Enabled",
|
|
53028
|
+
default: true
|
|
53029
|
+
}
|
|
53030
|
+
]
|
|
53031
|
+
}] };
|
|
53032
|
+
var WASTE_SOURCE_CREATE_VALUES = {
|
|
53033
|
+
label: "New source",
|
|
53034
|
+
module: "ics",
|
|
53035
|
+
argsJson: "{}",
|
|
53036
|
+
enabled: true
|
|
53037
|
+
};
|
|
53038
|
+
//#endregion
|
|
52959
53039
|
//#region src/waste-collections.addon.ts
|
|
52960
53040
|
/**
|
|
52961
53041
|
* Waste Collections — hub-only calendar-source over the vendored HACS
|
|
52962
53042
|
* `waste_collection_schedule` Python core (full source catalog).
|
|
52963
53043
|
*/
|
|
53044
|
+
var SOURCE_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
52964
53045
|
var DAY_MS = 1440 * 60 * 1e3;
|
|
52965
53046
|
var WasteCollectionsAddon = class extends BaseAddon {
|
|
52966
53047
|
pythonPath = null;
|
|
@@ -53008,7 +53089,14 @@ var WasteCollectionsAddon = class extends BaseAddon {
|
|
|
53008
53089
|
provider
|
|
53009
53090
|
}],
|
|
53010
53091
|
customActions: wasteCollectionsActions,
|
|
53011
|
-
actionHandlers: {
|
|
53092
|
+
actionHandlers: {
|
|
53093
|
+
fetchNow: async (input) => this.fetchNow(input),
|
|
53094
|
+
listSources: async () => this.listSources(),
|
|
53095
|
+
sourceFormSchema: async () => WASTE_SOURCE_FORM_SCHEMA,
|
|
53096
|
+
createSource: async (input) => this.createSource(input),
|
|
53097
|
+
updateSource: async (input) => this.updateSource(input),
|
|
53098
|
+
deleteSource: async (input) => this.deleteSource(input)
|
|
53099
|
+
}
|
|
53012
53100
|
};
|
|
53013
53101
|
}
|
|
53014
53102
|
async onConfigChanged() {
|
|
@@ -53017,6 +53105,49 @@ var WasteCollectionsAddon = class extends BaseAddon {
|
|
|
53017
53105
|
this.persistCache();
|
|
53018
53106
|
this.refreshAll("config-changed");
|
|
53019
53107
|
}
|
|
53108
|
+
listSources() {
|
|
53109
|
+
return this.config.sources.map((s) => ({
|
|
53110
|
+
...s,
|
|
53111
|
+
formValues: {
|
|
53112
|
+
label: s.label,
|
|
53113
|
+
module: s.module,
|
|
53114
|
+
argsJson: s.argsJson,
|
|
53115
|
+
enabled: s.enabled
|
|
53116
|
+
}
|
|
53117
|
+
}));
|
|
53118
|
+
}
|
|
53119
|
+
async createSource(input) {
|
|
53120
|
+
if (!SOURCE_ID_PATTERN.test(input.id)) throw new Error("id must be a lowercase slug (e.g. ics-home, junker)");
|
|
53121
|
+
if (this.config.sources.some((s) => s.id === input.id)) throw new Error(`source '${input.id}' already exists`);
|
|
53122
|
+
const row = WasteSourceConfigSchema.parse({
|
|
53123
|
+
...WASTE_SOURCE_CREATE_VALUES,
|
|
53124
|
+
id: input.id,
|
|
53125
|
+
label: input.label
|
|
53126
|
+
});
|
|
53127
|
+
await this.updateGlobalSettings({ sources: [...this.config.sources, row] });
|
|
53128
|
+
return { id: input.id };
|
|
53129
|
+
}
|
|
53130
|
+
async updateSource(input) {
|
|
53131
|
+
const idx = this.config.sources.findIndex((s) => s.id === input.id);
|
|
53132
|
+
if (idx < 0) throw new Error(`source '${input.id}' not found`);
|
|
53133
|
+
const prev = this.config.sources[idx];
|
|
53134
|
+
const next = WasteSourceConfigSchema.parse({
|
|
53135
|
+
id: prev.id,
|
|
53136
|
+
label: input.label,
|
|
53137
|
+
module: input.module ?? prev.module,
|
|
53138
|
+
argsJson: input.argsJson ?? prev.argsJson,
|
|
53139
|
+
enabled: input.enabled ?? prev.enabled
|
|
53140
|
+
});
|
|
53141
|
+
parseSourceArgs(next);
|
|
53142
|
+
const sources = this.config.sources.map((s, i) => i === idx ? next : s);
|
|
53143
|
+
await this.updateGlobalSettings({ sources });
|
|
53144
|
+
return { ok: true };
|
|
53145
|
+
}
|
|
53146
|
+
async deleteSource(input) {
|
|
53147
|
+
if (!this.config.sources.some((s) => s.id === input.id)) throw new Error(`source '${input.id}' not found`);
|
|
53148
|
+
await this.updateGlobalSettings({ sources: this.config.sources.filter((s) => s.id !== input.id) });
|
|
53149
|
+
return { ok: true };
|
|
53150
|
+
}
|
|
53020
53151
|
async fetchNow(input) {
|
|
53021
53152
|
const targets = this.config.sources.filter((s) => {
|
|
53022
53153
|
if (!s.enabled) return false;
|
|
@@ -53119,76 +53250,29 @@ var WasteCollectionsAddon = class extends BaseAddon {
|
|
|
53119
53250
|
}
|
|
53120
53251
|
globalSettingsSchema() {
|
|
53121
53252
|
return this.schema({ sections: [{
|
|
53122
|
-
id: "
|
|
53123
|
-
title: "
|
|
53124
|
-
description: "
|
|
53125
|
-
columns:
|
|
53126
|
-
fields: [
|
|
53127
|
-
|
|
53128
|
-
|
|
53129
|
-
|
|
53130
|
-
|
|
53131
|
-
|
|
53132
|
-
|
|
53133
|
-
|
|
53134
|
-
|
|
53135
|
-
|
|
53136
|
-
|
|
53137
|
-
|
|
53138
|
-
|
|
53139
|
-
|
|
53140
|
-
|
|
53141
|
-
|
|
53142
|
-
|
|
53143
|
-
|
|
53144
|
-
|
|
53145
|
-
type: "text",
|
|
53146
|
-
key: "module",
|
|
53147
|
-
label: "Source module",
|
|
53148
|
-
description: "e.g. `ics`, `junker_app`, `abfallnavi_de`."
|
|
53149
|
-
},
|
|
53150
|
-
{
|
|
53151
|
-
type: "textarea",
|
|
53152
|
-
key: "argsJson",
|
|
53153
|
-
label: "Args (JSON object)",
|
|
53154
|
-
description: "Constructor kwargs for the HACS source, e.g. `{\"url\":\"https://…/calendar.ics\"}`.",
|
|
53155
|
-
rows: 4
|
|
53156
|
-
},
|
|
53157
|
-
{
|
|
53158
|
-
type: "boolean",
|
|
53159
|
-
key: "enabled",
|
|
53160
|
-
label: "Enabled"
|
|
53161
|
-
}
|
|
53162
|
-
],
|
|
53163
|
-
defaultItem: {
|
|
53164
|
-
id: "",
|
|
53165
|
-
label: "New source",
|
|
53166
|
-
module: "ics",
|
|
53167
|
-
argsJson: "{}",
|
|
53168
|
-
enabled: true
|
|
53169
|
-
}
|
|
53170
|
-
},
|
|
53171
|
-
{
|
|
53172
|
-
type: "number",
|
|
53173
|
-
key: "fetchHour",
|
|
53174
|
-
label: "Daily fetch hour (local)",
|
|
53175
|
-
min: 0,
|
|
53176
|
-
max: 23,
|
|
53177
|
-
step: 1,
|
|
53178
|
-
description: "Informational — the addon refreshes about once per day from boot; use Fetch now to force."
|
|
53179
|
-
},
|
|
53180
|
-
{
|
|
53181
|
-
type: "addon-action-button",
|
|
53182
|
-
key: "_fetchNow",
|
|
53183
|
-
label: "Refresh",
|
|
53184
|
-
buttonLabel: "Fetch now",
|
|
53185
|
-
description: "Refresh every enabled source immediately.",
|
|
53186
|
-
addonId: "waste-collections",
|
|
53187
|
-
action: "fetchNow",
|
|
53188
|
-
variant: "primary",
|
|
53189
|
-
paramsStatic: {}
|
|
53190
|
-
}
|
|
53191
|
-
]
|
|
53253
|
+
id: "refresh",
|
|
53254
|
+
title: "Refresh",
|
|
53255
|
+
description: "Sources are managed in the table above (Add / Edit). Each source becomes one calendar under System → Calendars.",
|
|
53256
|
+
columns: 2,
|
|
53257
|
+
fields: [{
|
|
53258
|
+
type: "number",
|
|
53259
|
+
key: "fetchHour",
|
|
53260
|
+
label: "Daily fetch hour (local)",
|
|
53261
|
+
min: 0,
|
|
53262
|
+
max: 23,
|
|
53263
|
+
step: 1,
|
|
53264
|
+
description: "Informational — the addon refreshes about once per day from boot; use Fetch now to force."
|
|
53265
|
+
}, {
|
|
53266
|
+
type: "addon-action-button",
|
|
53267
|
+
key: "_fetchNow",
|
|
53268
|
+
label: "Refresh",
|
|
53269
|
+
buttonLabel: "Fetch now",
|
|
53270
|
+
description: "Refresh every enabled source immediately.",
|
|
53271
|
+
addonId: "waste-collections",
|
|
53272
|
+
action: "fetchNow",
|
|
53273
|
+
variant: "primary",
|
|
53274
|
+
paramsStatic: {}
|
|
53275
|
+
}]
|
|
53192
53276
|
}] });
|
|
53193
53277
|
}
|
|
53194
53278
|
};
|
|
@@ -52756,18 +52756,6 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
|
52756
52756
|
var MB = 1024 * 1024;
|
|
52757
52757
|
1024 * MB, 3072 * MB;
|
|
52758
52758
|
//#endregion
|
|
52759
|
-
//#region src/custom-actions.ts
|
|
52760
|
-
var wasteCollectionsActions = defineCustomActions({ fetchNow: customAction(object({
|
|
52761
|
-
/** When set, refresh only this configured source id; otherwise all enabled. */
|
|
52762
|
-
sourceId: string().min(1).optional() }).optional(), object({
|
|
52763
|
-
ok: literal(true),
|
|
52764
|
-
refreshed: array(object({
|
|
52765
|
-
sourceId: string(),
|
|
52766
|
-
entryCount: number().int(),
|
|
52767
|
-
error: string().optional()
|
|
52768
|
-
}))
|
|
52769
|
-
}), { kind: "mutation" }) });
|
|
52770
|
-
//#endregion
|
|
52771
52759
|
//#region src/waste-types.ts
|
|
52772
52760
|
var WasteSourceConfigSchema = object({
|
|
52773
52761
|
id: string().min(1),
|
|
@@ -52808,6 +52796,54 @@ var WasteFetchResultSchema = discriminatedUnion("ok", [object({
|
|
|
52808
52796
|
error: string()
|
|
52809
52797
|
})]);
|
|
52810
52798
|
//#endregion
|
|
52799
|
+
//#region src/custom-actions.ts
|
|
52800
|
+
var SourceIdSchema = string().min(1).regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "id must be a lowercase slug");
|
|
52801
|
+
var WasteSourceRowSchema = WasteSourceConfigSchema.extend({ formValues: record(string(), unknown()).optional() });
|
|
52802
|
+
var wasteCollectionsActions = defineCustomActions({
|
|
52803
|
+
fetchNow: customAction(object({
|
|
52804
|
+
/** When set, refresh only this configured source id; otherwise all enabled. */
|
|
52805
|
+
sourceId: string().min(1).optional() }).optional(), object({
|
|
52806
|
+
ok: literal(true),
|
|
52807
|
+
refreshed: array(object({
|
|
52808
|
+
sourceId: string(),
|
|
52809
|
+
entryCount: number().int(),
|
|
52810
|
+
error: string().optional()
|
|
52811
|
+
}))
|
|
52812
|
+
}), {
|
|
52813
|
+
kind: "mutation",
|
|
52814
|
+
auth: "admin"
|
|
52815
|
+
}),
|
|
52816
|
+
listSources: customAction(object({}), array(WasteSourceRowSchema).readonly(), {
|
|
52817
|
+
kind: "mutation",
|
|
52818
|
+
auth: "admin"
|
|
52819
|
+
}),
|
|
52820
|
+
sourceFormSchema: customAction(object({}), unknown(), {
|
|
52821
|
+
kind: "mutation",
|
|
52822
|
+
auth: "admin"
|
|
52823
|
+
}),
|
|
52824
|
+
createSource: customAction(object({
|
|
52825
|
+
id: SourceIdSchema,
|
|
52826
|
+
label: string().min(1)
|
|
52827
|
+
}), object({ id: string() }), {
|
|
52828
|
+
kind: "mutation",
|
|
52829
|
+
auth: "admin"
|
|
52830
|
+
}),
|
|
52831
|
+
updateSource: customAction(object({
|
|
52832
|
+
id: string().min(1),
|
|
52833
|
+
label: string().min(1),
|
|
52834
|
+
module: string().min(1).optional(),
|
|
52835
|
+
argsJson: string().optional(),
|
|
52836
|
+
enabled: boolean().optional()
|
|
52837
|
+
}), object({ ok: literal(true) }), {
|
|
52838
|
+
kind: "mutation",
|
|
52839
|
+
auth: "admin"
|
|
52840
|
+
}),
|
|
52841
|
+
deleteSource: customAction(object({ id: string().min(1) }), object({ ok: literal(true) }), {
|
|
52842
|
+
kind: "mutation",
|
|
52843
|
+
auth: "admin"
|
|
52844
|
+
})
|
|
52845
|
+
});
|
|
52846
|
+
//#endregion
|
|
52811
52847
|
//#region src/fetch-source.ts
|
|
52812
52848
|
/**
|
|
52813
52849
|
* Spawn the embedded Python bridge once per source fetch.
|
|
@@ -52952,11 +52988,56 @@ function createWasteCalendarSource(deps) {
|
|
|
52952
52988
|
};
|
|
52953
52989
|
}
|
|
52954
52990
|
//#endregion
|
|
52991
|
+
//#region src/waste-source-schema.ts
|
|
52992
|
+
var WASTE_SOURCE_FORM_SCHEMA = { sections: [{
|
|
52993
|
+
id: "source",
|
|
52994
|
+
title: "Source",
|
|
52995
|
+
columns: 2,
|
|
52996
|
+
fields: [
|
|
52997
|
+
{
|
|
52998
|
+
type: "text",
|
|
52999
|
+
key: "label",
|
|
53000
|
+
label: "Label",
|
|
53001
|
+
description: "Shown under System → Calendars.",
|
|
53002
|
+
default: "New source"
|
|
53003
|
+
},
|
|
53004
|
+
{
|
|
53005
|
+
type: "text",
|
|
53006
|
+
key: "module",
|
|
53007
|
+
label: "Source module",
|
|
53008
|
+
description: "HACS provider name, e.g. `ics`, `junker_app`, `abfallnavi_de`.",
|
|
53009
|
+
default: "ics"
|
|
53010
|
+
},
|
|
53011
|
+
{
|
|
53012
|
+
type: "textarea",
|
|
53013
|
+
key: "argsJson",
|
|
53014
|
+
label: "Args (JSON object)",
|
|
53015
|
+
description: "Constructor kwargs for the HACS source, e.g. `{\"url\":\"https://…/calendar.ics\"}`.",
|
|
53016
|
+
rows: 4,
|
|
53017
|
+
default: "{}",
|
|
53018
|
+
span: 2
|
|
53019
|
+
},
|
|
53020
|
+
{
|
|
53021
|
+
type: "boolean",
|
|
53022
|
+
key: "enabled",
|
|
53023
|
+
label: "Enabled",
|
|
53024
|
+
default: true
|
|
53025
|
+
}
|
|
53026
|
+
]
|
|
53027
|
+
}] };
|
|
53028
|
+
var WASTE_SOURCE_CREATE_VALUES = {
|
|
53029
|
+
label: "New source",
|
|
53030
|
+
module: "ics",
|
|
53031
|
+
argsJson: "{}",
|
|
53032
|
+
enabled: true
|
|
53033
|
+
};
|
|
53034
|
+
//#endregion
|
|
52955
53035
|
//#region src/waste-collections.addon.ts
|
|
52956
53036
|
/**
|
|
52957
53037
|
* Waste Collections — hub-only calendar-source over the vendored HACS
|
|
52958
53038
|
* `waste_collection_schedule` Python core (full source catalog).
|
|
52959
53039
|
*/
|
|
53040
|
+
var SOURCE_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
52960
53041
|
var DAY_MS = 1440 * 60 * 1e3;
|
|
52961
53042
|
var WasteCollectionsAddon = class extends BaseAddon {
|
|
52962
53043
|
pythonPath = null;
|
|
@@ -53004,7 +53085,14 @@ var WasteCollectionsAddon = class extends BaseAddon {
|
|
|
53004
53085
|
provider
|
|
53005
53086
|
}],
|
|
53006
53087
|
customActions: wasteCollectionsActions,
|
|
53007
|
-
actionHandlers: {
|
|
53088
|
+
actionHandlers: {
|
|
53089
|
+
fetchNow: async (input) => this.fetchNow(input),
|
|
53090
|
+
listSources: async () => this.listSources(),
|
|
53091
|
+
sourceFormSchema: async () => WASTE_SOURCE_FORM_SCHEMA,
|
|
53092
|
+
createSource: async (input) => this.createSource(input),
|
|
53093
|
+
updateSource: async (input) => this.updateSource(input),
|
|
53094
|
+
deleteSource: async (input) => this.deleteSource(input)
|
|
53095
|
+
}
|
|
53008
53096
|
};
|
|
53009
53097
|
}
|
|
53010
53098
|
async onConfigChanged() {
|
|
@@ -53013,6 +53101,49 @@ var WasteCollectionsAddon = class extends BaseAddon {
|
|
|
53013
53101
|
this.persistCache();
|
|
53014
53102
|
this.refreshAll("config-changed");
|
|
53015
53103
|
}
|
|
53104
|
+
listSources() {
|
|
53105
|
+
return this.config.sources.map((s) => ({
|
|
53106
|
+
...s,
|
|
53107
|
+
formValues: {
|
|
53108
|
+
label: s.label,
|
|
53109
|
+
module: s.module,
|
|
53110
|
+
argsJson: s.argsJson,
|
|
53111
|
+
enabled: s.enabled
|
|
53112
|
+
}
|
|
53113
|
+
}));
|
|
53114
|
+
}
|
|
53115
|
+
async createSource(input) {
|
|
53116
|
+
if (!SOURCE_ID_PATTERN.test(input.id)) throw new Error("id must be a lowercase slug (e.g. ics-home, junker)");
|
|
53117
|
+
if (this.config.sources.some((s) => s.id === input.id)) throw new Error(`source '${input.id}' already exists`);
|
|
53118
|
+
const row = WasteSourceConfigSchema.parse({
|
|
53119
|
+
...WASTE_SOURCE_CREATE_VALUES,
|
|
53120
|
+
id: input.id,
|
|
53121
|
+
label: input.label
|
|
53122
|
+
});
|
|
53123
|
+
await this.updateGlobalSettings({ sources: [...this.config.sources, row] });
|
|
53124
|
+
return { id: input.id };
|
|
53125
|
+
}
|
|
53126
|
+
async updateSource(input) {
|
|
53127
|
+
const idx = this.config.sources.findIndex((s) => s.id === input.id);
|
|
53128
|
+
if (idx < 0) throw new Error(`source '${input.id}' not found`);
|
|
53129
|
+
const prev = this.config.sources[idx];
|
|
53130
|
+
const next = WasteSourceConfigSchema.parse({
|
|
53131
|
+
id: prev.id,
|
|
53132
|
+
label: input.label,
|
|
53133
|
+
module: input.module ?? prev.module,
|
|
53134
|
+
argsJson: input.argsJson ?? prev.argsJson,
|
|
53135
|
+
enabled: input.enabled ?? prev.enabled
|
|
53136
|
+
});
|
|
53137
|
+
parseSourceArgs(next);
|
|
53138
|
+
const sources = this.config.sources.map((s, i) => i === idx ? next : s);
|
|
53139
|
+
await this.updateGlobalSettings({ sources });
|
|
53140
|
+
return { ok: true };
|
|
53141
|
+
}
|
|
53142
|
+
async deleteSource(input) {
|
|
53143
|
+
if (!this.config.sources.some((s) => s.id === input.id)) throw new Error(`source '${input.id}' not found`);
|
|
53144
|
+
await this.updateGlobalSettings({ sources: this.config.sources.filter((s) => s.id !== input.id) });
|
|
53145
|
+
return { ok: true };
|
|
53146
|
+
}
|
|
53016
53147
|
async fetchNow(input) {
|
|
53017
53148
|
const targets = this.config.sources.filter((s) => {
|
|
53018
53149
|
if (!s.enabled) return false;
|
|
@@ -53115,76 +53246,29 @@ var WasteCollectionsAddon = class extends BaseAddon {
|
|
|
53115
53246
|
}
|
|
53116
53247
|
globalSettingsSchema() {
|
|
53117
53248
|
return this.schema({ sections: [{
|
|
53118
|
-
id: "
|
|
53119
|
-
title: "
|
|
53120
|
-
description: "
|
|
53121
|
-
columns:
|
|
53122
|
-
fields: [
|
|
53123
|
-
|
|
53124
|
-
|
|
53125
|
-
|
|
53126
|
-
|
|
53127
|
-
|
|
53128
|
-
|
|
53129
|
-
|
|
53130
|
-
|
|
53131
|
-
|
|
53132
|
-
|
|
53133
|
-
|
|
53134
|
-
|
|
53135
|
-
|
|
53136
|
-
|
|
53137
|
-
|
|
53138
|
-
|
|
53139
|
-
|
|
53140
|
-
|
|
53141
|
-
type: "text",
|
|
53142
|
-
key: "module",
|
|
53143
|
-
label: "Source module",
|
|
53144
|
-
description: "e.g. `ics`, `junker_app`, `abfallnavi_de`."
|
|
53145
|
-
},
|
|
53146
|
-
{
|
|
53147
|
-
type: "textarea",
|
|
53148
|
-
key: "argsJson",
|
|
53149
|
-
label: "Args (JSON object)",
|
|
53150
|
-
description: "Constructor kwargs for the HACS source, e.g. `{\"url\":\"https://…/calendar.ics\"}`.",
|
|
53151
|
-
rows: 4
|
|
53152
|
-
},
|
|
53153
|
-
{
|
|
53154
|
-
type: "boolean",
|
|
53155
|
-
key: "enabled",
|
|
53156
|
-
label: "Enabled"
|
|
53157
|
-
}
|
|
53158
|
-
],
|
|
53159
|
-
defaultItem: {
|
|
53160
|
-
id: "",
|
|
53161
|
-
label: "New source",
|
|
53162
|
-
module: "ics",
|
|
53163
|
-
argsJson: "{}",
|
|
53164
|
-
enabled: true
|
|
53165
|
-
}
|
|
53166
|
-
},
|
|
53167
|
-
{
|
|
53168
|
-
type: "number",
|
|
53169
|
-
key: "fetchHour",
|
|
53170
|
-
label: "Daily fetch hour (local)",
|
|
53171
|
-
min: 0,
|
|
53172
|
-
max: 23,
|
|
53173
|
-
step: 1,
|
|
53174
|
-
description: "Informational — the addon refreshes about once per day from boot; use Fetch now to force."
|
|
53175
|
-
},
|
|
53176
|
-
{
|
|
53177
|
-
type: "addon-action-button",
|
|
53178
|
-
key: "_fetchNow",
|
|
53179
|
-
label: "Refresh",
|
|
53180
|
-
buttonLabel: "Fetch now",
|
|
53181
|
-
description: "Refresh every enabled source immediately.",
|
|
53182
|
-
addonId: "waste-collections",
|
|
53183
|
-
action: "fetchNow",
|
|
53184
|
-
variant: "primary",
|
|
53185
|
-
paramsStatic: {}
|
|
53186
|
-
}
|
|
53187
|
-
]
|
|
53249
|
+
id: "refresh",
|
|
53250
|
+
title: "Refresh",
|
|
53251
|
+
description: "Sources are managed in the table above (Add / Edit). Each source becomes one calendar under System → Calendars.",
|
|
53252
|
+
columns: 2,
|
|
53253
|
+
fields: [{
|
|
53254
|
+
type: "number",
|
|
53255
|
+
key: "fetchHour",
|
|
53256
|
+
label: "Daily fetch hour (local)",
|
|
53257
|
+
min: 0,
|
|
53258
|
+
max: 23,
|
|
53259
|
+
step: 1,
|
|
53260
|
+
description: "Informational — the addon refreshes about once per day from boot; use Fetch now to force."
|
|
53261
|
+
}, {
|
|
53262
|
+
type: "addon-action-button",
|
|
53263
|
+
key: "_fetchNow",
|
|
53264
|
+
label: "Refresh",
|
|
53265
|
+
buttonLabel: "Fetch now",
|
|
53266
|
+
description: "Refresh every enabled source immediately.",
|
|
53267
|
+
addonId: "waste-collections",
|
|
53268
|
+
action: "fetchNow",
|
|
53269
|
+
variant: "primary",
|
|
53270
|
+
paramsStatic: {}
|
|
53271
|
+
}]
|
|
53188
53272
|
}] });
|
|
53189
53273
|
}
|
|
53190
53274
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-waste-collections",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Waste collection schedules via the vendored HACS waste_collection_schedule Python core — full source catalog as calendar-source.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|