diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..6673a8093 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,65 @@ +name: Build Container Image +on: + workflow_dispatch: + push: + branches: + - main + tags: + - "*" + +jobs: + build: + name: Build + + runs-on: ubuntu-latest + + strategy: + matrix: + arch: [amd64, arm64] + + steps: + - name: Checkout Entire Repository + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + platforms: linux/${{ matrix.arch }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set Branch + run: | + export APPS_JSON='[{"url": "https://github.com/frappe/helpdesk","branch": "main"}]' + echo "APPS_JSON_BASE64=$(echo $APPS_JSON | base64 -w 0)" >> $GITHUB_ENV + echo "FRAPPE_BRANCH=version-15" >> $GITHUB_ENV + + - name: Set Image Tag + run: | + echo "IMAGE_TAG=stable" >> $GITHUB_ENV + + - uses: actions/checkout@v4 + with: + repository: frappe/frappe_docker + path: builds + + - name: Build and push + uses: docker/build-push-action@v6 + with: + push: true + context: builds + file: builds/images/layered/Containerfile + tags: > + ghcr.io/${{ github.repository }}:${{ github.ref_name }}, + ghcr.io/${{ github.repository }}:${{ env.IMAGE_TAG }} + build-args: | + "FRAPPE_BRANCH=${{ env.FRAPPE_BRANCH }}" + "APPS_JSON_BASE64=${{ env.APPS_JSON_BASE64 }}" \ No newline at end of file diff --git a/desk/src/App.vue b/desk/src/App.vue index bebc1e316..2431393f0 100644 --- a/desk/src/App.vue +++ b/desk/src/App.vue @@ -15,7 +15,7 @@ import { stopSession } from "@/telemetry"; import { Dialogs } from "frappe-ui"; useConfigStore(); -onMounted(async () => { +onMounted(() => { window.addEventListener("online", () => { createToast({ title: "You are now online", diff --git a/desk/src/components/EmailEditor.vue b/desk/src/components/EmailEditor.vue index db502a7bc..184729346 100644 --- a/desk/src/components/EmailEditor.vue +++ b/desk/src/components/EmailEditor.vue @@ -157,7 +157,7 @@ import { TextEditorFixedMenu, createResource, } from "frappe-ui"; -import { validateEmail } from "@/utils"; +import { createToast, validateEmail } from "@/utils"; import { MultiSelectInput, AttachmentItem, @@ -165,6 +165,7 @@ import { } from "@/components"; import { AttachmentIcon, EmailIcon } from "@/components/icons"; import { PreserveVideoControls } from "@/tiptap-extensions"; +import { useError } from "@/composables/error"; const editorRef = ref(null); const showCannedResponseSelectorModal = ref(false); @@ -242,6 +243,15 @@ function submitMail() { emit("submit"); loading.value = false; }, + onError: (err) => { + loading.value = false; + createToast({ + title: err.exc_type, + text: err.messages[0], + icon: "x", + iconClasses: "text-red-500", + }); + }, }); sendMail.submit(); diff --git a/desk/src/components/ListViewBuilder.vue b/desk/src/components/ListViewBuilder.vue index a08c9a581..427ed2350 100644 --- a/desk/src/components/ListViewBuilder.vue +++ b/desk/src/components/ListViewBuilder.vue @@ -7,7 +7,7 @@ >
- +
@@ -21,54 +21,55 @@ - - - - - - - - - - -
- {{ item }} -
-
- {{ dayjs.tz(item).fromNow() }} -
-
- {{ item }} -
-
-
-
-
-
+ + + + + + + + + +
+ {{ item }} +
+
+ {{ dayjs.tz(item).fromNow() }} +
+
+ +
+
+ {{ item }} +
+
+
+
+
; }; } @@ -134,7 +141,15 @@ interface E { (event: "rowClick", row: any): void; } -const props = defineProps

(); +const props = withDefaults(defineProps

(), { + options: () => { + return { + doctype: "", + hideViewControls: false, + selectable: true, + }; + }, +}); const emit = defineEmits(); const { isMobileView } = useScreenSize(); @@ -190,10 +205,21 @@ function handleColumnConfig(column) { return column; } +const statusMap: Record = props.options + .statusMap as Record; +function handleStatusColor(status: "Published" | "Draft"): BadgeStatus { + if (!statusMap) + return { + label: status, + theme: "gray", + }; + return statusMap[status]; +} + const filterableFields = createResource({ url: "helpdesk.api.doc.get_filterable_fields", cache: ["DocField", props.options.doctype], - auto: true, + auto: !props.options.hideViewControls, params: { doctype: props.options.doctype, append_assign: true, @@ -212,7 +238,7 @@ const filterableFields = createResource({ const sortableFields = createResource({ url: "helpdesk.api.doc.sort_options", - auto: true, + auto: !props.options.hideViewControls, params: { doctype: props.options.doctype, }, @@ -220,7 +246,7 @@ const sortableFields = createResource({ const quickFilters = createResource({ url: "helpdesk.api.doc.get_quick_filters", - auto: true, + auto: !props.options.hideViewControls, params: { doctype: props.options.doctype, }, @@ -232,7 +258,12 @@ const quickFilters = createResource({ }); const showViewControls = computed(() => { - return filterableFields.data && sortableFields.data && quickFilters.data; + return ( + !props.options.hideViewControls && + filterableFields.data && + sortableFields.data && + quickFilters.data + ); }); const listViewData = reactive({ diff --git a/desk/src/components/desk/global/NewContactDialog.vue b/desk/src/components/desk/global/NewContactDialog.vue index cc6619524..5cdf1ffed 100644 --- a/desk/src/components/desk/global/NewContactDialog.vue +++ b/desk/src/components/desk/global/NewContactDialog.vue @@ -51,6 +51,7 @@ import { ErrorMessage, createResource, Autocomplete, + createListResource, } from "frappe-ui"; import zod from "zod"; @@ -141,20 +142,17 @@ const open = computed({ }, }); -const customerResource = createResource({ - url: "helpdesk.extends.client.get_list", - params: { - doctype: "HD Customer", - fields: ["name", "customer_name"], - }, +const customerResource = createListResource({ + doctype: "HD Customer", + fields: ["name"], + cache: "customers", transform: (data) => { - let allData = data.map((option) => { + return data.map((option) => { return { label: option.name, - value: option.customer_name, + value: option.name, }; }); - return allData; }, auto: true, }); diff --git a/desk/src/components/index.ts b/desk/src/components/index.ts index edc4b21a5..339ab9153 100644 --- a/desk/src/components/index.ts +++ b/desk/src/components/index.ts @@ -1,7 +1,6 @@ export { default as AttachmentItem } from "./AttachmentItem.vue"; export { default as CommandPalette } from "./command-palette/CP.vue"; export { default as HCard } from "./HCard.vue"; -export { default as ListView } from "./list-view/LV.vue"; export { default as NestedPopover } from "./NestedPopover.vue"; export { default as Notifications } from "./notifications/Notifications.vue"; export { default as PageTitle } from "./PageTitle.vue"; diff --git a/desk/src/components/list-view/LV.vue b/desk/src/components/list-view/LV.vue deleted file mode 100644 index fba5e59b2..000000000 --- a/desk/src/components/list-view/LV.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - diff --git a/desk/src/components/list-view/LVEmpty.vue b/desk/src/components/list-view/LVEmpty.vue deleted file mode 100644 index 82ec350ed..000000000 --- a/desk/src/components/list-view/LVEmpty.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/desk/src/components/list-view/LVHeader.vue b/desk/src/components/list-view/LVHeader.vue deleted file mode 100644 index 00ad57645..000000000 --- a/desk/src/components/list-view/LVHeader.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - diff --git a/desk/src/components/list-view/LVLoading.vue b/desk/src/components/list-view/LVLoading.vue deleted file mode 100644 index eb8c23fea..000000000 --- a/desk/src/components/list-view/LVLoading.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - diff --git a/desk/src/components/list-view/LVNavigation.vue b/desk/src/components/list-view/LVNavigation.vue deleted file mode 100644 index 9ef6ed398..000000000 --- a/desk/src/components/list-view/LVNavigation.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/desk/src/components/list-view/LVRow.vue b/desk/src/components/list-view/LVRow.vue deleted file mode 100644 index d0217c44c..000000000 --- a/desk/src/components/list-view/LVRow.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - diff --git a/desk/src/components/list-view/LVSelectionBar.vue b/desk/src/components/list-view/LVSelectionBar.vue deleted file mode 100644 index 6145c14c0..000000000 --- a/desk/src/components/list-view/LVSelectionBar.vue +++ /dev/null @@ -1,48 +0,0 @@ - - - diff --git a/desk/src/components/list-view/selection.ts b/desk/src/components/list-view/selection.ts deleted file mode 100644 index fc77c7e5c..000000000 --- a/desk/src/components/list-view/selection.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { reactive } from "vue"; -import { Action, Key } from "./types"; - -export const selection = reactive({ - storage: new Set(), - actions: new Set(), - toggle: (key: Key) => { - if (!selection.storage.delete(key)) { - selection.storage.add(key); - } - }, - reset: () => { - selection.storage.clear(); - selection.actions.clear(); - }, -}); diff --git a/desk/src/components/list-view/symbols.ts b/desk/src/components/list-view/symbols.ts deleted file mode 100644 index b3f6d269e..000000000 --- a/desk/src/components/list-view/symbols.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { InjectionKey, Ref } from "vue"; -import { Resource, Column } from "@/types"; - -type I = { - name: string; - [key: string]: unknown; -}; -type R = Resource>; -export const CheckboxKey: InjectionKey = Symbol("Checkbox"); -export const ColumnsKey: InjectionKey> = Symbol("Columns"); -export const DocTypeKey: InjectionKey = Symbol("DocType"); -export const FilterKey: InjectionKey = Symbol("Filter"); -export const IdKey: InjectionKey = Symbol("Id"); -export const PluralKey: InjectionKey> = Symbol("Plural"); -export const ResourceKey: InjectionKey = Symbol("Resource"); -export const SingluarKey: InjectionKey> = Symbol("Singular"); diff --git a/desk/src/components/list-view/types.ts b/desk/src/components/list-view/types.ts deleted file mode 100644 index 4f67ee37f..000000000 --- a/desk/src/components/list-view/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type Selection = Set; -export type Key = string; -export type Action = { - label: string; - onClick: (key: Key[]) => void; -}; diff --git a/desk/src/components/notifications/Notifications.vue b/desk/src/components/notifications/Notifications.vue index 1b8fcf3b4..4356fdb33 100644 --- a/desk/src/components/notifications/Notifications.vue +++ b/desk/src/components/notifications/Notifications.vue @@ -48,13 +48,11 @@ } " > - +

- {{ - n.user_from.name - }} + {{ n.user_from }} mentioned you in ticket diff --git a/desk/src/components/ticket/TicketsListView.vue b/desk/src/components/ticket/TicketsListView.vue index e156d455e..bceacc902 100644 --- a/desk/src/components/ticket/TicketsListView.vue +++ b/desk/src/components/ticket/TicketsListView.vue @@ -72,7 +72,7 @@
- {{ item || "-" }} + {{ item }}
-