|
7 | 7 | import { Label } from '$lib/components/ui/label';
|
8 | 8 | import { AlertCircleIcon, Loader2Icon } from 'lucide-svelte';
|
9 | 9 | import * as Alert from '$lib/components/ui/alert';
|
10 |
| - import { deleteFeed, refreshFeeds, updateFeed } from '$lib/api/feed'; |
| 10 | + import { deleteFeed, refreshFeeds, updateFeed, type FeedUpdateForm } from '$lib/api/feed'; |
11 | 11 | import type { Feed } from '$lib/api/model';
|
12 | 12 | import type { groupFeeds } from './+page';
|
13 | 13 | import { invalidateAll } from '$app/navigation';
|
|
18 | 18 | export let groups: groupFeeds[];
|
19 | 19 | export let show = false;
|
20 | 20 | export let selectedFeed: Feed;
|
21 |
| - let formData: Feed; |
| 21 | + let formData: FeedUpdateForm; |
22 | 22 | let refreshing = false;
|
23 | 23 |
|
24 | 24 | $: {
|
25 | 25 | if (show) {
|
26 |
| - formData = Object.assign({}, selectedFeed); |
| 26 | + formData = {}; |
27 | 27 | }
|
28 | 28 | }
|
29 | 29 |
|
|
55 | 55 | }
|
56 | 56 |
|
57 | 57 | async function handleUpdate() {
|
58 |
| - if (!formData) return; |
59 |
| - toast.promise(updateFeed(formData), { |
| 58 | + toast.promise(updateFeed(selectedFeed.id, formData), { |
60 | 59 | loading: 'Updating',
|
61 | 60 | success: () => {
|
62 | 61 | invalidateAll();
|
63 |
| - return formData.name + ' has been updated'; |
| 62 | + return 'Update successfully'; |
64 | 63 | },
|
65 | 64 | error: (e) => {
|
66 | 65 | invalidateAll();
|
67 | 66 | return (e as Error).message;
|
68 | 67 | }
|
69 | 68 | });
|
70 | 69 | }
|
| 70 | +
|
| 71 | + async function handleToggleSuspended() { |
| 72 | + const data: FeedUpdateForm = { suspended: !selectedFeed.suspended }; |
| 73 | + try { |
| 74 | + await updateFeed(selectedFeed.id, data); |
| 75 | + toast.success('Update successfully'); |
| 76 | + invalidateAll(); |
| 77 | + } catch (e) { |
| 78 | + toast.error((e as Error).message); |
| 79 | + } |
| 80 | + } |
71 | 81 | </script>
|
72 | 82 |
|
73 | 83 | <Sheet.Root bind:open={show}>
|
|
94 | 104 | id="name"
|
95 | 105 | type="text"
|
96 | 106 | class="w-full"
|
97 |
| - value={formData.name} |
| 107 | + value={selectedFeed.name} |
98 | 108 | on:input={(e) => {
|
99 | 109 | // two-way bind not works, so do this. https://stackoverflow.com/questions/60825553/svelte-input-binding-breaks-when-a-reactive-value-is-a-reference-type
|
100 | 110 | if (e.target instanceof HTMLInputElement) {
|
|
110 | 120 | id="link"
|
111 | 121 | type="text"
|
112 | 122 | class="w-full"
|
113 |
| - value={formData.link} |
| 123 | + value={selectedFeed.link} |
114 | 124 | on:input={(e) => {
|
115 | 125 | if (e.target instanceof HTMLInputElement) {
|
116 | 126 | formData.link = e.target.value;
|
|
126 | 136 | items={groups.map((v) => {
|
127 | 137 | return { value: v.id, label: v.name };
|
128 | 138 | })}
|
129 |
| - onSelectedChange={(v) => v && (formData.group.id = v.value)} |
| 139 | + onSelectedChange={(v) => v && (formData.group_id = v.value)} |
130 | 140 | >
|
131 | 141 | <Select.Trigger>
|
132 |
| - <Select.Value placeholder={formData.group.name} /> |
| 142 | + <Select.Value placeholder={selectedFeed.group.name} /> |
133 | 143 | </Select.Trigger>
|
134 | 144 | <Select.Content>
|
135 | 145 | {#each groups as g}
|
|
142 | 152 | </form>
|
143 | 153 | {/if}
|
144 | 154 |
|
145 |
| - <Separator class="my-10" /> |
| 155 | + <Separator class="my-6" /> |
| 156 | + <Button |
| 157 | + variant="secondary" |
| 158 | + on:click={handleRefresh} |
| 159 | + disabled={refreshing || selectedFeed.suspended} |
| 160 | + > |
| 161 | + {#if refreshing} |
| 162 | + <Loader2Icon class="mr-2 h-4 w-4 animate-spin" /> |
| 163 | + {:else} |
| 164 | + Refresh |
| 165 | + {/if} |
| 166 | + </Button> |
| 167 | + |
| 168 | + <Separator class="my-6" /> |
146 | 169 | <div class="flex flex-col w-full gap-4">
|
147 |
| - <Button variant="secondary" on:click={handleRefresh} disabled={refreshing}> |
148 |
| - {#if refreshing} |
149 |
| - <Loader2Icon class="mr-2 h-4 w-4 animate-spin" /> |
150 |
| - {:else} |
151 |
| - Refresh |
152 |
| - {/if} |
153 |
| - </Button> |
| 170 | + <AlertDialog.Root> |
| 171 | + <AlertDialog.Trigger asChild let:builder> |
| 172 | + <Button builders={[builder]} variant="secondary"> |
| 173 | + {#if selectedFeed.suspended} |
| 174 | + Resume |
| 175 | + {:else} |
| 176 | + Suspend |
| 177 | + {/if} |
| 178 | + </Button> |
| 179 | + </AlertDialog.Trigger> |
| 180 | + <AlertDialog.Content> |
| 181 | + <AlertDialog.Header> |
| 182 | + <AlertDialog.Title>Are you absolutely sure?</AlertDialog.Title> |
| 183 | + <AlertDialog.Description> |
| 184 | + {#if selectedFeed.suspended} |
| 185 | + This will resume the refreshing of <b>{selectedFeed.name}</b>. |
| 186 | + {:else} |
| 187 | + This will suspend the refreshing of <b>{selectedFeed.name}</b> untill you resume it. |
| 188 | + {/if} |
| 189 | + </AlertDialog.Description> |
| 190 | + </AlertDialog.Header> |
| 191 | + <AlertDialog.Footer> |
| 192 | + <AlertDialog.Cancel>Cancel</AlertDialog.Cancel> |
| 193 | + <AlertDialog.Action on:click={handleToggleSuspended}>Continue</AlertDialog.Action> |
| 194 | + </AlertDialog.Footer> |
| 195 | + </AlertDialog.Content> |
| 196 | + </AlertDialog.Root> |
| 197 | + |
154 | 198 | <AlertDialog.Root>
|
155 | 199 | <AlertDialog.Trigger asChild let:builder>
|
156 | 200 | <Button builders={[builder]} variant="destructive">Delete</Button>
|
|
0 commit comments